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 |