| File: | util/makestrs.c |
| Location: | line 750, column 5 |
| Description: | Potential leak of memory pointed to by 'tagline' |
| 1 | /* | |||
| 2 | ||||
| 3 | Copyright (c) 1991, 1998 The Open Group | |||
| 4 | ||||
| 5 | Permission to use, copy, modify, distribute, and sell this software and its | |||
| 6 | documentation for any purpose is hereby granted without fee, provided that | |||
| 7 | the above copyright notice appear in all copies and that both that | |||
| 8 | copyright notice and this permission notice appear in supporting | |||
| 9 | documentation. | |||
| 10 | ||||
| 11 | The above copyright notice and this permission notice shall be included in | |||
| 12 | all copies or substantial portions of the Software. | |||
| 13 | ||||
| 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
| 17 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
| 18 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
| 19 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
| 20 | ||||
| 21 | Except as contained in this notice, the name of The Open Group shall not be | |||
| 22 | used in advertising or otherwise to promote the sale, use or other dealings | |||
| 23 | in this Software without prior written authorization from The Open Group. | |||
| 24 | ||||
| 25 | */ | |||
| 26 | ||||
| 27 | /* Constructs string definitions */ | |||
| 28 | ||||
| 29 | #include <stdio.h> | |||
| 30 | #include <string.h> | |||
| 31 | #include <stdlib.h> | |||
| 32 | #include <unistd.h> | |||
| 33 | ||||
| 34 | typedef struct _TableEnt { | |||
| 35 | struct _TableEnt* next; | |||
| 36 | char* left; | |||
| 37 | char* right; | |||
| 38 | int offset; | |||
| 39 | } TableEnt; | |||
| 40 | ||||
| 41 | typedef struct _Table { | |||
| 42 | struct _Table* next; | |||
| 43 | TableEnt* tableent; | |||
| 44 | TableEnt* tableentcurrent; | |||
| 45 | TableEnt** tableenttail; | |||
| 46 | char* name; | |||
| 47 | int offset; | |||
| 48 | } Table; | |||
| 49 | ||||
| 50 | typedef struct _File { | |||
| 51 | struct _File* next; | |||
| 52 | FILE* tmpl; | |||
| 53 | char* name; | |||
| 54 | Table* table; | |||
| 55 | Table* tablecurrent; | |||
| 56 | Table** tabletail; | |||
| 57 | } File; | |||
| 58 | ||||
| 59 | static File* file = NULL((void *)0); | |||
| 60 | static File* filecurrent = NULL((void *)0); | |||
| 61 | static File** filetail = &file; | |||
| 62 | static char* conststr; | |||
| 63 | static char* prefixstr = NULL((void *)0); | |||
| 64 | static char* featurestr = NULL((void *)0); | |||
| 65 | static char* ctmplstr = NULL((void *)0); | |||
| 66 | static char* fileprotstr; | |||
| 67 | static char* externrefstr; | |||
| 68 | static char* externdefstr; | |||
| 69 | ||||
| 70 | #ifndef FALSE0 | |||
| 71 | # define FALSE0 0 | |||
| 72 | # define TRUE!(0) !(FALSE0) | |||
| 73 | #endif | |||
| 74 | ||||
| 75 | static int solaris_abi_names = FALSE0; | |||
| 76 | ||||
| 77 | #define X_DEFAULT_ABI0 0 | |||
| 78 | #define X_ARRAYPER_ABI1 1 | |||
| 79 | #define X_INTEL_ABI2 2 | |||
| 80 | #define X_INTEL_ABI_BC3 3 | |||
| 81 | #define X_SPARC_ABI4 4 | |||
| 82 | #define X_FUNCTION_ABI5 5 | |||
| 83 | ||||
| 84 | #define X_MAGIC_STRING"<<<STRING_TABLE_GOES_HERE>>>" "<<<STRING_TABLE_GOES_HERE>>>" | |||
| 85 | ||||
| 86 | /* Wrapper for fopen() | |||
| 87 | * Prepend filename with an includedir which can be specified on the | |||
| 88 | * commandline. Needed to separate source and build directories. | |||
| 89 | */ | |||
| 90 | static char* includedir = NULL((void *)0); | |||
| 91 | static FILE *ifopen(const char *file, const char *mode) | |||
| 92 | { | |||
| 93 | #ifndef HAVE_ASPRINTF1 | |||
| 94 | size_t len; | |||
| 95 | #endif | |||
| 96 | char *buffer; | |||
| 97 | FILE *ret; | |||
| 98 | ||||
| 99 | if (includedir == NULL((void *)0)) | |||
| 100 | return fopen(file, mode); | |||
| 101 | ||||
| 102 | #ifdef HAVE_ASPRINTF1 | |||
| 103 | if (asprintf(&buffer, "%s/%s", includedir, file) == -1) | |||
| 104 | return NULL((void *)0); | |||
| 105 | #else | |||
| 106 | len = strlen(file) + strlen(includedir) + 1; | |||
| 107 | buffer = (char*)malloc(len + 1); | |||
| 108 | if (buffer == NULL((void *)0)) | |||
| 109 | return NULL((void *)0); | |||
| 110 | ||||
| 111 | snprintf(buffer, len + 1, "%s/%s", includedir, file)__builtin___snprintf_chk (buffer, len + 1, 0, __builtin_object_size (buffer, 2 > 1 ? 1 : 0), "%s/%s", includedir, file); | |||
| 112 | #endif | |||
| 113 | ||||
| 114 | ret = fopen(buffer, mode); | |||
| 115 | ||||
| 116 | free(buffer); | |||
| 117 | return ret; | |||
| 118 | } | |||
| 119 | ||||
| 120 | static void WriteHeaderProlog (FILE *f, File *phile) | |||
| 121 | { | |||
| 122 | Table* t; | |||
| 123 | TableEnt* te; | |||
| 124 | ||||
| 125 | (void) fprintf (f, "#ifdef %s\n", featurestr); | |||
| 126 | for (t = phile->table; t; t = t->next) | |||
| 127 | for (te = t->tableent; te; te = te->next) { | |||
| 128 | if (strcmp (te->left, "RAtom") == 0) { | |||
| 129 | (void) fprintf (f, | |||
| 130 | "#ifndef %s%s\n#define %s%s \"%s\"\n#endif\n", | |||
| 131 | prefixstr, te->left, prefixstr, te->left, te->right); | |||
| 132 | } else { | |||
| 133 | (void) fprintf (f, | |||
| 134 | "#define %s%s \"%s\"\n", | |||
| 135 | prefixstr, te->left, te->right); | |||
| 136 | } | |||
| 137 | } | |||
| 138 | (void) fprintf (f, "%s", "#else\n"); | |||
| 139 | } | |||
| 140 | ||||
| 141 | static void IntelABIWriteHeader (FILE *f, File *phile) | |||
| 142 | { | |||
| 143 | Table* t; | |||
| 144 | TableEnt* te; | |||
| 145 | ||||
| 146 | WriteHeaderProlog (f, phile); | |||
| 147 | ||||
| 148 | for (t = phile->table; t; t = t->next) { | |||
| 149 | (void) fprintf (f, "%s %sConst char %s[];\n", | |||
| 150 | externrefstr, conststr ? conststr : fileprotstr, t->name); | |||
| 151 | for (te = t->tableent; te; te = te->next) | |||
| 152 | (void) fprintf (f, | |||
| 153 | "#ifndef %s%s\n#define %s%s ((char*)&%s[%d])\n#endif\n", | |||
| 154 | prefixstr, te->left, prefixstr, te->left, t->name, te->offset); | |||
| 155 | } | |||
| 156 | ||||
| 157 | (void) fprintf (f, "#endif /* %s */\n", featurestr); | |||
| 158 | } | |||
| 159 | ||||
| 160 | static void SPARCABIWriteHeader (FILE *f, File *phile) | |||
| 161 | { | |||
| 162 | Table* t; | |||
| 163 | TableEnt* te; | |||
| 164 | ||||
| 165 | for (t = phile->table; t; t = t->next) | |||
| 166 | for (te = t->tableent; te; te = te->next) | |||
| 167 | (void) fprintf (f, "#define %s%s \"%s\"\n", | |||
| 168 | prefixstr, te->left, te->right); | |||
| 169 | } | |||
| 170 | ||||
| 171 | static void FunctionWriteHeader (FILE *f, File *phile) | |||
| 172 | { | |||
| 173 | Table* t; | |||
| 174 | TableEnt* te; | |||
| 175 | ||||
| 176 | WriteHeaderProlog (f, phile); | |||
| 177 | ||||
| 178 | (void) fprintf (f, "%s %sConst char* %s();\n", | |||
| 179 | externrefstr, conststr ? conststr : fileprotstr, | |||
| 180 | phile->table->name); | |||
| 181 | ||||
| 182 | for (t = phile->table; t; t = t->next) | |||
| 183 | for (te = t->tableent; te; te = te->next) | |||
| 184 | (void) fprintf (f, | |||
| 185 | "#ifndef %s%s\n#define %s%s (%s(%d))\n#endif\n", | |||
| 186 | prefixstr, te->left, prefixstr, te->left, phile->table->name, | |||
| 187 | te->offset); | |||
| 188 | ||||
| 189 | (void) fprintf (f, "#endif /* %s */\n", featurestr); | |||
| 190 | } | |||
| 191 | ||||
| 192 | static void ArrayperWriteHeader (FILE *f, File *phile) | |||
| 193 | { | |||
| 194 | Table* t; | |||
| 195 | TableEnt* te; | |||
| 196 | ||||
| 197 | WriteHeaderProlog (f, phile); | |||
| 198 | ||||
| 199 | for (t = phile->table; t; t = t->next) | |||
| 200 | for (te = t->tableent; te; te = te->next) | |||
| 201 | (void) fprintf (f, | |||
| 202 | "#ifndef %s%s\n%s %sConst char %s%s[];\n#endif\n", | |||
| 203 | prefixstr, te->left, | |||
| 204 | externrefstr, conststr ? conststr : fileprotstr, | |||
| 205 | prefixstr, te->left); | |||
| 206 | ||||
| 207 | (void) fprintf (f, "#endif /* %s */\n", featurestr); | |||
| 208 | } | |||
| 209 | ||||
| 210 | static void DefaultWriteHeader (FILE *f, File *phile) | |||
| 211 | { | |||
| 212 | Table* t; | |||
| 213 | TableEnt* te; | |||
| 214 | ||||
| 215 | WriteHeaderProlog (f, phile); | |||
| 216 | ||||
| 217 | (void) fprintf (f, "%s %sConst char %s[];\n", | |||
| 218 | externrefstr, conststr ? conststr : fileprotstr, | |||
| 219 | phile->table->name); | |||
| 220 | ||||
| 221 | for (t = phile->table; t; t = t->next) | |||
| 222 | for (te = t->tableent; te; te = te->next) | |||
| 223 | (void) fprintf (f, | |||
| 224 | "#ifndef %s%s\n#define %s%s ((char*)&%s[%d])\n#endif\n", | |||
| 225 | prefixstr, te->left, prefixstr, te->left, phile->table->name, | |||
| 226 | te->offset); | |||
| 227 | ||||
| 228 | (void) fprintf (f, "#endif /* %s */\n", featurestr); | |||
| 229 | } | |||
| 230 | ||||
| 231 | static void CopyTmplProlog (FILE *tmpl, FILE *f) | |||
| 232 | { | |||
| 233 | char buf[1024]; | |||
| 234 | static const char* magic_string = X_MAGIC_STRING"<<<STRING_TABLE_GOES_HERE>>>"; | |||
| 235 | int magic_string_len = strlen (magic_string); | |||
| 236 | ||||
| 237 | while (fgets (buf, sizeof buf, tmpl)) { | |||
| 238 | if (strncmp (buf, magic_string, magic_string_len) == 0) { | |||
| 239 | return; | |||
| 240 | } | |||
| 241 | (void) fputs (buf, f); | |||
| 242 | } | |||
| 243 | } | |||
| 244 | ||||
| 245 | static void CopyTmplEpilog (FILE *tmpl, FILE *f) | |||
| 246 | { | |||
| 247 | char buf[1024]; | |||
| 248 | ||||
| 249 | while (fgets (buf, sizeof buf, tmpl)) | |||
| 250 | (void) fputs (buf, f); | |||
| 251 | } | |||
| 252 | ||||
| 253 | static const char* abistring[] = { | |||
| 254 | "Default", "Array per string", "Intel", "Intel BC", "SPARC", "Function" }; | |||
| 255 | ||||
| 256 | static void WriteHeader (char *tagline, File *phile, int abi) | |||
| 257 | { | |||
| 258 | FILE* f; | |||
| 259 | char* tmp; | |||
| 260 | static void (*headerproc[])(FILE *f, File *phile) = { | |||
| 261 | DefaultWriteHeader, ArrayperWriteHeader, | |||
| 262 | IntelABIWriteHeader, IntelABIWriteHeader, | |||
| 263 | SPARCABIWriteHeader, FunctionWriteHeader }; | |||
| 264 | ||||
| 265 | if ((f = fopen (phile->name, "w+")) == NULL((void *)0)) exit (1); | |||
| 266 | ||||
| 267 | if (phile->tmpl) CopyTmplProlog (phile->tmpl, f); | |||
| 268 | ||||
| 269 | (void) fprintf (f, | |||
| 270 | "%s\n%s\n/* %s ABI version -- Do not edit */\n", | |||
| 271 | "/* $Xorg: makestrs.c,v 1.6 2001/02/09 02:03:17 xorgcvs Exp $ */", | |||
| 272 | "/* This file is automatically generated. */", | |||
| 273 | abistring[abi]); | |||
| 274 | ||||
| 275 | if (tagline) (void) fprintf (f, "/* %s */\n\n", tagline); | |||
| 276 | ||||
| 277 | /* do the right thing for Motif, i.e. avoid _XmXmStrDefs_h_ */ | |||
| 278 | if (strcmp (prefixstr, "Xm") == 0) { | |||
| 279 | #ifdef HAVE_ASPRINTF1 | |||
| 280 | if (asprintf (&fileprotstr, "_%s_", phile->name) == -1) | |||
| 281 | exit (1); | |||
| 282 | #else | |||
| 283 | if ((fileprotstr = malloc (strlen (phile->name) + 3)) == NULL((void *)0)) | |||
| 284 | exit (1); | |||
| 285 | (void) sprintf (fileprotstr, "_%s_", phile->name)__builtin___sprintf_chk (fileprotstr, 0, __builtin_object_size (fileprotstr, 2 > 1 ? 1 : 0), "_%s_", phile->name); | |||
| 286 | #endif | |||
| 287 | } else { | |||
| 288 | #ifdef HAVE_ASPRINTF1 | |||
| 289 | if (asprintf (&fileprotstr, "_%s%s_", prefixstr, phile->name) == -1) | |||
| 290 | exit (1); | |||
| 291 | #else | |||
| 292 | if ((fileprotstr = malloc (strlen (phile->name) + strlen (prefixstr) + 3)) == NULL((void *)0)) | |||
| 293 | exit (1); | |||
| 294 | (void) sprintf (fileprotstr, "_%s%s_", prefixstr, phile->name)__builtin___sprintf_chk (fileprotstr, 0, __builtin_object_size (fileprotstr, 2 > 1 ? 1 : 0), "_%s%s_", prefixstr, phile-> name); | |||
| 295 | #endif | |||
| 296 | } | |||
| 297 | ||||
| 298 | for (tmp = fileprotstr; *tmp; tmp++) if (*tmp == '.') *tmp = '_'; | |||
| 299 | ||||
| 300 | (*headerproc[abi])(f, phile); | |||
| 301 | ||||
| 302 | if (phile->tmpl) CopyTmplEpilog (phile->tmpl, f); | |||
| 303 | ||||
| 304 | (void) free (fileprotstr); | |||
| 305 | (void) fclose (phile->tmpl); | |||
| 306 | (void) fclose (f); | |||
| 307 | } | |||
| 308 | ||||
| 309 | static void WriteSourceLine (TableEnt *te, int abi, int fudge) | |||
| 310 | { | |||
| 311 | char* c; | |||
| 312 | ||||
| 313 | for (c = te->right; *c; c++) (void) printf ("'%c',", *c); | |||
| 314 | (void) printf ("%c", '0'); | |||
| 315 | if (te->next || fudge) (void) printf ("%c", ','); | |||
| 316 | (void) printf ("%s", "\n"); | |||
| 317 | } | |||
| 318 | ||||
| 319 | static const char* const_string = "%s %sConst char %s[] = {\n"; | |||
| 320 | ||||
| 321 | static void IntelABIWriteSource (int abi) | |||
| 322 | { | |||
| 323 | File* phile; | |||
| 324 | ||||
| 325 | for (phile = file; phile; phile = phile->next) { | |||
| 326 | Table* t; | |||
| 327 | TableEnt* te; | |||
| 328 | ||||
| 329 | for (t = phile->table; t; t = t->next) { | |||
| 330 | (void) printf (const_string, externdefstr, | |||
| 331 | conststr ? conststr : "", t->name); | |||
| 332 | for (te = t->tableent; te; te = te->next) | |||
| 333 | WriteSourceLine (te, abi, 0); | |||
| 334 | (void) printf ("%s\n\n", "};"); | |||
| 335 | } | |||
| 336 | } | |||
| 337 | } | |||
| 338 | ||||
| 339 | static void IntelABIBCWriteSource (int abi) | |||
| 340 | { | |||
| 341 | File* phile; | |||
| 342 | ||||
| 343 | for (phile = file; phile; phile = phile->next) { | |||
| 344 | Table* t; | |||
| 345 | TableEnt* te; | |||
| 346 | ||||
| 347 | (void) printf (const_string, externdefstr, | |||
| 348 | conststr ? conststr : "", phile->table->name); | |||
| 349 | ||||
| 350 | for (t = phile->table; t; t = t->next) | |||
| 351 | for (te = t->tableent; te; te = te->next) | |||
| 352 | WriteSourceLine (te, abi, t->next ? 1 : 0); | |||
| 353 | (void) printf ("%s\n\n", "};"); | |||
| 354 | ||||
| 355 | if (phile->table->next) { | |||
| 356 | (void) printf (const_string, externdefstr, | |||
| 357 | conststr ? conststr : "", phile->table->next->name); | |||
| 358 | for (t = phile->table->next; t; t = t->next) | |||
| 359 | for (te = t->tableent; te; te = te->next) | |||
| 360 | WriteSourceLine (te, abi, 0); | |||
| 361 | (void) printf ("%s\n\n", "};"); | |||
| 362 | } | |||
| 363 | } | |||
| 364 | } | |||
| 365 | ||||
| 366 | static void FunctionWriteSource (int abi) | |||
| 367 | { | |||
| 368 | File* phile; | |||
| 369 | ||||
| 370 | for (phile = file; phile; phile = phile->next) { | |||
| 371 | Table* t; | |||
| 372 | TableEnt* te; | |||
| 373 | ||||
| 374 | (void) printf ("static %sConst char _%s[] = {\n", | |||
| 375 | conststr ? conststr : "", phile->table->name); | |||
| 376 | ||||
| 377 | for (t = phile->table; t; t = t->next) | |||
| 378 | for (te = t->tableent; te; te = te->next) | |||
| 379 | WriteSourceLine (te, abi, t->next ? 1 : 0); | |||
| 380 | (void) printf ("%s\n\n", "};"); | |||
| 381 | ||||
| 382 | (void) printf ("%sConst char* %s(index)\n int index;\n{\n return &_%s[index];\n}\n\n", | |||
| 383 | conststr ? conststr : "", | |||
| 384 | phile->table->name, phile->table->name); | |||
| 385 | } | |||
| 386 | } | |||
| 387 | ||||
| 388 | static void ArrayperWriteSource (int abi) | |||
| 389 | { | |||
| 390 | File* phile; | |||
| 391 | static int done_atom; | |||
| 392 | ||||
| 393 | for (phile = file; phile; phile = phile->next) { | |||
| 394 | Table* t; | |||
| 395 | TableEnt* te; | |||
| 396 | ||||
| 397 | for (t = phile->table; t; t = t->next) | |||
| 398 | for (te = t->tableent; te; te = te->next) { | |||
| 399 | if (strcmp (te->left, "RAtom") == 0) { | |||
| 400 | if (done_atom) return; | |||
| 401 | done_atom = 1; | |||
| 402 | } | |||
| 403 | (void) printf ("%s %sConst char %s%s[] = \"%s\";\n", | |||
| 404 | externdefstr, conststr ? conststr : "", | |||
| 405 | prefixstr, | |||
| 406 | te->left, te->right); | |||
| 407 | } | |||
| 408 | } | |||
| 409 | } | |||
| 410 | ||||
| 411 | static void DefaultWriteSource (int abi) | |||
| 412 | { | |||
| 413 | File* phile; | |||
| 414 | ||||
| 415 | for (phile = file; phile; phile = phile->next) { | |||
| 416 | Table* t; | |||
| 417 | TableEnt* te; | |||
| 418 | ||||
| 419 | (void) printf (const_string, externdefstr, conststr ? conststr : "", | |||
| 420 | phile->table->name); | |||
| 421 | ||||
| 422 | for (t = phile->table; t; t = t->next) | |||
| 423 | for (te = t->tableent; te; te = te->next) | |||
| 424 | WriteSourceLine (te, abi, t->next ? 1 : 0); | |||
| 425 | (void) printf ("%s\n\n", "};"); | |||
| 426 | } | |||
| 427 | } | |||
| 428 | ||||
| 429 | static void WriteSource(char *tagline, int abi) | |||
| 430 | { | |||
| 431 | static void (*sourceproc[])(int) = { | |||
| 432 | DefaultWriteSource, ArrayperWriteSource, | |||
| 433 | IntelABIWriteSource, IntelABIBCWriteSource, | |||
| 434 | DefaultWriteSource, FunctionWriteSource }; | |||
| 435 | ||||
| 436 | FILE* tmpl; | |||
| 437 | ||||
| 438 | if (ctmplstr) { | |||
| 439 | tmpl = ifopen (ctmplstr, "r"); | |||
| 440 | ||||
| 441 | if (tmpl) CopyTmplProlog (tmpl, stdout__stdoutp); | |||
| 442 | else { | |||
| 443 | (void) fprintf (stderr__stderrp, "Expected template %s, not found\n", | |||
| 444 | ctmplstr); | |||
| 445 | exit (1); | |||
| 446 | } | |||
| 447 | } else | |||
| 448 | tmpl = NULL((void *)0); | |||
| 449 | ||||
| 450 | ||||
| 451 | (void) printf ("%s\n%s\n/* %s ABI version -- Do not edit */\n", | |||
| 452 | "/* $Xorg: makestrs.c,v 1.6 2001/02/09 02:03:17 xorgcvs Exp $ */", | |||
| 453 | "/* This file is automatically generated. */", | |||
| 454 | abistring[abi]); | |||
| 455 | ||||
| 456 | if (tagline) (void) printf ("/* %s */\n\n", tagline); | |||
| 457 | ||||
| 458 | (*sourceproc[abi])(abi); | |||
| 459 | ||||
| 460 | if (tmpl) CopyTmplEpilog (tmpl, stdout__stdoutp); | |||
| 461 | } | |||
| 462 | ||||
| 463 | static void DoLine(char *buf) | |||
| 464 | { | |||
| 465 | #define X_NO_TOKEN0 0 | |||
| 466 | #define X_FILE_TOKEN1 1 | |||
| 467 | #define X_TABLE_TOKEN2 2 | |||
| 468 | #define X_PREFIX_TOKEN3 3 | |||
| 469 | #define X_FEATURE_TOKEN4 4 | |||
| 470 | #define X_EXTERNREF_TOKEN5 5 | |||
| 471 | #define X_EXTERNDEF_TOKEN6 6 | |||
| 472 | #define X_CTMPL_TOKEN7 7 | |||
| 473 | #define X_HTMPL_TOKEN8 8 | |||
| 474 | #define X_CONST_TOKEN9 9 | |||
| 475 | ||||
| 476 | int token; | |||
| 477 | char lbuf[1024]; | |||
| 478 | static const char* file_str = "#file"; | |||
| 479 | static const char* table_str = "#table"; | |||
| 480 | static const char* prefix_str = "#prefix"; | |||
| 481 | static const char* feature_str = "#feature"; | |||
| 482 | static const char* externref_str = "#externref"; | |||
| 483 | static const char* externdef_str = "#externdef"; | |||
| 484 | static const char* ctmpl_str = "#ctmpl"; | |||
| 485 | static const char* htmpl_str = "#htmpl"; | |||
| 486 | static const char* const_str = "#const"; | |||
| 487 | ||||
| 488 | if (strncmp (buf, file_str, strlen (file_str)) == 0) | |||
| 489 | token = X_FILE_TOKEN1; | |||
| 490 | else if (strncmp (buf, table_str, strlen (table_str)) == 0) | |||
| 491 | token = X_TABLE_TOKEN2; | |||
| 492 | else if (strncmp (buf, prefix_str, strlen (prefix_str)) == 0) | |||
| 493 | token = X_PREFIX_TOKEN3; | |||
| 494 | else if (strncmp (buf, feature_str, strlen (feature_str)) == 0) | |||
| 495 | token = X_FEATURE_TOKEN4; | |||
| 496 | else if (strncmp (buf, externref_str, strlen (externref_str)) == 0) | |||
| 497 | token = X_EXTERNREF_TOKEN5; | |||
| 498 | else if (strncmp (buf, externdef_str, strlen (externdef_str)) == 0) | |||
| 499 | token = X_EXTERNDEF_TOKEN6; | |||
| 500 | else if (strncmp (buf, ctmpl_str, strlen (ctmpl_str)) == 0) | |||
| 501 | token = X_CTMPL_TOKEN7; | |||
| 502 | else if (strncmp (buf, htmpl_str, strlen (htmpl_str)) == 0) | |||
| 503 | token = X_HTMPL_TOKEN8; | |||
| 504 | else if (strncmp (buf, const_str, strlen (const_str)) == 0) | |||
| 505 | token = X_CONST_TOKEN9; | |||
| 506 | else | |||
| 507 | token = X_NO_TOKEN0; | |||
| 508 | ||||
| 509 | switch (token) { | |||
| 510 | case X_FILE_TOKEN1: | |||
| 511 | { | |||
| 512 | File* phile; | |||
| 513 | ||||
| 514 | if ((phile = (File*) malloc (sizeof(File))) == NULL((void *)0)) | |||
| 515 | exit(1); | |||
| 516 | if ((phile->name = strdup (buf + strlen (file_str) + 1)) == NULL((void *)0)) | |||
| 517 | exit(1); | |||
| 518 | phile->table = NULL((void *)0); | |||
| 519 | phile->tablecurrent = NULL((void *)0); | |||
| 520 | phile->tabletail = &phile->table; | |||
| 521 | phile->next = NULL((void *)0); | |||
| 522 | phile->tmpl = NULL((void *)0); | |||
| 523 | ||||
| 524 | *filetail = phile; | |||
| 525 | filetail = &phile->next; | |||
| 526 | filecurrent = phile; | |||
| 527 | } | |||
| 528 | break; | |||
| 529 | case X_TABLE_TOKEN2: | |||
| 530 | { | |||
| 531 | Table* table; | |||
| 532 | if ((table = (Table*) malloc (sizeof(Table))) == NULL((void *)0)) | |||
| 533 | exit(1); | |||
| 534 | if ((table->name = strdup (buf + strlen (table_str) + 1)) == NULL((void *)0)) | |||
| 535 | exit(1); | |||
| 536 | if (solaris_abi_names) { | |||
| 537 | if (strcmp(table->name, "XtStringsR6") == 0) { | |||
| 538 | strcpy(table->name, "XtR6Strings")__builtin___strcpy_chk (table->name, "XtR6Strings", __builtin_object_size (table->name, 2 > 1 ? 1 : 0)); | |||
| 539 | } else if (strcmp(table->name, "XtShellStringsR6") == 0) { | |||
| 540 | strcpy(table->name, "XtR6ShellStrings")__builtin___strcpy_chk (table->name, "XtR6ShellStrings", __builtin_object_size (table->name, 2 > 1 ? 1 : 0)); | |||
| 541 | } | |||
| 542 | } | |||
| 543 | table->tableent = NULL((void *)0); | |||
| 544 | table->tableentcurrent = NULL((void *)0); | |||
| 545 | table->tableenttail = &table->tableent; | |||
| 546 | table->next = NULL((void *)0); | |||
| 547 | table->offset = 0; | |||
| 548 | ||||
| 549 | *filecurrent->tabletail = table; | |||
| 550 | filecurrent->tabletail = &table->next; | |||
| 551 | filecurrent->tablecurrent = table; | |||
| 552 | } | |||
| 553 | break; | |||
| 554 | case X_PREFIX_TOKEN3: | |||
| 555 | if ((prefixstr = strdup (buf + strlen (prefix_str) + 1)) == NULL((void *)0)) | |||
| 556 | exit(1); | |||
| 557 | break; | |||
| 558 | case X_FEATURE_TOKEN4: | |||
| 559 | if ((featurestr = strdup (buf + strlen (feature_str) + 1)) == NULL((void *)0)) | |||
| 560 | exit(1); | |||
| 561 | break; | |||
| 562 | case X_EXTERNREF_TOKEN5: | |||
| 563 | if ((externrefstr = strdup (buf + strlen (externref_str) + 1)) == NULL((void *)0)) | |||
| 564 | exit(1); | |||
| 565 | break; | |||
| 566 | case X_EXTERNDEF_TOKEN6: | |||
| 567 | if ((externdefstr = strdup (buf + strlen (externdef_str) + 1)) == NULL((void *)0)) | |||
| 568 | exit(1); | |||
| 569 | break; | |||
| 570 | case X_CTMPL_TOKEN7: | |||
| 571 | if ((ctmplstr = strdup (buf + strlen (ctmpl_str) + 1)) == NULL((void *)0)) | |||
| 572 | exit(1); | |||
| 573 | break; | |||
| 574 | case X_HTMPL_TOKEN8: | |||
| 575 | if ((filecurrent->tmpl = ifopen (buf + strlen (htmpl_str) + 1, "r")) == NULL((void *)0)) { | |||
| 576 | (void) fprintf (stderr__stderrp, | |||
| 577 | "Expected template %s, not found\n", htmpl_str); | |||
| 578 | exit (1); | |||
| 579 | } | |||
| 580 | break; | |||
| 581 | case X_CONST_TOKEN9: | |||
| 582 | if ((conststr = strdup (buf + strlen (const_str) + 1)) == NULL((void *)0)) | |||
| 583 | exit(1); | |||
| 584 | break; | |||
| 585 | default: | |||
| 586 | { | |||
| 587 | char* right; | |||
| 588 | TableEnt* tableent; | |||
| 589 | int llen; | |||
| 590 | int rlen; | |||
| 591 | int len; | |||
| 592 | ||||
| 593 | if ((right = strchr(buf, ' '))) | |||
| 594 | *right++ = 0; | |||
| 595 | else | |||
| 596 | right = buf + 1; | |||
| 597 | if (buf[0] == 'H') { | |||
| 598 | snprintf (lbuf, sizeof(lbuf), "%s%s", prefixstr, right)__builtin___snprintf_chk (lbuf, sizeof(lbuf), 0, __builtin_object_size (lbuf, 2 > 1 ? 1 : 0), "%s%s", prefixstr, right); | |||
| 599 | right = lbuf; | |||
| 600 | } | |||
| 601 | ||||
| 602 | llen = len = strlen(buf) + 1; | |||
| 603 | rlen = strlen(right) + 1; | |||
| 604 | if (right != buf + 1) len += rlen; | |||
| 605 | if ((tableent = (TableEnt*)malloc(sizeof(TableEnt) + len)) == NULL((void *)0)) | |||
| 606 | exit(1); | |||
| 607 | tableent->left = (char *)(tableent + 1); | |||
| 608 | strcpy(tableent->left, buf)__builtin___strcpy_chk (tableent->left, buf, __builtin_object_size (tableent->left, 2 > 1 ? 1 : 0)); | |||
| 609 | if (llen != len) { | |||
| 610 | tableent->right = tableent->left + llen; | |||
| 611 | strcpy(tableent->right, right)__builtin___strcpy_chk (tableent->right, right, __builtin_object_size (tableent->right, 2 > 1 ? 1 : 0)); | |||
| 612 | } else { | |||
| 613 | tableent->right = tableent->left + 1; | |||
| 614 | } | |||
| 615 | tableent->next = NULL((void *)0); | |||
| 616 | ||||
| 617 | *filecurrent->tablecurrent->tableenttail = tableent; | |||
| 618 | filecurrent->tablecurrent->tableenttail = &tableent->next; | |||
| 619 | filecurrent->tablecurrent->tableentcurrent = tableent; | |||
| 620 | } | |||
| 621 | break; | |||
| 622 | } | |||
| 623 | } | |||
| 624 | ||||
| 625 | static void IntelABIIndexEntries (File *file) | |||
| 626 | { | |||
| 627 | Table* t; | |||
| 628 | TableEnt* te; | |||
| 629 | ||||
| 630 | for (t = file->table; t; t = t->next) | |||
| 631 | for (te = t->tableent; te; te = te->next) { | |||
| 632 | te->offset = t->offset; | |||
| 633 | t->offset += strlen (te->right); | |||
| 634 | t->offset++; | |||
| 635 | } | |||
| 636 | } | |||
| 637 | ||||
| 638 | static void DefaultIndexEntries (File *file) | |||
| 639 | { | |||
| 640 | Table* t; | |||
| 641 | TableEnt* te; | |||
| 642 | int offset = 0; | |||
| 643 | ||||
| 644 | for (t = file->table; t; t = t->next) | |||
| 645 | for (te = t->tableent; te; te = te->next) { | |||
| 646 | te->offset = offset; | |||
| 647 | offset += strlen (te->right); | |||
| 648 | offset++; | |||
| 649 | } | |||
| 650 | } | |||
| 651 | ||||
| 652 | static void IndexEntries (File *file, int abi) | |||
| 653 | { | |||
| 654 | switch (abi) { | |||
| 655 | case X_SPARC_ABI4: | |||
| 656 | break; | |||
| 657 | case X_INTEL_ABI2: | |||
| 658 | case X_INTEL_ABI_BC3: | |||
| 659 | IntelABIIndexEntries (file); | |||
| 660 | break; | |||
| 661 | default: | |||
| 662 | DefaultIndexEntries (file); | |||
| 663 | break; | |||
| 664 | } | |||
| 665 | } | |||
| 666 | ||||
| 667 | static char* DoComment (char *line) | |||
| 668 | { | |||
| 669 | char* tag; | |||
| 670 | char* eol; | |||
| 671 | char* ret; | |||
| 672 | int len; | |||
| 673 | ||||
| 674 | /* assume that the first line with two '$' in it is the RCS tag line */ | |||
| 675 | if ((tag = strchr (line, '$')) == NULL((void *)0)) return NULL((void *)0); | |||
| 676 | if ((eol = strchr (tag + 1, '$')) == NULL((void *)0)) return NULL((void *)0); | |||
| 677 | len = eol - tag; | |||
| 678 | if ((ret = malloc (len)) == NULL((void *)0)) | |||
| 679 | exit (1); | |||
| 680 | (void) strncpy (ret, tag + 1, len - 1)__builtin___strncpy_chk (ret, tag + 1, len - 1, __builtin_object_size (ret, 2 > 1 ? 1 : 0)); | |||
| 681 | ret[len - 2] = 0; | |||
| 682 | return ret; | |||
| 683 | } | |||
| 684 | ||||
| 685 | int main(int argc, char *argv[]) | |||
| 686 | { | |||
| 687 | int len, i; | |||
| 688 | char* tagline = NULL((void *)0); | |||
| 689 | File* phile; | |||
| 690 | FILE *f; | |||
| 691 | char buf[1024]; | |||
| 692 | int abi = | |||
| 693 | #ifndef ARRAYPERSTR | |||
| 694 | X_DEFAULT_ABI0; | |||
| 695 | #else | |||
| 696 | X_ARRAYPER_ABI1; | |||
| 697 | #endif | |||
| 698 | ||||
| 699 | f = stdin__stdinp; | |||
| 700 | if (argc > 1) { | |||
| ||||
| 701 | for (i = 1; i < argc; i++) { | |||
| 702 | if (strcmp (argv[i], "-f") == 0) { | |||
| 703 | if (++i < argc) | |||
| 704 | f = fopen (argv[i], "r"); | |||
| 705 | else | |||
| 706 | return 1; | |||
| 707 | } | |||
| 708 | if (strcmp (argv[i], "-i") == 0) { | |||
| 709 | if (++i < argc) | |||
| 710 | includedir = argv[i]; | |||
| 711 | else | |||
| 712 | return 1; | |||
| 713 | } | |||
| 714 | if (strcmp (argv[i], "-sparcabi") == 0) | |||
| 715 | abi = X_SPARC_ABI4; | |||
| 716 | if (strcmp (argv[i], "-intelabi") == 0) | |||
| 717 | abi = X_INTEL_ABI2; | |||
| 718 | if (strcmp (argv[i], "-functionabi") == 0) | |||
| 719 | abi = X_FUNCTION_ABI5; | |||
| 720 | if (strcmp (argv[i], "-earlyR6bc") == 0 && abi == X_INTEL_ABI2) | |||
| 721 | abi = X_INTEL_ABI_BC3; | |||
| 722 | if (strcmp (argv[i], "-arrayperabi") == 0) | |||
| 723 | abi = X_ARRAYPER_ABI1; | |||
| 724 | #ifdef ARRAYPERSTR | |||
| 725 | if (strcmp (argv[i], "-defaultabi") == 0) | |||
| 726 | abi = X_DEFAULT_ABI0; | |||
| 727 | #endif | |||
| 728 | if (strcmp (argv[i], "-solarisabinames") == 0) | |||
| 729 | solaris_abi_names = TRUE!(0); | |||
| 730 | } | |||
| 731 | } | |||
| 732 | ||||
| 733 | if (f == NULL((void *)0)) return 1; | |||
| 734 | while (fgets(buf, sizeof buf, f)) { | |||
| 735 | if (!buf[0] || buf[0] == '\n') | |||
| 736 | continue; | |||
| 737 | if (buf[0] == '!') { | |||
| 738 | if (tagline) continue; | |||
| 739 | tagline = DoComment (buf); | |||
| 740 | continue; | |||
| 741 | } | |||
| 742 | if (buf[(len = strlen (buf) - 1)] == '\n') buf[len] = '\0'; | |||
| 743 | DoLine(buf); | |||
| 744 | } | |||
| 745 | for (phile = file; phile; phile = phile->next) { | |||
| 746 | if (abi != X_ARRAYPER_ABI1) IndexEntries (phile, abi); | |||
| 747 | WriteHeader (tagline, phile, abi); | |||
| 748 | } | |||
| 749 | WriteSource(tagline, abi); | |||
| 750 | return 0; | |||
| ||||
| 751 | } | |||
| 752 |