| File: | xrdb.c |
| Location: | line 197, column 12 |
| Description: | Call to 'realloc' has an allocation size of 0 bytes |
| 1 | /* | |||
| 2 | * xrdb - X resource manager database utility | |||
| 3 | * | |||
| 4 | */ | |||
| 5 | ||||
| 6 | /* | |||
| 7 | * COPYRIGHT 1987, 1991 | |||
| 8 | * DIGITAL EQUIPMENT CORPORATION | |||
| 9 | * MAYNARD, MASSACHUSETTS | |||
| 10 | * MASSACHUSETTS INSTITUTE OF TECHNOLOGY | |||
| 11 | * CAMBRIDGE, MASSACHUSETTS | |||
| 12 | * ALL RIGHTS RESERVED. | |||
| 13 | * | |||
| 14 | * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND | |||
| 15 | * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION. | |||
| 16 | * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR | |||
| 17 | * ANY PURPOSE. IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. | |||
| 18 | * | |||
| 19 | * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT RIGHTS, | |||
| 20 | * APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN ADDITION TO THAT | |||
| 21 | * SET FORTH ABOVE. | |||
| 22 | * | |||
| 23 | * | |||
| 24 | * Permission to use, copy, modify, and distribute this software and its | |||
| 25 | * documentation for any purpose and without fee is hereby granted, provided | |||
| 26 | * that the above copyright notice appear in all copies and that both that | |||
| 27 | * copyright notice and this permission notice appear in supporting | |||
| 28 | * documentation, and that the name of Digital Equipment Corporation not be | |||
| 29 | * used in advertising or publicity pertaining to distribution of the software | |||
| 30 | * without specific, written prior permission. | |||
| 31 | */ | |||
| 32 | ||||
| 33 | /* | |||
| 34 | * this program is used to load, or dump the resource manager database | |||
| 35 | * in the server. | |||
| 36 | * | |||
| 37 | * Original Author: Jim Gettys, August 28, 1987 | |||
| 38 | * Extensively Modified: Phil Karlton, January 5, 1987 | |||
| 39 | * Modified a Bunch More: Bob Scheifler, February, 1991 | |||
| 40 | */ | |||
| 41 | ||||
| 42 | #ifdef HAVE_CONFIG_H1 | |||
| 43 | #include <config.h> | |||
| 44 | #endif | |||
| 45 | ||||
| 46 | #include <X11/Xlib.h> | |||
| 47 | #include <X11/Xutil.h> | |||
| 48 | #include <X11/Xatom.h> | |||
| 49 | #include <X11/Xos.h> | |||
| 50 | #include <X11/Xmu/SysUtil.h> | |||
| 51 | #include <stdio.h> | |||
| 52 | #include <ctype.h> | |||
| 53 | #include <errno(*__error()).h> | |||
| 54 | #include <stdlib.h> | |||
| 55 | #include <stdarg.h> | |||
| 56 | #include <stdint.h> | |||
| 57 | ||||
| 58 | #ifdef NEED_SYS_PARAM_H1 | |||
| 59 | # include <sys/param.h> /* defines MAXHOSTNAMELEN on BSD & Linux */ | |||
| 60 | #endif | |||
| 61 | ||||
| 62 | #ifdef NEED_NETDB_H | |||
| 63 | # include <netdb.h> /* defines MAXHOSTNAMELEN on Solaris */ | |||
| 64 | #endif | |||
| 65 | ||||
| 66 | #define SCREEN_RESOURCES"SCREEN_RESOURCES" "SCREEN_RESOURCES" | |||
| 67 | ||||
| 68 | #ifndef CPP"/usr/bin/cpp" | |||
| 69 | #define CPP"/usr/bin/cpp" "/usr/lib/cpp" | |||
| 70 | #endif /* CPP */ | |||
| 71 | ||||
| 72 | #define INIT_BUFFER_SIZE10000 10000 | |||
| 73 | #define INIT_ENTRY_SIZE500 500 | |||
| 74 | ||||
| 75 | #define RALL0 0 | |||
| 76 | #define RGLOBAL1 1 | |||
| 77 | #define RSCREEN2 2 | |||
| 78 | #define RSCREENS3 3 | |||
| 79 | ||||
| 80 | #define OPSYMBOLS0 0 | |||
| 81 | #define OPQUERY1 1 | |||
| 82 | #define OPREMOVE2 2 | |||
| 83 | #define OPEDIT3 3 | |||
| 84 | #define OPLOAD4 4 | |||
| 85 | #define OPMERGE5 5 | |||
| 86 | #define OPOVERRIDE6 6 | |||
| 87 | ||||
| 88 | #define BACKUP_SUFFIX".bak" ".bak" /* for editing */ | |||
| 89 | ||||
| 90 | typedef struct _Entry { | |||
| 91 | char *tag, *value; | |||
| 92 | int lineno; | |||
| 93 | Boolint usable; | |||
| 94 | } Entry; | |||
| 95 | ||||
| 96 | typedef struct _Buffer { | |||
| 97 | char *buff; | |||
| 98 | size_t room, used; | |||
| 99 | } Buffer; | |||
| 100 | ||||
| 101 | typedef struct _Entries { | |||
| 102 | Entry *entry; | |||
| 103 | size_t room, used; | |||
| 104 | } Entries; | |||
| 105 | ||||
| 106 | /* dynamically allocated strings */ | |||
| 107 | #define CHUNK_SIZE4096 4096 | |||
| 108 | typedef struct _String { | |||
| 109 | char *val; | |||
| 110 | size_t room, used; | |||
| 111 | } String; | |||
| 112 | ||||
| 113 | static char *ProgramName; | |||
| 114 | static Boolint quiet = False0; | |||
| 115 | static char tmpname[32]; | |||
| 116 | static char *filename = NULL((void*)0); | |||
| 117 | #ifdef PATHETICCPP | |||
| 118 | static Boolint need_real_defines = False0; | |||
| 119 | static char tmpname2[32]; | |||
| 120 | #endif | |||
| 121 | #ifdef WIN32 | |||
| 122 | static char tmpname3[32]; | |||
| 123 | #endif | |||
| 124 | static int oper = OPLOAD4; | |||
| 125 | static char *editFile = NULL((void*)0); | |||
| 126 | static const char *cpp_program = NULL((void*)0); | |||
| 127 | static const char * const cpp_locations[] = { CPP"/usr/bin/cpp" }; | |||
| 128 | static const char *backup_suffix = BACKUP_SUFFIX".bak"; | |||
| 129 | static Boolint dont_execute = False0; | |||
| 130 | static String defines; | |||
| 131 | static size_t defines_base; | |||
| 132 | #define MAX_CMD_DEFINES512 512 | |||
| 133 | static char *cmd_defines[MAX_CMD_DEFINES512]; | |||
| 134 | static int num_cmd_defines = 0; | |||
| 135 | static String includes; | |||
| 136 | static Display *dpy; | |||
| 137 | static Buffer buffer; | |||
| 138 | static Entries newDB; | |||
| 139 | ||||
| 140 | static void fatal(const char *, ...) | |||
| 141 | _X_ATTRIBUTE_PRINTF(1, 2)__attribute__((__format__(__printf__,1,2)))_X_NORETURN__attribute((noreturn)) _X_COLD__attribute__((__cold__)); | |||
| 142 | static void addstring(String *arg, const char *s); | |||
| 143 | static void addescapedstring(String *arg, const char *s); | |||
| 144 | static void addtokstring(String *arg, const char *s); | |||
| 145 | static void FormatEntries(Buffer *b, Entries * entries); | |||
| 146 | static void StoreProperty(Display *display, Window root, Atom res_prop); | |||
| 147 | static void Process(int scrno, Boolint doScreen, Boolint execute); | |||
| 148 | static void ShuffleEntries(Entries *db, Entries *dbs, unsigned int num); | |||
| 149 | static void ReProcess(int scrno, Boolint doScreen); | |||
| 150 | ||||
| 151 | #ifndef HAVE_ASPRINTF1 | |||
| 152 | /* sprintf variant found in newer libc's which allocates string to print to */ | |||
| 153 | static int _X_ATTRIBUTE_PRINTF(2, 3)__attribute__((__format__(__printf__,2,3))) | |||
| 154 | asprintf(char **ret, const char *format, ...) | |||
| 155 | { | |||
| 156 | char buf[256]; | |||
| 157 | int len; | |||
| 158 | va_list ap; | |||
| 159 | ||||
| 160 | va_start(ap, format)__builtin_va_start(ap, format); | |||
| 161 | len = vsnprintf(buf, sizeof(buf), format, ap)__builtin___vsnprintf_chk (buf, sizeof(buf), 0, __builtin_object_size (buf, 2 > 1 ? 1 : 0), format, ap); | |||
| 162 | va_end(ap)__builtin_va_end(ap); | |||
| 163 | ||||
| 164 | if (len < 0) | |||
| 165 | return -1; | |||
| 166 | ||||
| 167 | if (len < sizeof(buf)) { | |||
| 168 | *ret = strdup(buf); | |||
| 169 | } | |||
| 170 | else { | |||
| 171 | *ret = malloc(len + 1); /* snprintf doesn't count trailing '\0' */ | |||
| 172 | if (*ret != NULL((void*)0)) { | |||
| 173 | va_start(ap, format)__builtin_va_start(ap, format); | |||
| 174 | len = vsnprintf(*ret, len + 1, format, ap)__builtin___vsnprintf_chk (*ret, len + 1, 0, __builtin_object_size (*ret, 2 > 1 ? 1 : 0), format, ap); | |||
| 175 | va_end(ap)__builtin_va_end(ap); | |||
| 176 | if (len < 0) { | |||
| 177 | free(*ret); | |||
| 178 | *ret = NULL((void*)0); | |||
| 179 | } | |||
| 180 | } | |||
| 181 | } | |||
| 182 | ||||
| 183 | if (*ret == NULL((void*)0)) | |||
| 184 | return -1; | |||
| 185 | ||||
| 186 | return len; | |||
| 187 | } | |||
| 188 | #endif /* HAVE_ASPRINTF */ | |||
| 189 | ||||
| 190 | #ifndef HAVE_REALLOCARRAY | |||
| 191 | /* overflow checking realloc API from OpenBSD libc */ | |||
| 192 | static inline void * | |||
| 193 | reallocarray(void *optr, size_t n, size_t s) | |||
| 194 | { | |||
| 195 | if (n > 0 && (SIZE_MAX18446744073709551615ULL / n) < s) | |||
| 196 | return NULL((void*)0); | |||
| 197 | return realloc(optr, n * s); | |||
| ||||
| 198 | } | |||
| 199 | #endif | |||
| 200 | ||||
| 201 | # define mallocarray(n, s)reallocarray(((void*)0), n, s) reallocarray(NULL((void*)0), n, s) | |||
| 202 | ||||
| 203 | static void | |||
| 204 | InitBuffer(Buffer *b) | |||
| 205 | { | |||
| 206 | b->room = INIT_BUFFER_SIZE10000; | |||
| 207 | b->used = 0; | |||
| 208 | b->buff = mallocarray(INIT_BUFFER_SIZE, sizeof(char))reallocarray(((void*)0), 10000, sizeof(char)); | |||
| 209 | if (b->buff == NULL((void*)0)) | |||
| 210 | fatal("%s: Can't allocate memory in %s\n", ProgramName, __func__); | |||
| 211 | } | |||
| 212 | ||||
| 213 | #ifdef notyet | |||
| 214 | static void | |||
| 215 | FreeBuffer(Buffer *b) | |||
| 216 | { | |||
| 217 | free(b->buff); | |||
| 218 | } | |||
| 219 | #endif | |||
| 220 | ||||
| 221 | static void | |||
| 222 | AppendToBuffer(Buffer *b, const char *str, size_t len) | |||
| 223 | { | |||
| 224 | while (b->used + len > b->room) { | |||
| 225 | b->buff = reallocarray(b->buff, b->room, 2 * sizeof(char)); | |||
| 226 | if (b->buff == NULL((void*)0)) | |||
| 227 | fatal("%s: Can't allocate memory in %s\n", ProgramName, __func__); | |||
| 228 | b->room *= 2; | |||
| 229 | } | |||
| 230 | strncpy(b->buff + b->used, str, len)__builtin___strncpy_chk (b->buff + b->used, str, len, __builtin_object_size (b->buff + b->used, 2 > 1 ? 1 : 0)); | |||
| 231 | b->used += len; | |||
| 232 | } | |||
| 233 | ||||
| 234 | static void | |||
| 235 | InitEntries(Entries *e) | |||
| 236 | { | |||
| 237 | e->room = INIT_ENTRY_SIZE500; | |||
| 238 | e->used = 0; | |||
| 239 | e->entry = mallocarray(INIT_ENTRY_SIZE, sizeof(Entry))reallocarray(((void*)0), 500, sizeof(Entry)); | |||
| 240 | if (e->entry == NULL((void*)0)) | |||
| 241 | fatal("%s: Can't allocate memory in %s\n", ProgramName, __func__); | |||
| 242 | ||||
| 243 | } | |||
| 244 | ||||
| 245 | static void | |||
| 246 | FreeEntries(Entries *e) | |||
| 247 | { | |||
| 248 | size_t i; | |||
| 249 | ||||
| 250 | for (i = 0; i < e->used; i++) { | |||
| 251 | if (e->entry[i].usable) { | |||
| 252 | free(e->entry[i].tag); | |||
| 253 | free(e->entry[i].value); | |||
| 254 | } | |||
| 255 | } | |||
| 256 | free(e->entry); | |||
| 257 | } | |||
| 258 | ||||
| 259 | static void | |||
| 260 | AddEntry(Entries *e, Entry *entry) | |||
| 261 | { | |||
| 262 | size_t n; | |||
| 263 | ||||
| 264 | for (n = 0; n < e->used; n++) { | |||
| 265 | if (!strcmp(e->entry[n].tag, entry->tag)) { | |||
| 266 | /* overwrite old entry */ | |||
| 267 | if (e->entry[n].lineno && !quiet) { | |||
| 268 | fprintf(stderr__stderrp, | |||
| 269 | "%s: \"%s\" on line %d overrides entry on line %d\n", | |||
| 270 | ProgramName, entry->tag, entry->lineno, | |||
| 271 | e->entry[n].lineno); | |||
| 272 | } | |||
| 273 | free(e->entry[n].tag); | |||
| 274 | free(e->entry[n].value); | |||
| 275 | entry->usable = True1; | |||
| 276 | e->entry[n] = *entry; | |||
| 277 | return; /* ok to leave, now there's only one of each tag in db */ | |||
| 278 | } | |||
| 279 | } | |||
| 280 | ||||
| 281 | if (e->used == e->room) { | |||
| 282 | e->entry = reallocarray(e->entry, e->room, 2 * sizeof(Entry)); | |||
| 283 | if (e->entry == NULL((void*)0)) | |||
| 284 | fatal("%s: Can't allocate memory in %s\n", ProgramName, __func__); | |||
| 285 | e->room *= 2; | |||
| 286 | } | |||
| 287 | entry->usable = True1; | |||
| 288 | e->entry[e->used++] = *entry; | |||
| 289 | } | |||
| 290 | ||||
| 291 | static int | |||
| 292 | CompareEntries(const void *e1, const void *e2) | |||
| 293 | { | |||
| 294 | return strcmp(((const Entry *) e1)->tag, ((const Entry *) e2)->tag); | |||
| 295 | } | |||
| 296 | ||||
| 297 | static void | |||
| 298 | AppendEntryToBuffer(Buffer *b, Entry *entry) | |||
| 299 | { | |||
| 300 | AppendToBuffer(b, entry->tag, strlen(entry->tag)); | |||
| 301 | AppendToBuffer(b, ":\t", 2); | |||
| 302 | AppendToBuffer(b, entry->value, strlen(entry->value)); | |||
| 303 | AppendToBuffer(b, "\n", 1); | |||
| 304 | } | |||
| 305 | ||||
| 306 | /* | |||
| 307 | * Return the position of the first unescaped occurrence of dest in string. | |||
| 308 | * If lines is non-null, return the number of newlines skipped over. | |||
| 309 | */ | |||
| 310 | static const char * | |||
| 311 | FindFirst(const char *string, char dest, int *lines) | |||
| 312 | { | |||
| 313 | if (lines) | |||
| 314 | *lines = 0; | |||
| 315 | for (;;) { | |||
| 316 | if (*string == '\0') | |||
| 317 | return NULL((void*)0); | |||
| 318 | if (*string == '\\') { | |||
| 319 | if (*++string == '\0') | |||
| 320 | return NULL((void*)0); | |||
| 321 | } | |||
| 322 | else if (*string == dest) | |||
| 323 | return string; | |||
| 324 | if (*string == '\n' && lines) | |||
| 325 | (*lines)++; | |||
| 326 | string++; | |||
| 327 | } | |||
| 328 | } | |||
| 329 | ||||
| 330 | static void | |||
| 331 | GetEntries(Entries *entries, Buffer *buff, int bequiet) | |||
| 332 | { | |||
| 333 | const char *line, *colon, *temp, *str; | |||
| 334 | Entry entry; | |||
| 335 | size_t length; | |||
| 336 | int lineno = 0; | |||
| 337 | int lines_skipped; | |||
| 338 | ||||
| 339 | str = buff->buff; | |||
| 340 | if (!str) | |||
| ||||
| 341 | return; | |||
| 342 | for (; str < buff->buff + buff->used; | |||
| 343 | str = line + 1, lineno += lines_skipped) { | |||
| 344 | line = FindFirst(str, '\n', &lines_skipped); | |||
| 345 | lineno++; | |||
| 346 | if (!line) | |||
| 347 | line = buff->buff + buff->used; | |||
| 348 | if (*str == '!') | |||
| 349 | continue; | |||
| 350 | if (*str == '\n') | |||
| 351 | continue; | |||
| 352 | if (!bequiet && *str == '#') { | |||
| 353 | int dummy; | |||
| 354 | ||||
| 355 | if (sscanf(str, "# %d", &dummy) == 1 || | |||
| 356 | sscanf(str, "# line %d", &dummy) == 1) | |||
| 357 | lineno = dummy - 1; | |||
| 358 | continue; | |||
| 359 | } | |||
| 360 | for (temp = str; | |||
| 361 | *temp && *temp != '\n' && isascii(*temp) && isspace(*temp); | |||
| 362 | temp++); | |||
| 363 | if (!*temp || *temp == '\n') | |||
| 364 | continue; | |||
| 365 | ||||
| 366 | colon = FindFirst(str, ':', NULL((void*)0)); | |||
| 367 | if (!colon || colon > line) { | |||
| 368 | if (!bequiet && !quiet) | |||
| 369 | fprintf(stderr__stderrp, | |||
| 370 | "%s: colon missing on line %d, ignoring line\n", | |||
| 371 | ProgramName, lineno); | |||
| 372 | continue; | |||
| 373 | } | |||
| 374 | ||||
| 375 | /* strip leading and trailing blanks from name and store result */ | |||
| 376 | while (*str == ' ' || *str == '\t') | |||
| 377 | str++; | |||
| 378 | length = colon - str; | |||
| 379 | while (length && (str[length - 1] == ' ' || str[length - 1] == '\t')) | |||
| 380 | length--; | |||
| 381 | entry.tag = malloc(length + 1); | |||
| 382 | strncpy(entry.tag, str, length)__builtin___strncpy_chk (entry.tag, str, length, __builtin_object_size (entry.tag, 2 > 1 ? 1 : 0)); | |||
| 383 | entry.tag[length] = '\0'; | |||
| 384 | ||||
| 385 | /* strip leading and trailing blanks from value and store result */ | |||
| 386 | colon++; | |||
| 387 | while (*colon == ' ' || *colon == '\t') | |||
| 388 | colon++; | |||
| 389 | length = line - colon; | |||
| 390 | entry.value = malloc(length + 1); | |||
| 391 | strncpy(entry.value, colon, length)__builtin___strncpy_chk (entry.value, colon, length, __builtin_object_size (entry.value, 2 > 1 ? 1 : 0)); | |||
| 392 | entry.value[length] = '\0'; | |||
| 393 | entry.lineno = bequiet ? 0 : lineno; | |||
| 394 | ||||
| 395 | AddEntry(entries, &entry); | |||
| 396 | } | |||
| 397 | } | |||
| 398 | ||||
| 399 | static void | |||
| 400 | GetEntriesString(Entries *entries, char *str) | |||
| 401 | { | |||
| 402 | Buffer buff; | |||
| 403 | ||||
| 404 | if (str && *str) { | |||
| 405 | buff.buff = str; | |||
| 406 | buff.used = strlen(str); | |||
| 407 | GetEntries(entries, &buff, 1); | |||
| 408 | } | |||
| 409 | } | |||
| 410 | ||||
| 411 | static void | |||
| 412 | ReadFile(Buffer *b, FILE *input) | |||
| 413 | { | |||
| 414 | char buf[BUFSIZ1024 + 1]; | |||
| 415 | size_t bytes; | |||
| 416 | ||||
| 417 | b->used = 0; | |||
| 418 | while (!feof(input) && (bytes = fread(buf, 1, BUFSIZ1024, input)) > 0) { | |||
| 419 | #ifdef WIN32 | |||
| 420 | char *p; | |||
| 421 | ||||
| 422 | buf[bytes] = '\0'; | |||
| 423 | for (p = buf; p = strchr(p, '\r');) { | |||
| 424 | if (p[-1] == '\\' && p[1] == '\n') { | |||
| 425 | bytes -= 3; | |||
| 426 | strcpy(p - 1, p + 2)__builtin___strcpy_chk (p - 1, p + 2, __builtin_object_size ( p - 1, 2 > 1 ? 1 : 0)); | |||
| 427 | } | |||
| 428 | } | |||
| 429 | #endif | |||
| 430 | AppendToBuffer(b, buf, bytes); | |||
| 431 | } | |||
| 432 | AppendToBuffer(b, "", 1); | |||
| 433 | } | |||
| 434 | ||||
| 435 | static void | |||
| 436 | AddDef(String *buff, const char *title, const char *value) | |||
| 437 | { | |||
| 438 | #ifdef PATHETICCPP | |||
| 439 | if (need_real_defines) { | |||
| 440 | addstring(buff, "\n#define "); | |||
| 441 | addtokstring(buff, title); | |||
| 442 | if (value && (value[0] != '\0')) { | |||
| 443 | addstring(buff, " "); | |||
| 444 | addstring(buff, value); | |||
| 445 | } | |||
| 446 | return; | |||
| 447 | } | |||
| 448 | #endif | |||
| 449 | if (buff->used) { | |||
| 450 | if (oper == OPSYMBOLS0) | |||
| 451 | addstring(buff, "\n-D"); | |||
| 452 | else | |||
| 453 | addstring(buff, " -D"); | |||
| 454 | } | |||
| 455 | else | |||
| 456 | addstring(buff, "-D"); | |||
| 457 | addtokstring(buff, title); | |||
| 458 | if (value && (value[0] != '\0')) { | |||
| 459 | addstring(buff, "="); | |||
| 460 | addescapedstring(buff, value); | |||
| 461 | } | |||
| 462 | } | |||
| 463 | ||||
| 464 | static void | |||
| 465 | AddSimpleDef(String *buff, const char *title) | |||
| 466 | { | |||
| 467 | AddDef(buff, title, (char *) NULL((void*)0)); | |||
| 468 | } | |||
| 469 | ||||
| 470 | static void | |||
| 471 | AddDefQ(String *buff, const char *title, const char *value) | |||
| 472 | { | |||
| 473 | #ifdef PATHETICCPP | |||
| 474 | if (need_real_defines) | |||
| 475 | AddDef(buff, title, value); | |||
| 476 | else | |||
| 477 | #endif | |||
| 478 | if (value && (value[0] != '\0')) { | |||
| 479 | AddSimpleDef(buff, title); | |||
| 480 | addstring(buff, "=\""); | |||
| 481 | addescapedstring(buff, value); | |||
| 482 | addstring(buff, "\""); | |||
| 483 | } | |||
| 484 | else | |||
| 485 | AddDef(buff, title, NULL((void*)0)); | |||
| 486 | } | |||
| 487 | ||||
| 488 | static void | |||
| 489 | AddNum(String *buff, const char *title, int value) | |||
| 490 | { | |||
| 491 | char num[20]; | |||
| 492 | ||||
| 493 | snprintf(num, sizeof(num), "%d", value)__builtin___snprintf_chk (num, sizeof(num), 0, __builtin_object_size (num, 2 > 1 ? 1 : 0), "%d", value); | |||
| 494 | AddDef(buff, title, num); | |||
| 495 | } | |||
| 496 | ||||
| 497 | static void | |||
| 498 | AddDefTok(String *buff, const char *prefix, char *title) | |||
| 499 | { | |||
| 500 | char name[512]; | |||
| 501 | ||||
| 502 | snprintf(name, sizeof(name), "%s%s", prefix, title)__builtin___snprintf_chk (name, sizeof(name), 0, __builtin_object_size (name, 2 > 1 ? 1 : 0), "%s%s", prefix, title); | |||
| 503 | AddSimpleDef(buff, name); | |||
| 504 | } | |||
| 505 | ||||
| 506 | static void | |||
| 507 | AddDefHostname(String *buff, const char *title, const char *value) | |||
| 508 | { | |||
| 509 | char *s; | |||
| 510 | char name[512]; | |||
| 511 | char c; | |||
| 512 | ||||
| 513 | strncpy(name, value, sizeof(name) - 1)__builtin___strncpy_chk (name, value, sizeof(name) - 1, __builtin_object_size (name, 2 > 1 ? 1 : 0)); | |||
| 514 | name[sizeof(name) - 1] = '\0'; | |||
| 515 | for (s = name; (c = *s); s++) { | |||
| 516 | if (!isalpha(c) && !isdigit(c) && | |||
| 517 | c != '_' && c != '.' && c != ':' && c != '-') | |||
| 518 | *s = '_'; | |||
| 519 | } | |||
| 520 | AddDef(buff, title, name); | |||
| 521 | } | |||
| 522 | ||||
| 523 | static void | |||
| 524 | AddUndef(String *buff, const char *title) | |||
| 525 | { | |||
| 526 | #ifdef PATHETICCPP | |||
| 527 | if (need_real_defines) { | |||
| 528 | addstring(buff, "\n#undef "); | |||
| 529 | addstring(buff, title); | |||
| 530 | return; | |||
| 531 | } | |||
| 532 | #endif | |||
| 533 | if (buff->used) { | |||
| 534 | if (oper == OPSYMBOLS0) | |||
| 535 | addstring(buff, "\n-U"); | |||
| 536 | else | |||
| 537 | addstring(buff, " -U"); | |||
| 538 | } | |||
| 539 | else | |||
| 540 | addstring(buff, "-U"); | |||
| 541 | addtokstring(buff, title); | |||
| 542 | } | |||
| 543 | ||||
| 544 | static void | |||
| 545 | DoCmdDefines(String *buff) | |||
| 546 | { | |||
| 547 | int i; | |||
| 548 | char *arg, *val; | |||
| 549 | ||||
| 550 | for (i = 0; i < num_cmd_defines; i++) { | |||
| 551 | arg = cmd_defines[i]; | |||
| 552 | if (arg[1] == 'D') { | |||
| 553 | val = strchr(arg, '='); | |||
| 554 | if (val) { | |||
| 555 | *val = '\0'; | |||
| 556 | AddDefQ(buff, arg + 2, val + 1); | |||
| 557 | *val = '='; | |||
| 558 | } | |||
| 559 | else | |||
| 560 | AddSimpleDef(buff, arg + 2); | |||
| 561 | } | |||
| 562 | else if (arg[1] == 'U') { | |||
| 563 | AddUndef(buff, arg + 2); | |||
| 564 | } | |||
| 565 | else if (!strcmp(arg, "-undef") && oper != OPSYMBOLS0) { | |||
| 566 | addstring(buff, " -undef"); | |||
| 567 | } | |||
| 568 | } | |||
| 569 | } | |||
| 570 | ||||
| 571 | static int | |||
| 572 | Resolution(int pixels, int mm) | |||
| 573 | { | |||
| 574 | if (mm == 0) | |||
| 575 | return 0; | |||
| 576 | else | |||
| 577 | return ((pixels * 100000 / mm) + 50) / 100; | |||
| 578 | } | |||
| 579 | ||||
| 580 | static void | |||
| 581 | DoDisplayDefines(Display *display, String *defs, char *host) | |||
| 582 | { | |||
| 583 | #ifndef MAXHOSTNAMELEN256 | |||
| 584 | #define MAXHOSTNAMELEN256 255 | |||
| 585 | #endif | |||
| 586 | char client[MAXHOSTNAMELEN256], server[MAXHOSTNAMELEN256], *colon; | |||
| 587 | char **extnames; | |||
| 588 | int n; | |||
| 589 | ||||
| 590 | XmuGetHostname(client, MAXHOSTNAMELEN256); | |||
| 591 | strncpy(server, XDisplayName(host), sizeof(server))__builtin___strncpy_chk (server, XDisplayName(host), sizeof(server ), __builtin_object_size (server, 2 > 1 ? 1 : 0)); | |||
| 592 | server[sizeof(server) - 1] = '\0'; | |||
| 593 | /* search for final colon to skip over any embedded colons in IPv6 | |||
| 594 | numeric address forms */ | |||
| 595 | colon = strrchr(server, ':'); | |||
| 596 | n = 0; | |||
| 597 | if (colon) { | |||
| 598 | /* remove extra colon if there are exactly two, since it indicates | |||
| 599 | DECnet. Three colons is an IPv6 address ending in :: though. */ | |||
| 600 | if ((colon > server) && (*(colon - 1) == ':') && | |||
| 601 | (((colon - 1) == server) || (*(colon - 2) != ':'))) { | |||
| 602 | *(colon - 1) = ':'; | |||
| 603 | } | |||
| 604 | *colon++ = '\0'; | |||
| 605 | sscanf(colon, "%d", &n); | |||
| 606 | } | |||
| 607 | if (!*server || !strcmp(server, "unix") || !strcmp(server, "localhost")) | |||
| 608 | strcpy(server, client)__builtin___strcpy_chk (server, client, __builtin_object_size (server, 2 > 1 ? 1 : 0)); | |||
| 609 | AddDefHostname(defs, "HOST", server); /* R3 compatibility */ | |||
| 610 | AddDefHostname(defs, "SERVERHOST", server); | |||
| 611 | AddDefTok(defs, "SRVR_", server); | |||
| 612 | AddNum(defs, "DISPLAY_NUM", n); | |||
| 613 | AddDefHostname(defs, "CLIENTHOST", client); | |||
| 614 | AddDefTok(defs, "CLNT_", client); | |||
| 615 | AddNum(defs, "VERSION", ProtocolVersion(display)(((_XPrivDisplay)(display))->proto_major_version)); | |||
| 616 | AddNum(defs, "REVISION", ProtocolRevision(display)(((_XPrivDisplay)(display))->proto_minor_version)); | |||
| 617 | AddDefQ(defs, "VENDOR", ServerVendor(display)(((_XPrivDisplay)(display))->vendor)); | |||
| 618 | AddDefTok(defs, "VNDR_", ServerVendor(display)(((_XPrivDisplay)(display))->vendor)); | |||
| 619 | AddNum(defs, "RELEASE", VendorRelease(display)(((_XPrivDisplay)(display))->release)); | |||
| 620 | AddNum(defs, "NUM_SCREENS", ScreenCount(display)(((_XPrivDisplay)(display))->nscreens)); | |||
| 621 | extnames = XListExtensions(display, &n); | |||
| 622 | while (--n >= 0) | |||
| 623 | AddDefTok(defs, "EXT_", extnames[n]); | |||
| 624 | XFreeExtensionList(extnames); | |||
| 625 | } | |||
| 626 | ||||
| 627 | static const char *ClassNames[] = { | |||
| 628 | "StaticGray", | |||
| 629 | "GrayScale", | |||
| 630 | "StaticColor", | |||
| 631 | "PseudoColor", | |||
| 632 | "TrueColor", | |||
| 633 | "DirectColor" | |||
| 634 | }; | |||
| 635 | ||||
| 636 | #define NUM_CLASS_NAMES(int)(sizeof(ClassNames) / sizeof(ClassNames[0])) (int)(sizeof(ClassNames) / sizeof(ClassNames[0])) | |||
| 637 | ||||
| 638 | static void | |||
| 639 | DoScreenDefines(Display *display, int scrno, String *defs) | |||
| 640 | { | |||
| 641 | Screen *screen; | |||
| 642 | Visual *visual; | |||
| 643 | XVisualInfo vinfo, *vinfos; | |||
| 644 | int nv, i, j; | |||
| 645 | char name[50]; | |||
| 646 | ||||
| 647 | screen = ScreenOfDisplay(display, scrno)(&((_XPrivDisplay)(display))->screens[scrno]); | |||
| 648 | visual = DefaultVisualOfScreen(screen)((screen)->root_visual); | |||
| 649 | vinfo.screen = scrno; | |||
| 650 | vinfos = XGetVisualInfo(display, VisualScreenMask0x2, &vinfo, &nv); | |||
| 651 | AddNum(defs, "SCREEN_NUM", scrno); | |||
| 652 | AddNum(defs, "WIDTH", screen->width); | |||
| 653 | AddNum(defs, "HEIGHT", screen->height); | |||
| 654 | AddNum(defs, "X_RESOLUTION", Resolution(screen->width, screen->mwidth)); | |||
| 655 | AddNum(defs, "Y_RESOLUTION", Resolution(screen->height, screen->mheight)); | |||
| 656 | AddNum(defs, "PLANES", DisplayPlanes(display, scrno)((&((_XPrivDisplay)(display))->screens[scrno])->root_depth )); | |||
| 657 | AddNum(defs, "BITS_PER_RGB", visual->bits_per_rgb); | |||
| 658 | if (visual->class >= 0 && visual->class < NUM_CLASS_NAMES(int)(sizeof(ClassNames) / sizeof(ClassNames[0]))) { | |||
| 659 | AddDefQ(defs, "CLASS", ClassNames[visual->class]); | |||
| 660 | snprintf(name, sizeof(name), "CLASS_%s", ClassNames[visual->class])__builtin___snprintf_chk (name, sizeof(name), 0, __builtin_object_size (name, 2 > 1 ? 1 : 0), "CLASS_%s", ClassNames[visual-> class]); | |||
| 661 | AddNum(defs, name, (int) visual->visualid); | |||
| 662 | } | |||
| 663 | else { | |||
| 664 | fprintf(stderr__stderrp, | |||
| 665 | "%s: unknown visual type %d for default visual id 0x%lx\n", | |||
| 666 | ProgramName, visual->class, visual->visualid); | |||
| 667 | } | |||
| 668 | switch (visual->class) { | |||
| 669 | case StaticColor2: | |||
| 670 | case PseudoColor3: | |||
| 671 | case TrueColor4: | |||
| 672 | case DirectColor5: | |||
| 673 | AddSimpleDef(defs, "COLOR"); | |||
| 674 | break; | |||
| 675 | } | |||
| 676 | for (i = 0; i < nv; i++) { | |||
| 677 | for (j = i; --j >= 0;) { | |||
| 678 | if (vinfos[j].class == vinfos[i].class && | |||
| 679 | vinfos[j].depth == vinfos[i].depth) | |||
| 680 | break; | |||
| 681 | } | |||
| 682 | if (j < 0) { | |||
| 683 | if (vinfos[i].class >= 0 && vinfos[i].class < NUM_CLASS_NAMES(int)(sizeof(ClassNames) / sizeof(ClassNames[0]))) { | |||
| 684 | snprintf(name, sizeof(name), "CLASS_%s_%d",__builtin___snprintf_chk (name, sizeof(name), 0, __builtin_object_size (name, 2 > 1 ? 1 : 0), "CLASS_%s_%d", ClassNames[vinfos[i ].class], vinfos[i].depth) | |||
| 685 | ClassNames[vinfos[i].class], vinfos[i].depth)__builtin___snprintf_chk (name, sizeof(name), 0, __builtin_object_size (name, 2 > 1 ? 1 : 0), "CLASS_%s_%d", ClassNames[vinfos[i ].class], vinfos[i].depth); | |||
| 686 | AddNum(defs, name, (int) vinfos[i].visualid); | |||
| 687 | } | |||
| 688 | else { | |||
| 689 | fprintf(stderr__stderrp, | |||
| 690 | "%s: unknown visual type %d for visual id 0x%lx\n", | |||
| 691 | ProgramName, vinfos[i].class, vinfos[i].visualid); | |||
| 692 | } | |||
| 693 | } | |||
| 694 | } | |||
| 695 | XFree(vinfos); | |||
| 696 | } | |||
| 697 | ||||
| 698 | static Entry * | |||
| 699 | FindEntry(Entries *db, Buffer *b) | |||
| 700 | { | |||
| 701 | size_t i; | |||
| 702 | register Entry *e; | |||
| 703 | Entries phoney; | |||
| 704 | Entry entry; | |||
| 705 | ||||
| 706 | entry.usable = False0; | |||
| 707 | entry.tag = NULL((void*)0); | |||
| 708 | entry.value = NULL((void*)0); | |||
| 709 | phoney.used = 0; | |||
| 710 | phoney.room = 1; | |||
| 711 | phoney.entry = &entry; | |||
| 712 | GetEntries(&phoney, b, 1); | |||
| 713 | if (phoney.used < 1) | |||
| 714 | return NULL((void*)0); | |||
| 715 | for (i = 0; i < db->used; i++) { | |||
| 716 | e = &db->entry[i]; | |||
| 717 | if (!e->usable) | |||
| 718 | continue; | |||
| 719 | if (strcmp(e->tag, entry.tag)) | |||
| 720 | continue; | |||
| 721 | e->usable = False0; | |||
| 722 | if (strcmp(e->value, entry.value)) | |||
| 723 | return e; | |||
| 724 | return NULL((void*)0); | |||
| 725 | } | |||
| 726 | return NULL((void*)0); | |||
| 727 | } | |||
| 728 | ||||
| 729 | static void | |||
| 730 | EditFile(Entries *new, FILE *in, FILE *out) | |||
| 731 | { | |||
| 732 | Buffer b; | |||
| 733 | char buff[BUFSIZ1024]; | |||
| 734 | register Entry *e; | |||
| 735 | register char *c; | |||
| 736 | size_t i; | |||
| 737 | ||||
| 738 | InitBuffer(&b); | |||
| 739 | while (in) { | |||
| 740 | b.used = 0; | |||
| 741 | while (1) { | |||
| 742 | buff[0] = '\0'; | |||
| 743 | if (!fgets(buff, BUFSIZ1024, in)) | |||
| 744 | goto cleanup; | |||
| 745 | AppendToBuffer(&b, buff, strlen(buff)); | |||
| 746 | c = &b.buff[b.used - 1]; | |||
| 747 | if ((*(c--) == '\n') && (b.used == 1 || *c != '\\')) | |||
| 748 | break; | |||
| 749 | } | |||
| 750 | if ((e = FindEntry(new, &b))) | |||
| 751 | fprintf(out, "%s:\t%s\n", e->tag, e->value); | |||
| 752 | else | |||
| 753 | fwrite(b.buff, 1, b.used, out); | |||
| 754 | } | |||
| 755 | cleanup: | |||
| 756 | for (i = 0; i < new->used; i++) { | |||
| 757 | e = &new->entry[i]; | |||
| 758 | if (e->usable) | |||
| 759 | fprintf(out, "%s:\t%s\n", e->tag, e->value); | |||
| 760 | } | |||
| 761 | } | |||
| 762 | ||||
| 763 | static void _X_NORETURN__attribute((noreturn)) _X_COLD__attribute__((__cold__)) | |||
| 764 | Syntax(const char *errmsg) | |||
| 765 | { | |||
| 766 | if (errmsg != NULL((void*)0)) | |||
| 767 | fprintf(stderr__stderrp, "%s: %s\n", ProgramName, errmsg); | |||
| 768 | ||||
| 769 | fprintf(stderr__stderrp, | |||
| 770 | "usage: %s [-options ...] [filename]\n\n" | |||
| 771 | "where options include:\n" | |||
| 772 | " -help print this help message\n" | |||
| 773 | " -version print the program version\n" | |||
| 774 | " -display host:dpy display to use\n" | |||
| 775 | " -all do all resources [default]\n" | |||
| 776 | " -global do screen-independent resources\n" | |||
| 777 | " -screen do screen-specific resources for one screen\n" | |||
| 778 | " -screens do screen-specific resources for all screens\n" | |||
| 779 | " -n show but don't do changes\n" | |||
| 780 | " -cpp filename preprocessor to use [%s]\n" | |||
| 781 | " -nocpp do not use a preprocessor\n" | |||
| 782 | " -query query resources\n" | |||
| 783 | " -load load resources from file [default]\n" | |||
| 784 | " -override add in resources from file\n" | |||
| 785 | " -merge merge resources from file & sort\n" | |||
| 786 | " -edit filename edit resources into file\n" | |||
| 787 | " -backup string backup suffix for -edit [%s]\n" | |||
| 788 | " -symbols show preprocessor symbols\n" | |||
| 789 | " -remove remove resources\n" | |||
| 790 | " -retain avoid server reset (avoid using this)\n" | |||
| 791 | " -quiet don't warn about duplicates\n" | |||
| 792 | " -Dname[=value], -Uname, -Idirectory passed to preprocessor\n" | |||
| 793 | "\n" | |||
| 794 | "A - or no input filename represents stdin.\n", | |||
| 795 | ProgramName, cpp_program ? cpp_program : "", BACKUP_SUFFIX".bak"); | |||
| 796 | exit(1); | |||
| 797 | } | |||
| 798 | ||||
| 799 | /* | |||
| 800 | * The following is a hack until XrmParseCommand is ready. It determines | |||
| 801 | * whether or not the given string is an abbreviation of the arg. | |||
| 802 | */ | |||
| 803 | ||||
| 804 | static Boolint | |||
| 805 | isabbreviation(const char *arg, const char *s, size_t minslen) | |||
| 806 | { | |||
| 807 | size_t arglen; | |||
| 808 | size_t slen; | |||
| 809 | ||||
| 810 | /* exact match */ | |||
| 811 | if (!strcmp(arg, s)) | |||
| 812 | return (True1); | |||
| 813 | ||||
| 814 | arglen = strlen(arg); | |||
| 815 | slen = strlen(s); | |||
| 816 | ||||
| 817 | /* too long or too short */ | |||
| 818 | if (slen >= arglen || slen < minslen) | |||
| 819 | return (False0); | |||
| 820 | ||||
| 821 | /* abbreviation */ | |||
| 822 | if (strncmp(arg, s, slen) == 0) | |||
| 823 | return (True1); | |||
| 824 | ||||
| 825 | /* bad */ | |||
| 826 | return (False0); | |||
| 827 | } | |||
| 828 | ||||
| 829 | static void | |||
| 830 | addstring(String *arg, const char *s) | |||
| 831 | { | |||
| 832 | if (arg->used + strlen(s) + 1 >= arg->room) { | |||
| 833 | if (arg->val) | |||
| 834 | arg->val = realloc(arg->val, arg->room + CHUNK_SIZE4096); | |||
| 835 | else | |||
| 836 | arg->val = malloc(arg->room + CHUNK_SIZE4096); | |||
| 837 | if (arg->val == NULL((void*)0)) | |||
| 838 | fatal("%s: Not enough memory\n", ProgramName); | |||
| 839 | arg->room += CHUNK_SIZE4096; | |||
| 840 | } | |||
| 841 | if (arg->used) | |||
| 842 | strcat(arg->val, s)__builtin___strcat_chk (arg->val, s, __builtin_object_size (arg->val, 2 > 1 ? 1 : 0)); | |||
| 843 | else | |||
| 844 | strcpy(arg->val, s)__builtin___strcpy_chk (arg->val, s, __builtin_object_size (arg->val, 2 > 1 ? 1 : 0)); | |||
| 845 | arg->used += strlen(s); | |||
| 846 | } | |||
| 847 | ||||
| 848 | static void | |||
| 849 | addescapedstring(String *arg, const char *s) | |||
| 850 | { | |||
| 851 | char copy[512], *c; | |||
| 852 | ||||
| 853 | for (c = copy; *s && c < ©[sizeof(copy) - 1]; s++) { | |||
| 854 | switch (*s) { | |||
| 855 | case '"': | |||
| 856 | case '\'': | |||
| 857 | case '`': | |||
| 858 | case '$': | |||
| 859 | case '\\': | |||
| 860 | *c++ = '_'; | |||
| 861 | break; | |||
| 862 | default: | |||
| 863 | *c++ = *s; | |||
| 864 | } | |||
| 865 | } | |||
| 866 | *c = 0; | |||
| 867 | addstring(arg, copy); | |||
| 868 | } | |||
| 869 | ||||
| 870 | static void | |||
| 871 | addtokstring(String *arg, const char *s) | |||
| 872 | { | |||
| 873 | char copy[512], *c; | |||
| 874 | ||||
| 875 | for (c = copy; *s && c < ©[sizeof(copy) - 1]; s++) { | |||
| 876 | if (!isalpha(*s) && !isdigit(*s) && *s != '_') | |||
| 877 | *c++ = '_'; | |||
| 878 | else | |||
| 879 | *c++ = *s; | |||
| 880 | } | |||
| 881 | *c = 0; | |||
| 882 | addstring(arg, copy); | |||
| 883 | } | |||
| 884 | ||||
| 885 | ||||
| 886 | int | |||
| 887 | main(int argc, char *argv[]) | |||
| 888 | { | |||
| 889 | int i; | |||
| 890 | char *displayname = NULL((void*)0); | |||
| 891 | int whichResources = RALL0; | |||
| 892 | int retainProp = 0; | |||
| 893 | FILE *fp = NULL((void*)0); | |||
| 894 | Boolint need_newline; | |||
| 895 | ||||
| 896 | ProgramName = argv[0]; | |||
| 897 | ||||
| 898 | defines.room = defines.used = includes.room = includes.used = 0; | |||
| 899 | ||||
| 900 | /* initialize the includes String struct */ | |||
| 901 | addstring(&includes, ""); | |||
| 902 | ||||
| 903 | /* Pick the default cpp to use. This needs to be done before | |||
| 904 | * we parse the command line in order to honor -nocpp which sets | |||
| 905 | * it back to NULL. | |||
| 906 | */ | |||
| 907 | if (cpp_program == NULL((void*)0)) { | |||
| 908 | int number_of_elements | |||
| 909 | = (sizeof cpp_locations) / (sizeof cpp_locations[0]); | |||
| 910 | int j; | |||
| 911 | ||||
| 912 | for (j = 0; j < number_of_elements; j++) { | |||
| 913 | char *end, *dup; | |||
| 914 | ||||
| 915 | /* cut off arguments */ | |||
| 916 | dup = strdup(cpp_locations[j]); | |||
| 917 | end = strchr(dup, ' '); | |||
| 918 | if (end) | |||
| 919 | *end = '\0'; | |||
| 920 | if (access(dup, X_OK(1<<0)) == 0) { | |||
| 921 | cpp_program = cpp_locations[j]; | |||
| 922 | free(dup); | |||
| 923 | break; | |||
| 924 | } | |||
| 925 | free(dup); | |||
| 926 | } | |||
| 927 | } | |||
| 928 | ||||
| 929 | /* needs to be replaced with XrmParseCommand */ | |||
| 930 | ||||
| 931 | for (i = 1; i < argc; i++) { | |||
| 932 | char *arg = argv[i]; | |||
| 933 | ||||
| 934 | if (arg[0] == '-') { | |||
| 935 | if (arg[1] == '\0') { | |||
| 936 | filename = NULL((void*)0); | |||
| 937 | continue; | |||
| 938 | } | |||
| 939 | else if (isabbreviation("-help", arg, 2)) { | |||
| 940 | Syntax(NULL((void*)0)); | |||
| 941 | /* doesn't return */ | |||
| 942 | } | |||
| 943 | else if (isabbreviation("-version", arg, 2)) { | |||
| 944 | printf("%s\n", PACKAGE_STRING"xrdb 1.1.0"); | |||
| 945 | exit(0); | |||
| 946 | } | |||
| 947 | else if (isabbreviation("-display", arg, 2)) { | |||
| 948 | if (++i >= argc) | |||
| 949 | Syntax("-display requires an argument"); | |||
| 950 | displayname = argv[i]; | |||
| 951 | continue; | |||
| 952 | } | |||
| 953 | else if (isabbreviation("-geometry", arg, 3)) { | |||
| 954 | if (++i >= argc) | |||
| 955 | Syntax("-geometry requires an argument"); | |||
| 956 | /* ignore geometry */ | |||
| 957 | continue; | |||
| 958 | } | |||
| 959 | else if (isabbreviation("-cpp", arg, 2)) { | |||
| 960 | if (++i >= argc) | |||
| 961 | Syntax("-cpp requires an argument"); | |||
| 962 | cpp_program = argv[i]; | |||
| 963 | continue; | |||
| 964 | } | |||
| 965 | else if (!strcmp("-n", arg)) { | |||
| 966 | dont_execute = True1; | |||
| 967 | continue; | |||
| 968 | } | |||
| 969 | else if (isabbreviation("-nocpp", arg, 3)) { | |||
| 970 | cpp_program = NULL((void*)0); | |||
| 971 | continue; | |||
| 972 | } | |||
| 973 | else if (isabbreviation("-query", arg, 2)) { | |||
| 974 | oper = OPQUERY1; | |||
| 975 | continue; | |||
| 976 | } | |||
| 977 | else if (isabbreviation("-load", arg, 2)) { | |||
| 978 | oper = OPLOAD4; | |||
| 979 | continue; | |||
| 980 | } | |||
| 981 | else if (isabbreviation("-merge", arg, 2)) { | |||
| 982 | oper = OPMERGE5; | |||
| 983 | continue; | |||
| 984 | } | |||
| 985 | else if (isabbreviation("-override", arg, 2)) { | |||
| 986 | oper = OPOVERRIDE6; | |||
| 987 | continue; | |||
| 988 | } | |||
| 989 | else if (isabbreviation("-symbols", arg, 3)) { | |||
| 990 | oper = OPSYMBOLS0; | |||
| 991 | continue; | |||
| 992 | } | |||
| 993 | else if (isabbreviation("-remove", arg, 4)) { | |||
| 994 | oper = OPREMOVE2; | |||
| 995 | continue; | |||
| 996 | } | |||
| 997 | else if (isabbreviation("-edit", arg, 2)) { | |||
| 998 | if (++i >= argc) | |||
| 999 | Syntax("-edit requires an argument"); | |||
| 1000 | oper = OPEDIT3; | |||
| 1001 | editFile = argv[i]; | |||
| 1002 | continue; | |||
| 1003 | } | |||
| 1004 | else if (isabbreviation("-backup", arg, 2)) { | |||
| 1005 | if (++i >= argc) | |||
| 1006 | Syntax("-backup requires an argument"); | |||
| 1007 | backup_suffix = argv[i]; | |||
| 1008 | continue; | |||
| 1009 | } | |||
| 1010 | else if (isabbreviation("-all", arg, 2)) { | |||
| 1011 | whichResources = RALL0; | |||
| 1012 | continue; | |||
| 1013 | } | |||
| 1014 | else if (isabbreviation("-global", arg, 3)) { | |||
| 1015 | whichResources = RGLOBAL1; | |||
| 1016 | continue; | |||
| 1017 | } | |||
| 1018 | else if (isabbreviation("-screen", arg, 3)) { | |||
| 1019 | whichResources = RSCREEN2; | |||
| 1020 | continue; | |||
| 1021 | } | |||
| 1022 | else if (!strcmp("-screens", arg)) { | |||
| 1023 | whichResources = RSCREENS3; | |||
| 1024 | continue; | |||
| 1025 | } | |||
| 1026 | else if (isabbreviation("-retain", arg, 4)) { | |||
| 1027 | retainProp = 1; | |||
| 1028 | continue; | |||
| 1029 | } | |||
| 1030 | else if (isabbreviation("-quiet", arg, 2)) { | |||
| 1031 | quiet = True1; | |||
| 1032 | continue; | |||
| 1033 | } | |||
| 1034 | else if (arg[1] == 'I') { | |||
| 1035 | addstring(&includes, " "); | |||
| 1036 | addescapedstring(&includes, arg); | |||
| 1037 | continue; | |||
| 1038 | } | |||
| 1039 | else if (arg[1] == 'U' || arg[1] == 'D') { | |||
| 1040 | if (num_cmd_defines < MAX_CMD_DEFINES512) { | |||
| 1041 | cmd_defines[num_cmd_defines++] = arg; | |||
| 1042 | } | |||
| 1043 | else { | |||
| 1044 | fatal("%s: Too many -U/-D arguments\n", ProgramName); | |||
| 1045 | } | |||
| 1046 | continue; | |||
| 1047 | } | |||
| 1048 | else if (!strcmp("-undef", arg)) { | |||
| 1049 | if (num_cmd_defines < MAX_CMD_DEFINES512) { | |||
| 1050 | cmd_defines[num_cmd_defines++] = "-undef"; | |||
| 1051 | } | |||
| 1052 | else { | |||
| 1053 | fatal("%s: Too many cpp arguments\n", ProgramName); | |||
| 1054 | } | |||
| 1055 | continue; | |||
| 1056 | } | |||
| 1057 | fprintf(stderr__stderrp, "%s: unrecognized argument '%s'\n", | |||
| 1058 | ProgramName, arg); | |||
| 1059 | Syntax(NULL((void*)0)); | |||
| 1060 | } | |||
| 1061 | else if (arg[0] == '=') | |||
| 1062 | continue; | |||
| 1063 | else | |||
| 1064 | filename = arg; | |||
| 1065 | } /* end for */ | |||
| 1066 | ||||
| 1067 | #ifndef WIN32 | |||
| 1068 | while ((i = open("/dev/null", O_RDONLY0x0000)) < 3) | |||
| 1069 | ; /* make sure later freopen won't clobber things */ | |||
| 1070 | (void) close(i); | |||
| 1071 | #endif | |||
| 1072 | /* Open display */ | |||
| 1073 | if (!(dpy = XOpenDisplay(displayname))) | |||
| 1074 | fatal("%s: Can't open display '%s'\n", ProgramName, | |||
| 1075 | XDisplayName(displayname)); | |||
| 1076 | ||||
| 1077 | if (whichResources == RALL0 && ScreenCount(dpy)(((_XPrivDisplay)(dpy))->nscreens) == 1) | |||
| 1078 | whichResources = RGLOBAL1; | |||
| 1079 | ||||
| 1080 | #ifdef PATHETICCPP | |||
| 1081 | if (cpp_program && | |||
| 1082 | (oper == OPLOAD4 || oper == OPMERGE5 || oper == OPOVERRIDE6)) { | |||
| 1083 | need_real_defines = True1; | |||
| 1084 | #ifdef WIN32 | |||
| 1085 | strcpy(tmpname2, "xrdbD_XXXXXX")__builtin___strcpy_chk (tmpname2, "xrdbD_XXXXXX", __builtin_object_size (tmpname2, 2 > 1 ? 1 : 0)); | |||
| 1086 | strcpy(tmpname3, "\\temp\\xrdbD_XXXXXX")__builtin___strcpy_chk (tmpname3, "\\temp\\xrdbD_XXXXXX", __builtin_object_size (tmpname3, 2 > 1 ? 1 : 0)); | |||
| 1087 | #else | |||
| 1088 | strcpy(tmpname2, "/tmp/xrdbD_XXXXXX")__builtin___strcpy_chk (tmpname2, "/tmp/xrdbD_XXXXXX", __builtin_object_size (tmpname2, 2 > 1 ? 1 : 0)); | |||
| 1089 | #endif | |||
| 1090 | (void) mktemp(tmpname2); | |||
| 1091 | } | |||
| 1092 | #endif | |||
| 1093 | ||||
| 1094 | if (!filename && | |||
| 1095 | #ifdef PATHETICCPP | |||
| 1096 | need_real_defines | |||
| 1097 | #else | |||
| 1098 | (oper == OPLOAD4 || oper == OPMERGE5 || oper == OPOVERRIDE6) && | |||
| 1099 | (whichResources == RALL0 || whichResources == RSCREENS3) | |||
| 1100 | #endif | |||
| 1101 | ) { | |||
| 1102 | char inputbuf[1024]; | |||
| 1103 | ||||
| 1104 | #ifdef WIN32 | |||
| 1105 | strcpy(tmpname, "\\temp\\xrdb_XXXXXX")__builtin___strcpy_chk (tmpname, "\\temp\\xrdb_XXXXXX", __builtin_object_size (tmpname, 2 > 1 ? 1 : 0)); | |||
| 1106 | #else | |||
| 1107 | strcpy(tmpname, "/tmp/xrdb_XXXXXX")__builtin___strcpy_chk (tmpname, "/tmp/xrdb_XXXXXX", __builtin_object_size (tmpname, 2 > 1 ? 1 : 0)); | |||
| 1108 | #endif | |||
| 1109 | #ifndef HAVE_MKSTEMP1 | |||
| 1110 | (void) mktemp(tmpname); | |||
| 1111 | filename = tmpname; | |||
| 1112 | fp = fopen(filename, "w"); | |||
| 1113 | #else | |||
| 1114 | { | |||
| 1115 | int fd = mkstemp(tmpname); | |||
| 1116 | ||||
| 1117 | filename = tmpname; | |||
| 1118 | fp = fdopen(fd, "w"); | |||
| 1119 | } | |||
| 1120 | #endif /* MKSTEMP */ | |||
| 1121 | if (!fp) | |||
| 1122 | fatal("%s: Failed to open temp file: %s\n", ProgramName, filename); | |||
| 1123 | while (fgets(inputbuf, sizeof(inputbuf), stdin__stdinp) != NULL((void*)0)) | |||
| 1124 | fputs(inputbuf, fp); | |||
| 1125 | fclose(fp); | |||
| 1126 | } | |||
| 1127 | ||||
| 1128 | DoDisplayDefines(dpy, &defines, displayname); | |||
| 1129 | defines_base = defines.used; | |||
| 1130 | need_newline = (oper == OPQUERY1 || oper == OPSYMBOLS0 || | |||
| 1131 | (dont_execute && oper != OPREMOVE2)); | |||
| 1132 | InitBuffer(&buffer); | |||
| 1133 | if (whichResources == RGLOBAL1) | |||
| 1134 | Process(DefaultScreen(dpy)(((_XPrivDisplay)(dpy))->default_screen), False0, True1); | |||
| 1135 | else if (whichResources == RSCREEN2) | |||
| 1136 | Process(DefaultScreen(dpy)(((_XPrivDisplay)(dpy))->default_screen), True1, True1); | |||
| 1137 | else if (whichResources == RSCREENS3 || | |||
| 1138 | (oper != OPLOAD4 && oper != OPMERGE5 && oper != OPOVERRIDE6)) { | |||
| 1139 | if (whichResources == RALL0 && oper != OPSYMBOLS0) { | |||
| 1140 | if (need_newline) | |||
| 1141 | printf("! screen-independent resources\n"); | |||
| 1142 | Process(0, False0, True1); | |||
| 1143 | if (need_newline) | |||
| 1144 | printf("\n"); | |||
| 1145 | } | |||
| 1146 | for (i = 0; i < ScreenCount(dpy)(((_XPrivDisplay)(dpy))->nscreens); i++) { | |||
| 1147 | if (need_newline) { | |||
| 1148 | if (oper == OPSYMBOLS0) | |||
| 1149 | printf("# screen %d symbols\n", i); | |||
| 1150 | else { | |||
| 1151 | printf("! screen %d resources\n", i); | |||
| 1152 | printf("#if SCREEN_NUM == %d\n", i); | |||
| 1153 | } | |||
| 1154 | } | |||
| 1155 | Process(i, True1, True1); | |||
| 1156 | if (need_newline) { | |||
| 1157 | if (oper != OPSYMBOLS0) | |||
| 1158 | printf("#endif\n"); | |||
| 1159 | if (i + 1 != ScreenCount(dpy)(((_XPrivDisplay)(dpy))->nscreens)) | |||
| 1160 | printf("\n"); | |||
| 1161 | } | |||
| 1162 | } | |||
| 1163 | } | |||
| 1164 | else { | |||
| 1165 | Entries *dbs; | |||
| 1166 | ||||
| 1167 | dbs = mallocarray(ScreenCount(dpy), sizeof(Entries))reallocarray(((void*)0), (((_XPrivDisplay)(dpy))->nscreens ), sizeof(Entries)); | |||
| 1168 | if (dbs == NULL((void*)0)) | |||
| 1169 | fatal("%s: Can't allocate memory in %s\n", ProgramName, __func__); | |||
| 1170 | for (i = 0; i < ScreenCount(dpy)(((_XPrivDisplay)(dpy))->nscreens); i++) { | |||
| 1171 | Process(i, True1, False0); | |||
| 1172 | dbs[i] = newDB; | |||
| 1173 | } | |||
| 1174 | InitEntries(&newDB); | |||
| 1175 | if (oper == OPMERGE5 || oper == OPOVERRIDE6) | |||
| 1176 | GetEntriesString(&newDB, XResourceManagerString(dpy)); | |||
| 1177 | ShuffleEntries(&newDB, dbs, (unsigned) ScreenCount(dpy)(((_XPrivDisplay)(dpy))->nscreens)); | |||
| 1178 | if (need_newline) | |||
| 1179 | printf("! screen-independent resources\n"); | |||
| 1180 | ReProcess(0, False0); | |||
| 1181 | if (need_newline) | |||
| 1182 | printf("\n"); | |||
| 1183 | for (i = 0; i < ScreenCount(dpy)(((_XPrivDisplay)(dpy))->nscreens); i++) { | |||
| 1184 | newDB = dbs[i]; | |||
| 1185 | if (need_newline) { | |||
| 1186 | printf("! screen %d resources\n", i); | |||
| 1187 | printf("#if SCREEN_NUM == %d\n", i); | |||
| 1188 | } | |||
| 1189 | ReProcess(i, True1); | |||
| 1190 | if (need_newline) { | |||
| 1191 | printf("#endif\n"); | |||
| 1192 | if (i + 1 != ScreenCount(dpy)(((_XPrivDisplay)(dpy))->nscreens)) | |||
| 1193 | printf("\n"); | |||
| 1194 | } | |||
| 1195 | } | |||
| 1196 | } | |||
| 1197 | ||||
| 1198 | if (fp) | |||
| 1199 | unlink(filename); | |||
| 1200 | if (retainProp) | |||
| 1201 | XSetCloseDownMode(dpy, RetainPermanent1); | |||
| 1202 | XCloseDisplay(dpy); | |||
| 1203 | exit(0); | |||
| 1204 | } | |||
| 1205 | ||||
| 1206 | ||||
| 1207 | static void | |||
| 1208 | FormatEntries(Buffer *b, Entries *entries) | |||
| 1209 | { | |||
| 1210 | size_t i; | |||
| 1211 | ||||
| 1212 | b->used = 0; | |||
| 1213 | if (!entries->used) | |||
| 1214 | return; | |||
| 1215 | if (oper == OPMERGE5) | |||
| 1216 | qsort(entries->entry, entries->used, sizeof(Entry), CompareEntries); | |||
| 1217 | for (i = 0; i < entries->used; i++) { | |||
| 1218 | if (entries->entry[i].usable) | |||
| 1219 | AppendEntryToBuffer(b, &entries->entry[i]); | |||
| 1220 | } | |||
| 1221 | } | |||
| 1222 | ||||
| 1223 | static void | |||
| 1224 | StoreProperty(Display *display, Window root, Atom res_prop) | |||
| 1225 | { | |||
| 1226 | size_t len = buffer.used; | |||
| 1227 | int mode = PropModeReplace0; | |||
| 1228 | unsigned char *buf = (unsigned char *) buffer.buff; | |||
| 1229 | size_t max = ((unsigned) XMaxRequestSize(display) << 2) - 28; | |||
| 1230 | ||||
| 1231 | if (len > max) { | |||
| 1232 | XGrabServer(display); | |||
| 1233 | do { | |||
| 1234 | XChangeProperty(display, root, res_prop, XA_STRING((Atom) 31), 8, mode, buf, | |||
| 1235 | (int) max); | |||
| 1236 | buf += max; | |||
| 1237 | len -= max; | |||
| 1238 | mode = PropModeAppend2; | |||
| 1239 | } while (len > max); | |||
| 1240 | } | |||
| 1241 | XChangeProperty(display, root, res_prop, XA_STRING((Atom) 31), 8, mode, buf, | |||
| 1242 | (int) len); | |||
| 1243 | if (mode != PropModeReplace0) | |||
| 1244 | XUngrabServer(display); | |||
| 1245 | } | |||
| 1246 | ||||
| 1247 | static void | |||
| 1248 | Process(int scrno, Boolint doScreen, Boolint execute) | |||
| 1249 | { | |||
| 1250 | char *xdefs; | |||
| 1251 | Window root; | |||
| 1252 | Atom res_prop; | |||
| 1253 | FILE *input, *output; | |||
| 1254 | char *cmd; | |||
| 1255 | ||||
| 1256 | defines.val[defines_base] = '\0'; | |||
| 1257 | defines.used = defines_base; | |||
| 1258 | buffer.used = 0; | |||
| 1259 | InitEntries(&newDB); | |||
| 1260 | DoScreenDefines(dpy, scrno, &defines); | |||
| 1261 | DoCmdDefines(&defines); | |||
| 1262 | if (doScreen) { | |||
| 1263 | xdefs = XScreenResourceString(ScreenOfDisplay(dpy, scrno)(&((_XPrivDisplay)(dpy))->screens[scrno])); | |||
| 1264 | root = RootWindow(dpy, scrno)((&((_XPrivDisplay)(dpy))->screens[scrno])->root); | |||
| 1265 | res_prop = XInternAtom(dpy, SCREEN_RESOURCES"SCREEN_RESOURCES", False0); | |||
| 1266 | } | |||
| 1267 | else { | |||
| 1268 | xdefs = XResourceManagerString(dpy); | |||
| 1269 | root = RootWindow(dpy, 0)((&((_XPrivDisplay)(dpy))->screens[0])->root); | |||
| 1270 | res_prop = XA_RESOURCE_MANAGER((Atom) 23); | |||
| 1271 | } | |||
| 1272 | if (oper == OPSYMBOLS0) { | |||
| 1273 | printf("%s\n", defines.val); | |||
| 1274 | } | |||
| 1275 | else if (oper == OPQUERY1) { | |||
| 1276 | if (xdefs) | |||
| 1277 | printf("%s", xdefs); /* fputs broken in SunOS 4.0 */ | |||
| 1278 | } | |||
| 1279 | else if (oper == OPREMOVE2) { | |||
| 1280 | if (xdefs) | |||
| 1281 | XDeleteProperty(dpy, root, res_prop); | |||
| 1282 | } | |||
| 1283 | else if (oper == OPEDIT3) { | |||
| 1284 | char template[100], old[100]; | |||
| 1285 | ||||
| 1286 | input = fopen(editFile, "r"); | |||
| 1287 | snprintf(template, sizeof(template), "%sXXXXXX", editFile)__builtin___snprintf_chk (template, sizeof(template), 0, __builtin_object_size (template, 2 > 1 ? 1 : 0), "%sXXXXXX", editFile); | |||
| 1288 | #ifndef HAVE_MKSTEMP1 | |||
| 1289 | (void) mktemp(template); | |||
| 1290 | output = fopen(template, "w"); | |||
| 1291 | #else | |||
| 1292 | { | |||
| 1293 | int fd = mkstemp(template); | |||
| 1294 | ||||
| 1295 | output = fdopen(fd, "w"); | |||
| 1296 | } | |||
| 1297 | #endif | |||
| 1298 | if (!output) | |||
| 1299 | fatal("%s: can't open temporary file '%s'\n", ProgramName, | |||
| 1300 | template); | |||
| 1301 | GetEntriesString(&newDB, xdefs); | |||
| 1302 | EditFile(&newDB, input, output); | |||
| 1303 | if (input) | |||
| 1304 | fclose(input); | |||
| 1305 | fclose(output); | |||
| 1306 | snprintf(old, sizeof(old), "%s%s", editFile, backup_suffix)__builtin___snprintf_chk (old, sizeof(old), 0, __builtin_object_size (old, 2 > 1 ? 1 : 0), "%s%s", editFile, backup_suffix); | |||
| 1307 | if (dont_execute) { /* then write to standard out */ | |||
| 1308 | char buf[BUFSIZ1024]; | |||
| 1309 | size_t n; | |||
| 1310 | ||||
| 1311 | output = fopen(template, "r"); | |||
| 1312 | if (output) { | |||
| 1313 | while ((n = fread(buf, 1, sizeof buf, output)) > 0) { | |||
| 1314 | fwrite(buf, 1, n, stdout__stdoutp); | |||
| 1315 | } | |||
| 1316 | fclose(output); | |||
| 1317 | } | |||
| 1318 | unlink(template); | |||
| 1319 | } | |||
| 1320 | else { | |||
| 1321 | rename(editFile, old); | |||
| 1322 | if (rename(template, editFile)) | |||
| 1323 | fatal("%s: can't rename file '%s' to '%s'\n", ProgramName, | |||
| 1324 | template, editFile); | |||
| 1325 | } | |||
| 1326 | } | |||
| 1327 | else { | |||
| 1328 | const char *cpp_addflags = ""; | |||
| 1329 | ||||
| 1330 | if (oper == OPMERGE5 || oper == OPOVERRIDE6) | |||
| 1331 | GetEntriesString(&newDB, xdefs); | |||
| 1332 | ||||
| 1333 | /* Add -P flag only if using cpp, not another preprocessor */ | |||
| 1334 | if (cpp_program) { | |||
| 1335 | const char *cp = strstr(cpp_program, "cpp"); | |||
| 1336 | ||||
| 1337 | if (cp && ((cp[3] == '\0') || cp[3] == ' ')) | |||
| 1338 | cpp_addflags = "-P"; | |||
| 1339 | } | |||
| 1340 | #ifdef PATHETICCPP | |||
| 1341 | if (need_real_defines) { | |||
| 1342 | #ifdef WIN32 | |||
| 1343 | if (!(input = fopen(tmpname2, "w"))) | |||
| 1344 | fatal("%s: can't open file '%s'\n", ProgramName, tmpname2); | |||
| 1345 | fputs(defines.val, input); | |||
| 1346 | fprintf(input, "\n#include \"%s\"\n", filename); | |||
| 1347 | fclose(input); | |||
| 1348 | (void) mktemp(tmpname3); | |||
| 1349 | if (asprintf(&cmd, "%s %s %s %s > %s", cpp_program, cpp_addflags, | |||
| 1350 | includes.val, tmpname2, tmpname3) == -1) | |||
| 1351 | fatal("%s: Out of memory\n", ProgramName); | |||
| 1352 | if (system(cmd) < 0) | |||
| 1353 | fatal("%s: cannot run '%s'\n", ProgramName, cmd); | |||
| 1354 | free(cmd); | |||
| 1355 | if (!(input = fopen(tmpname3, "r"))) | |||
| 1356 | fatal("%s: can't open file '%s'\n", ProgramName, tmpname3); | |||
| 1357 | #else | |||
| 1358 | if (!freopen(tmpname2, "w+", stdin__stdinp)) | |||
| 1359 | fatal("%s: can't open file '%s'\n", ProgramName, tmpname2); | |||
| 1360 | fputs(defines.val, stdin__stdinp); | |||
| 1361 | fprintf(stdin__stdinp, "\n#include \"%s\"\n", filename); | |||
| 1362 | fflush(stdin__stdinp); | |||
| 1363 | fseek(stdin__stdinp, 0, SEEK_SET0); | |||
| 1364 | if (asprintf(&cmd, "%s %s %s", cpp_program, cpp_addflags, | |||
| 1365 | includes.val) == -1) | |||
| 1366 | fatal("%s: Out of memory\n", ProgramName); | |||
| 1367 | if (!(input = popen(cmd, "r"))) | |||
| 1368 | fatal("%s: cannot run '%s'\n", ProgramName, cmd); | |||
| 1369 | free(cmd); | |||
| 1370 | #endif | |||
| 1371 | } | |||
| 1372 | else { | |||
| 1373 | #endif | |||
| 1374 | if (filename) { | |||
| 1375 | if (!freopen(filename, "r", stdin__stdinp)) | |||
| 1376 | fatal("%s: can't open file '%s'\n", ProgramName, filename); | |||
| 1377 | } | |||
| 1378 | if (cpp_program) { | |||
| 1379 | #ifdef WIN32 | |||
| 1380 | (void) mktemp(tmpname3); | |||
| 1381 | if (asprintf(&cmd, "%s %s %s %s %s > %s", cpp_program, | |||
| 1382 | cpp_addflags, includes.val, defines.val, | |||
| 1383 | filename ? filename : "", tmpname3) == -1) | |||
| 1384 | fatal("%s: Out of memory\n", ProgramName); | |||
| 1385 | if (system(cmd) < 0) | |||
| 1386 | fatal("%s: cannot run '%s'\n", ProgramName, cmd); | |||
| 1387 | free(cmd); | |||
| 1388 | if (!(input = fopen(tmpname3, "r"))) | |||
| 1389 | fatal("%s: can't open file '%s'\n", ProgramName, tmpname3); | |||
| 1390 | #else | |||
| 1391 | if (asprintf(&cmd, "%s %s %s %s %s", cpp_program, | |||
| 1392 | cpp_addflags, includes.val, defines.val, | |||
| 1393 | filename ? filename : "") == -1) | |||
| 1394 | fatal("%s: Out of memory\n", ProgramName); | |||
| 1395 | if (!(input = popen(cmd, "r"))) | |||
| 1396 | fatal("%s: cannot run '%s'\n", ProgramName, cmd); | |||
| 1397 | free(cmd); | |||
| 1398 | #endif | |||
| 1399 | } | |||
| 1400 | else { | |||
| 1401 | input = stdin__stdinp; | |||
| 1402 | } | |||
| 1403 | #ifdef PATHETICCPP | |||
| 1404 | } | |||
| 1405 | #endif | |||
| 1406 | ReadFile(&buffer, input); | |||
| 1407 | if (cpp_program) { | |||
| 1408 | #ifdef WIN32 | |||
| 1409 | fclose(input); | |||
| 1410 | #else | |||
| 1411 | pclose(input); | |||
| 1412 | #endif | |||
| 1413 | } | |||
| 1414 | #ifdef PATHETICCPP | |||
| 1415 | if (need_real_defines) { | |||
| 1416 | unlink(tmpname2); | |||
| 1417 | #ifdef WIN32 | |||
| 1418 | if (tmpname3[strlen(tmpname3) - 1] != 'X') | |||
| 1419 | unlink(tmpname3); | |||
| 1420 | #endif | |||
| 1421 | } | |||
| 1422 | #endif | |||
| 1423 | GetEntries(&newDB, &buffer, 0); | |||
| 1424 | if (execute) { | |||
| 1425 | FormatEntries(&buffer, &newDB); | |||
| 1426 | if (dont_execute) { | |||
| 1427 | if (buffer.used > 0) { | |||
| 1428 | fwrite(buffer.buff, 1, buffer.used, stdout__stdoutp); | |||
| 1429 | if (buffer.buff[buffer.used - 1] != '\n') | |||
| 1430 | putchar('\n'); | |||
| 1431 | } | |||
| 1432 | } | |||
| 1433 | else if (buffer.used > 1 || !doScreen) | |||
| 1434 | StoreProperty(dpy, root, res_prop); | |||
| 1435 | else | |||
| 1436 | XDeleteProperty(dpy, root, res_prop); | |||
| 1437 | } | |||
| 1438 | } | |||
| 1439 | if (execute) | |||
| 1440 | FreeEntries(&newDB); | |||
| 1441 | if (doScreen && xdefs) | |||
| 1442 | XFree(xdefs); | |||
| 1443 | } | |||
| 1444 | ||||
| 1445 | static void | |||
| 1446 | ShuffleEntries(Entries *db, Entries *dbs, unsigned int num) | |||
| 1447 | { | |||
| 1448 | unsigned int *hits; | |||
| 1449 | unsigned int i, j, k; | |||
| 1450 | Entries cur, cmp; | |||
| 1451 | char *curtag, *curvalue; | |||
| 1452 | ||||
| 1453 | hits = mallocarray(num, sizeof(int))reallocarray(((void*)0), num, sizeof(int)); | |||
| 1454 | if (hits == NULL((void*)0)) | |||
| 1455 | fatal("%s: Can't allocate memory in %s\n", ProgramName, __func__); | |||
| 1456 | cur = dbs[0]; | |||
| 1457 | for (i = 0; i < cur.used; i++) { | |||
| 1458 | curtag = cur.entry[i].tag; | |||
| 1459 | curvalue = cur.entry[i].value; | |||
| 1460 | for (j = 1; j < num; j++) { | |||
| 1461 | cmp = dbs[j]; | |||
| 1462 | for (k = 0; k < cmp.used; k++) { | |||
| 1463 | if (cmp.entry[k].usable && | |||
| 1464 | !strcmp(curtag, cmp.entry[k].tag) && | |||
| 1465 | !strcmp(curvalue, cmp.entry[k].value)) { | |||
| 1466 | hits[j] = k; | |||
| 1467 | break; | |||
| 1468 | } | |||
| 1469 | } | |||
| 1470 | if (k == cmp.used) | |||
| 1471 | break; | |||
| 1472 | } | |||
| 1473 | if (j == num) { | |||
| 1474 | AddEntry(db, &cur.entry[i]); | |||
| 1475 | hits[0] = i; | |||
| 1476 | for (j = 0; j < num; j++) | |||
| 1477 | dbs[j].entry[hits[j]].usable = False0; | |||
| 1478 | } | |||
| 1479 | } | |||
| 1480 | free(hits); | |||
| 1481 | } | |||
| 1482 | ||||
| 1483 | static void | |||
| 1484 | ReProcess(int scrno, Boolint doScreen) | |||
| 1485 | { | |||
| 1486 | Window root; | |||
| 1487 | Atom res_prop; | |||
| 1488 | ||||
| 1489 | FormatEntries(&buffer, &newDB); | |||
| 1490 | if (doScreen) { | |||
| 1491 | root = RootWindow(dpy, scrno)((&((_XPrivDisplay)(dpy))->screens[scrno])->root); | |||
| 1492 | res_prop = XInternAtom(dpy, SCREEN_RESOURCES"SCREEN_RESOURCES", False0); | |||
| 1493 | } | |||
| 1494 | else { | |||
| 1495 | root = RootWindow(dpy, 0)((&((_XPrivDisplay)(dpy))->screens[0])->root); | |||
| 1496 | res_prop = XA_RESOURCE_MANAGER((Atom) 23); | |||
| 1497 | } | |||
| 1498 | if (dont_execute) { | |||
| 1499 | if (buffer.used > 0) { | |||
| 1500 | fwrite(buffer.buff, 1, buffer.used, stdout__stdoutp); | |||
| 1501 | if (buffer.buff[buffer.used - 1] != '\n') | |||
| 1502 | putchar('\n'); | |||
| 1503 | } | |||
| 1504 | } | |||
| 1505 | else { | |||
| 1506 | if (buffer.used > 1 || !doScreen) | |||
| 1507 | StoreProperty(dpy, root, res_prop); | |||
| 1508 | else | |||
| 1509 | XDeleteProperty(dpy, root, res_prop); | |||
| 1510 | } | |||
| 1511 | FreeEntries(&newDB); | |||
| 1512 | } | |||
| 1513 | ||||
| 1514 | static void | |||
| 1515 | fatal(const char *msg, ...) | |||
| 1516 | { | |||
| 1517 | va_list args; | |||
| 1518 | ||||
| 1519 | if (errno(*__error()) != 0) | |||
| 1520 | perror(ProgramName); | |||
| 1521 | va_start(args, msg)__builtin_va_start(args, msg); | |||
| 1522 | vfprintf(stderr__stderrp, msg, args); | |||
| 1523 | va_end(args)__builtin_va_end(args); | |||
| 1524 | exit(1); | |||
| 1525 | } |