File: | main.c |
Location: | line 507, column 3 |
Description: | Potential memory leak |
1 | /* | |||
2 | ||||
3 | Copyright (c) 1993, 1994, 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 | THE 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 | #include "def.h" | |||
28 | #ifdef hpux | |||
29 | #define sigvec sigvector | |||
30 | #endif /* hpux */ | |||
31 | ||||
32 | #ifdef X_POSIX_C_SOURCE | |||
33 | #define _POSIX_C_SOURCE X_POSIX_C_SOURCE | |||
34 | #include <signal.h> | |||
35 | #undef _POSIX_C_SOURCE | |||
36 | #else | |||
37 | #if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE) | |||
38 | #include <signal.h> | |||
39 | #else | |||
40 | #define _POSIX_SOURCE | |||
41 | #include <signal.h> | |||
42 | #undef _POSIX_SOURCE | |||
43 | #endif | |||
44 | #endif | |||
45 | ||||
46 | #include <stdarg.h> | |||
47 | ||||
48 | #ifdef __sun | |||
49 | # include <sys/utsname.h> | |||
50 | #endif | |||
51 | ||||
52 | #ifdef DEBUG | |||
53 | int _debugmask; | |||
54 | #endif | |||
55 | ||||
56 | /* #define DEBUG_DUMP */ | |||
57 | #ifdef DEBUG_DUMP | |||
58 | #define DBG_PRINT(file, fmt, args) fprintf(file, fmt, args) | |||
59 | #else | |||
60 | #define DBG_PRINT(file, fmt, args) /* empty */ | |||
61 | #endif | |||
62 | ||||
63 | #define DASH_INC_PRE"#include \"" "#include \"" | |||
64 | #define DASH_INC_POST"\"" "\"" | |||
65 | ||||
66 | const char *ProgramName; | |||
67 | ||||
68 | const char * const directives[] = { | |||
69 | "if", | |||
70 | "ifdef", | |||
71 | "ifndef", | |||
72 | "else", | |||
73 | "endif", | |||
74 | "define", | |||
75 | "undef", | |||
76 | "include", | |||
77 | "line", | |||
78 | "pragma", | |||
79 | "error", | |||
80 | "ident", | |||
81 | "sccs", | |||
82 | "elif", | |||
83 | "eject", | |||
84 | "warning", | |||
85 | "include_next", | |||
86 | NULL((void *)0) | |||
87 | }; | |||
88 | ||||
89 | #include "imakemdep.h" | |||
90 | ||||
91 | struct inclist inclist[ MAXFILES2048 ], | |||
92 | *inclistp = inclist, | |||
93 | *inclistnext = inclist, | |||
94 | maininclist; | |||
95 | ||||
96 | static char *filelist[ MAXFILES2048 ]; | |||
97 | const char *includedirs[ MAXDIRS64 + 1 ], | |||
98 | **includedirsnext = includedirs; | |||
99 | char *notdotdot[ MAXDIRS64 ]; | |||
100 | static int cmdinc_count = 0; | |||
101 | static char *cmdinc_list[ 2 * MAXINCFILES128 ]; | |||
102 | const char *objprefix = ""; | |||
103 | const char *objsuffix = OBJSUFFIX".o"; | |||
104 | static const char *startat = "# DO NOT DELETE"; | |||
105 | int width = 78; | |||
106 | static boolean append = FALSE0; | |||
107 | boolean printed = FALSE0; | |||
108 | boolean verbose = FALSE0; | |||
109 | boolean show_where_not = FALSE0; | |||
110 | /* Warn on multiple includes of same file */ | |||
111 | boolean warn_multiple = FALSE0; | |||
112 | ||||
113 | static void setfile_cmdinc(struct filepointer *filep, long count, char **list); | |||
114 | static void redirect(const char *line, const char *makefile); | |||
115 | ||||
116 | static void _X_NORETURN__attribute((noreturn)) | |||
117 | catch (int sig) | |||
118 | { | |||
119 | fflush (stdout__stdoutp); | |||
120 | fatalerr ("got signal %d\n", sig); | |||
121 | } | |||
122 | ||||
123 | #if defined(USG) || (defined(i386) && defined(SYSV)) || defined(WIN32) || defined(Lynx_22) || defined(__CYGWIN__) | |||
124 | #define USGISH | |||
125 | #endif | |||
126 | ||||
127 | #ifndef USGISH | |||
128 | #ifdef X_NOT_POSIX | |||
129 | #define sigaction sigvec | |||
130 | #define sa_handler__sigaction_u.__sa_handler sv_handler | |||
131 | #define sa_mask sv_mask | |||
132 | #define sa_flags sv_flags | |||
133 | #endif | |||
134 | static struct sigaction sig_act; | |||
135 | #endif /* USGISH */ | |||
136 | ||||
137 | int | |||
138 | main(int argc, char *argv[]) | |||
139 | { | |||
140 | char **fp = filelist; | |||
141 | const char **incp = includedirs; | |||
142 | char *p; | |||
143 | struct inclist *ip; | |||
144 | char *makefile = NULL((void *)0); | |||
145 | struct filepointer *filecontent; | |||
146 | const struct symtab *psymp = predefs; | |||
147 | const char *endmarker = NULL((void *)0); | |||
148 | char *defincdir = NULL((void *)0); | |||
149 | char **undeflist = NULL((void *)0); | |||
150 | int numundefs = 0, i; | |||
151 | ||||
152 | ProgramName = argv[0]; | |||
153 | ||||
154 | while (psymp->s_name) | |||
| ||||
155 | { | |||
156 | define2(psymp->s_name, psymp->s_value, &maininclist); | |||
157 | psymp++; | |||
158 | } | |||
159 | #ifdef __sun | |||
160 | /* Solaris predefined values that are computed, not hardcoded */ | |||
161 | { | |||
162 | struct utsname name; | |||
163 | ||||
164 | if (uname(&name) >= 0) { | |||
165 | char osrevdef[SYS_NMLN + SYS_NMLN + 5]; | |||
166 | snprintf(osrevdef, sizeof(osrevdef), "__%s_%s",__builtin___snprintf_chk (osrevdef, sizeof(osrevdef), 0, __builtin_object_size (osrevdef, 2 > 1 ? 1 : 0), "__%s_%s", name.sysname, name. release) | |||
167 | name.sysname, name.release)__builtin___snprintf_chk (osrevdef, sizeof(osrevdef), 0, __builtin_object_size (osrevdef, 2 > 1 ? 1 : 0), "__%s_%s", name.sysname, name. release); | |||
168 | ||||
169 | for (p = osrevdef; *p != '\0'; p++) { | |||
170 | if (!isalnum(*p)) { | |||
171 | *p = '_'; | |||
172 | } | |||
173 | } | |||
174 | define2(osrevdef, "1", &maininclist); | |||
175 | } | |||
176 | } | |||
177 | #endif | |||
178 | if (argc == 2 && argv[1][0] == '@') { | |||
179 | struct stat ast; | |||
180 | int afd; | |||
181 | char *args; | |||
182 | char **nargv; | |||
183 | int nargc; | |||
184 | char quotechar = '\0'; | |||
185 | ||||
186 | nargc = 1; | |||
187 | if ((afd = open(argv[1]+1, O_RDONLY0x0000)) < 0) | |||
188 | fatalerr("cannot open \"%s\"\n", argv[1]+1); | |||
189 | fstat(afd, &ast); | |||
190 | args = malloc(ast.st_size + 1); | |||
191 | if ((ast.st_size = read(afd, args, ast.st_size)) < 0) | |||
192 | fatalerr("failed to read %s\n", argv[1]+1); | |||
193 | args[ast.st_size] = '\0'; | |||
194 | close(afd); | |||
195 | for (p = args; *p; p++) { | |||
196 | if (quotechar) { | |||
197 | if (quotechar == '\\' || | |||
198 | (*p == quotechar && p[-1] != '\\')) | |||
199 | quotechar = '\0'; | |||
200 | continue; | |||
201 | } | |||
202 | switch (*p) { | |||
203 | case '\\': | |||
204 | case '"': | |||
205 | case '\'': | |||
206 | quotechar = *p; | |||
207 | break; | |||
208 | case ' ': | |||
209 | case '\n': | |||
210 | *p = '\0'; | |||
211 | if (p > args && p[-1]) | |||
212 | nargc++; | |||
213 | break; | |||
214 | } | |||
215 | } | |||
216 | if (p[-1]) | |||
217 | nargc++; | |||
218 | nargv = malloc(nargc * sizeof(char *)); | |||
219 | nargv[0] = argv[0]; | |||
220 | argc = 1; | |||
221 | for (p = args; argc < nargc; p += strlen(p) + 1) | |||
222 | if (*p) nargv[argc++] = p; | |||
223 | argv = nargv; | |||
224 | } | |||
225 | for(argc--, argv++; argc; argc--, argv++) { | |||
226 | /* if looking for endmarker then check before parsing */ | |||
227 | if (endmarker && strcmp (endmarker, *argv) == 0) { | |||
228 | endmarker = NULL((void *)0); | |||
229 | continue; | |||
230 | } | |||
231 | if (**argv != '-') { | |||
232 | /* treat +thing as an option for C++ */ | |||
233 | if (endmarker && **argv == '+') | |||
234 | continue; | |||
235 | *fp++ = argv[0]; | |||
236 | continue; | |||
237 | } | |||
238 | switch(argv[0][1]) { | |||
239 | case '-': | |||
240 | endmarker = &argv[0][2]; | |||
241 | if (endmarker[0] == '\0') endmarker = "--"; | |||
242 | break; | |||
243 | case 'D': | |||
244 | if (argv[0][2] == '\0') { | |||
245 | if (argc < 2) | |||
246 | fatalerr("Missing argument for -D\n"); | |||
247 | argv++; | |||
248 | argc--; | |||
249 | } | |||
250 | for (p=argv[0] + 2; *p ; p++) | |||
251 | if (*p == '=') { | |||
252 | *p = ' '; | |||
253 | break; | |||
254 | } | |||
255 | define(argv[0] + 2, &maininclist); | |||
256 | break; | |||
257 | case 'I': | |||
258 | if (incp >= includedirs + MAXDIRS64) | |||
259 | fatalerr("Too many -I flags.\n"); | |||
260 | *incp++ = argv[0]+2; | |||
261 | if (**(incp-1) == '\0') { | |||
262 | if (argc < 2) | |||
263 | fatalerr("Missing argument for -I\n"); | |||
264 | *(incp-1) = *(++argv); | |||
265 | argc--; | |||
266 | } | |||
267 | break; | |||
268 | case 'U': | |||
269 | /* Undef's override all -D's so save them up */ | |||
270 | numundefs++; | |||
271 | if (numundefs == 1) | |||
272 | undeflist = malloc(sizeof(char *)); | |||
273 | else | |||
274 | undeflist = realloc(undeflist, | |||
275 | numundefs * sizeof(char *)); | |||
276 | if (argv[0][2] == '\0') { | |||
277 | if (argc < 2) | |||
278 | fatalerr("Missing argument for -U\n"); | |||
279 | argv++; | |||
280 | argc--; | |||
281 | } | |||
282 | undeflist[numundefs - 1] = argv[0] + 2; | |||
283 | break; | |||
284 | case 'Y': | |||
285 | defincdir = argv[0]+2; | |||
286 | break; | |||
287 | /* do not use if endmarker processing */ | |||
288 | case 'a': | |||
289 | if (endmarker) break; | |||
290 | append = TRUE1; | |||
291 | break; | |||
292 | case 'w': | |||
293 | if (endmarker) break; | |||
294 | if (argv[0][2] == '\0') { | |||
295 | if (argc < 2) | |||
296 | fatalerr("Missing argument for -w\n"); | |||
297 | argv++; | |||
298 | argc--; | |||
299 | width = atoi(argv[0]); | |||
300 | } else | |||
301 | width = atoi(argv[0]+2); | |||
302 | break; | |||
303 | case 'o': | |||
304 | if (endmarker) break; | |||
305 | if (argv[0][2] == '\0') { | |||
306 | if (argc < 2) | |||
307 | fatalerr("Missing argument for -o\n"); | |||
308 | argv++; | |||
309 | argc--; | |||
310 | objsuffix = argv[0]; | |||
311 | } else | |||
312 | objsuffix = argv[0]+2; | |||
313 | break; | |||
314 | case 'p': | |||
315 | if (endmarker) break; | |||
316 | if (argv[0][2] == '\0') { | |||
317 | if (argc < 2) | |||
318 | fatalerr("Missing argument for -p\n"); | |||
319 | argv++; | |||
320 | argc--; | |||
321 | objprefix = argv[0]; | |||
322 | } else | |||
323 | objprefix = argv[0]+2; | |||
324 | break; | |||
325 | case 'v': | |||
326 | if (endmarker) break; | |||
327 | verbose = TRUE1; | |||
328 | #ifdef DEBUG | |||
329 | if (argv[0][2]) | |||
330 | _debugmask = atoi(argv[0]+2); | |||
331 | #endif | |||
332 | break; | |||
333 | case 's': | |||
334 | if (endmarker) break; | |||
335 | startat = argv[0]+2; | |||
336 | if (*startat == '\0') { | |||
337 | if (argc < 2) | |||
338 | fatalerr("Missing argument for -s\n"); | |||
339 | startat = *(++argv); | |||
340 | argc--; | |||
341 | } | |||
342 | if (*startat != '#') | |||
343 | fatalerr("-s flag's value should start %s\n", | |||
344 | "with '#'."); | |||
345 | break; | |||
346 | case 'f': | |||
347 | if (endmarker) break; | |||
348 | makefile = argv[0]+2; | |||
349 | if (*makefile == '\0') { | |||
350 | if (argc < 2) | |||
351 | fatalerr("Missing argument for -f\n"); | |||
352 | makefile = *(++argv); | |||
353 | argc--; | |||
354 | } | |||
355 | break; | |||
356 | ||||
357 | case 'm': | |||
358 | warn_multiple = TRUE1; | |||
359 | break; | |||
360 | ||||
361 | /* Ignore -O, -g so we can just pass ${CFLAGS} to | |||
362 | makedepend | |||
363 | */ | |||
364 | case 'O': | |||
365 | case 'g': | |||
366 | break; | |||
367 | case 'i': | |||
368 | if (strcmp(&argv[0][1],"include") == 0) { | |||
369 | char *buf; | |||
370 | if (argc<2) | |||
371 | fatalerr("option -include is a " | |||
372 | "missing its parameter\n"); | |||
373 | if (cmdinc_count >= MAXINCFILES128) | |||
374 | fatalerr("Too many -include flags.\n"); | |||
375 | argc--; | |||
376 | argv++; | |||
377 | buf = malloc(strlen(DASH_INC_PRE"#include \"") + | |||
378 | strlen(argv[0]) + | |||
379 | strlen(DASH_INC_POST"\"") + 1); | |||
380 | if(!buf) | |||
381 | fatalerr("out of memory at " | |||
382 | "-include string\n"); | |||
383 | cmdinc_list[2 * cmdinc_count + 0] = argv[0]; | |||
384 | cmdinc_list[2 * cmdinc_count + 1] = buf; | |||
385 | cmdinc_count++; | |||
386 | break; | |||
387 | } | |||
388 | /* intentional fall through */ | |||
389 | default: | |||
390 | if (endmarker) break; | |||
391 | /* fatalerr("unknown opt = %s\n", argv[0]); */ | |||
392 | warning("ignoring option %s\n", argv[0]); | |||
393 | } | |||
394 | } | |||
395 | /* Now do the undefs from the command line */ | |||
396 | for (i = 0; i < numundefs; i++) | |||
397 | undefine(undeflist[i], &maininclist); | |||
398 | if (numundefs > 0) | |||
399 | free(undeflist); | |||
400 | ||||
401 | if (!defincdir) { | |||
402 | #ifdef PREINCDIR | |||
403 | if (incp >= includedirs + MAXDIRS64) | |||
404 | fatalerr("Too many -I flags.\n"); | |||
405 | *incp++ = PREINCDIR; | |||
406 | #endif | |||
407 | if (incp >= includedirs + MAXDIRS64) | |||
408 | fatalerr("Too many -I flags.\n"); | |||
409 | *incp++ = INCLUDEDIR"/usr/include"; | |||
410 | ||||
411 | #ifdef EXTRAINCDIR | |||
412 | if (incp >= includedirs + MAXDIRS64) | |||
413 | fatalerr("Too many -I flags.\n"); | |||
414 | *incp++ = EXTRAINCDIR; | |||
415 | #endif | |||
416 | ||||
417 | #ifdef POSTINCDIR | |||
418 | if (incp >= includedirs + MAXDIRS64) | |||
419 | fatalerr("Too many -I flags.\n"); | |||
420 | *incp++ = POSTINCDIR; | |||
421 | #endif | |||
422 | } else if (*defincdir) { | |||
423 | if (incp >= includedirs + MAXDIRS64) | |||
424 | fatalerr("Too many -I flags.\n"); | |||
425 | *incp++ = defincdir; | |||
426 | } | |||
427 | ||||
428 | redirect(startat, makefile); | |||
429 | ||||
430 | /* | |||
431 | * catch signals. | |||
432 | */ | |||
433 | #ifdef USGISH | |||
434 | /* should really reset SIGINT to SIG_IGN if it was. */ | |||
435 | #ifdef SIGHUP1 | |||
436 | signal (SIGHUP1, catch); | |||
437 | #endif | |||
438 | signal (SIGINT2, catch); | |||
439 | #ifdef SIGQUIT3 | |||
440 | signal (SIGQUIT3, catch); | |||
441 | #endif | |||
442 | signal (SIGILL4, catch); | |||
443 | #ifdef SIGBUS10 | |||
444 | signal (SIGBUS10, catch); | |||
445 | #endif | |||
446 | signal (SIGSEGV11, catch); | |||
447 | #ifdef SIGSYS12 | |||
448 | signal (SIGSYS12, catch); | |||
449 | #endif | |||
450 | #else | |||
451 | sig_act.sa_handler__sigaction_u.__sa_handler = catch; | |||
452 | #if defined(_POSIX_SOURCE) || !defined(X_NOT_POSIX) | |||
453 | sigemptyset(&sig_act.sa_mask)(*(&sig_act.sa_mask) = 0, 0); | |||
454 | sigaddset(&sig_act.sa_mask, SIGINT)(*(&sig_act.sa_mask) |= __sigbits(2), 0); | |||
455 | sigaddset(&sig_act.sa_mask, SIGQUIT)(*(&sig_act.sa_mask) |= __sigbits(3), 0); | |||
456 | #ifdef SIGBUS10 | |||
457 | sigaddset(&sig_act.sa_mask, SIGBUS)(*(&sig_act.sa_mask) |= __sigbits(10), 0); | |||
458 | #endif | |||
459 | sigaddset(&sig_act.sa_mask, SIGILL)(*(&sig_act.sa_mask) |= __sigbits(4), 0); | |||
460 | sigaddset(&sig_act.sa_mask, SIGSEGV)(*(&sig_act.sa_mask) |= __sigbits(11), 0); | |||
461 | sigaddset(&sig_act.sa_mask, SIGHUP)(*(&sig_act.sa_mask) |= __sigbits(1), 0); | |||
462 | sigaddset(&sig_act.sa_mask, SIGPIPE)(*(&sig_act.sa_mask) |= __sigbits(13), 0); | |||
463 | #ifdef SIGSYS12 | |||
464 | sigaddset(&sig_act.sa_mask, SIGSYS)(*(&sig_act.sa_mask) |= __sigbits(12), 0); | |||
465 | #endif | |||
466 | #else | |||
467 | sig_act.sa_mask = ((1<<(SIGINT2 -1)) | |||
468 | |(1<<(SIGQUIT3-1)) | |||
469 | #ifdef SIGBUS10 | |||
470 | |(1<<(SIGBUS10-1)) | |||
471 | #endif | |||
472 | |(1<<(SIGILL4-1)) | |||
473 | |(1<<(SIGSEGV11-1)) | |||
474 | |(1<<(SIGHUP1-1)) | |||
475 | |(1<<(SIGPIPE13-1)) | |||
476 | #ifdef SIGSYS12 | |||
477 | |(1<<(SIGSYS12-1)) | |||
478 | #endif | |||
479 | ); | |||
480 | #endif /* _POSIX_SOURCE */ | |||
481 | sig_act.sa_flags = 0; | |||
482 | sigaction(SIGHUP1, &sig_act, (struct sigaction *)0); | |||
483 | sigaction(SIGINT2, &sig_act, (struct sigaction *)0); | |||
484 | sigaction(SIGQUIT3, &sig_act, (struct sigaction *)0); | |||
485 | sigaction(SIGILL4, &sig_act, (struct sigaction *)0); | |||
486 | #ifdef SIGBUS10 | |||
487 | sigaction(SIGBUS10, &sig_act, (struct sigaction *)0); | |||
488 | #endif | |||
489 | sigaction(SIGSEGV11, &sig_act, (struct sigaction *)0); | |||
490 | #ifdef SIGSYS12 | |||
491 | sigaction(SIGSYS12, &sig_act, (struct sigaction *)0); | |||
492 | #endif | |||
493 | #endif /* USGISH */ | |||
494 | ||||
495 | /* | |||
496 | * now peruse through the list of files. | |||
497 | */ | |||
498 | for(fp=filelist; *fp; fp++) { | |||
499 | DBG_PRINT(stderr,"file: %s\n",*fp); | |||
500 | filecontent = getfile(*fp); | |||
501 | setfile_cmdinc(filecontent, cmdinc_count, cmdinc_list); | |||
502 | ip = newinclude(*fp, (char *)NULL((void *)0)); | |||
503 | ||||
504 | find_includes(filecontent, ip, ip, 0, FALSE0); | |||
505 | freefile(filecontent); | |||
506 | recursive_pr_include(ip, ip->i_file, base_name(*fp)); | |||
507 | inc_clean(); | |||
| ||||
508 | } | |||
509 | if (printed) | |||
510 | printf("\n"); | |||
511 | return 0; | |||
512 | } | |||
513 | ||||
514 | ||||
515 | struct filepointer * | |||
516 | getfile(const char *file) | |||
517 | { | |||
518 | int fd; | |||
519 | struct filepointer *content; | |||
520 | struct stat st; | |||
521 | ||||
522 | content = malloc(sizeof(struct filepointer)); | |||
523 | content->f_name = file; | |||
524 | if ((fd = open(file, O_RDONLY0x0000)) < 0) { | |||
525 | warning("cannot open \"%s\"\n", file); | |||
526 | content->f_p = content->f_base = content->f_end = malloc(1); | |||
527 | *content->f_p = '\0'; | |||
528 | return(content); | |||
529 | } | |||
530 | fstat(fd, &st); | |||
531 | content->f_base = malloc(st.st_size+1); | |||
532 | if (content->f_base == NULL((void *)0)) | |||
533 | fatalerr("cannot allocate mem\n"); | |||
534 | if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0) | |||
535 | fatalerr("failed to read %s\n", file); | |||
536 | close(fd); | |||
537 | content->f_len = st.st_size+1; | |||
538 | content->f_p = content->f_base; | |||
539 | content->f_end = content->f_base + st.st_size; | |||
540 | *content->f_end = '\0'; | |||
541 | content->f_line = 0; | |||
542 | content->cmdinc_count = 0; | |||
543 | content->cmdinc_list = NULL((void *)0); | |||
544 | content->cmdinc_line = 0; | |||
545 | return(content); | |||
546 | } | |||
547 | ||||
548 | void | |||
549 | setfile_cmdinc(struct filepointer* filep, long count, char** list) | |||
550 | { | |||
551 | filep->cmdinc_count = count; | |||
552 | filep->cmdinc_list = list; | |||
553 | filep->cmdinc_line = 0; | |||
554 | } | |||
555 | ||||
556 | void | |||
557 | freefile(struct filepointer *fp) | |||
558 | { | |||
559 | free(fp->f_base); | |||
560 | free(fp); | |||
561 | } | |||
562 | ||||
563 | int | |||
564 | match(const char *str, const char * const *list) | |||
565 | { | |||
566 | int i; | |||
567 | ||||
568 | for (i=0; *list; i++, list++) | |||
569 | if (strcmp(str, *list) == 0) | |||
570 | return(i); | |||
571 | return(-1); | |||
572 | } | |||
573 | ||||
574 | /* | |||
575 | * Get the next line. We only return lines beginning with '#' since that | |||
576 | * is all this program is ever interested in. | |||
577 | */ | |||
578 | char *getnextline(struct filepointer *filep) | |||
579 | { | |||
580 | char *p, /* walking pointer */ | |||
581 | *eof, /* end of file pointer */ | |||
582 | *bol; /* beginning of line pointer */ | |||
583 | int lineno; /* line number */ | |||
584 | boolean whitespace = FALSE0; | |||
585 | ||||
586 | /* | |||
587 | * Fake the "-include" line files in form of #include to the | |||
588 | * start of each file. | |||
589 | */ | |||
590 | if (filep->cmdinc_line < filep->cmdinc_count) { | |||
591 | char *inc = filep->cmdinc_list[2 * filep->cmdinc_line + 0]; | |||
592 | char *buf = filep->cmdinc_list[2 * filep->cmdinc_line + 1]; | |||
593 | filep->cmdinc_line++; | |||
594 | sprintf(buf,"%s%s%s",DASH_INC_PRE,inc,DASH_INC_POST)__builtin___sprintf_chk (buf, 0, __builtin_object_size (buf, 2 > 1 ? 1 : 0), "%s%s%s","#include \"",inc,"\""); | |||
595 | DBG_PRINT(stderr,"%s\n",buf); | |||
596 | return(buf); | |||
597 | } | |||
598 | ||||
599 | p = filep->f_p; | |||
600 | eof = filep->f_end; | |||
601 | if (p >= eof) | |||
602 | return((char *)NULL((void *)0)); | |||
603 | lineno = filep->f_line; | |||
604 | ||||
605 | for (bol = p--; ++p < eof; ) { | |||
606 | if ((bol == p) && ((*p == ' ') || (*p == '\t'))) | |||
607 | { | |||
608 | /* Consume leading white-spaces for this line */ | |||
609 | while (((p+1) < eof) && ((*p == ' ') || (*p == '\t'))) | |||
610 | { | |||
611 | p++; | |||
612 | bol++; | |||
613 | } | |||
614 | whitespace = TRUE1; | |||
615 | } | |||
616 | ||||
617 | if (*p == '/' && (p+1) < eof && *(p+1) == '*') { | |||
618 | /* Consume C comments */ | |||
619 | *(p++) = ' '; | |||
620 | *(p++) = ' '; | |||
621 | while (p < eof && *p) { | |||
622 | if (*p == '*' && (p+1) < eof && *(p+1) == '/') { | |||
623 | *(p++) = ' '; | |||
624 | *(p++) = ' '; | |||
625 | break; | |||
626 | } | |||
627 | if (*p == '\n') | |||
628 | lineno++; | |||
629 | *(p++) = ' '; | |||
630 | } | |||
631 | --p; | |||
632 | } | |||
633 | else if (*p == '/' && (p+1) < eof && *(p+1) == '/') { | |||
634 | /* Consume C++ comments */ | |||
635 | *(p++) = ' '; | |||
636 | *(p++) = ' '; | |||
637 | while (p < eof && *p) { | |||
638 | if (*p == '\\' && (p+1) < eof && | |||
639 | *(p+1) == '\n') { | |||
640 | *(p++) = ' '; | |||
641 | lineno++; | |||
642 | } | |||
643 | else if (*p == '?' && (p+3) < eof && | |||
644 | *(p+1) == '?' && | |||
645 | *(p+2) == '/' && | |||
646 | *(p+3) == '\n') { | |||
647 | *(p++) = ' '; | |||
648 | *(p++) = ' '; | |||
649 | *(p++) = ' '; | |||
650 | lineno++; | |||
651 | } | |||
652 | else if (*p == '\n') | |||
653 | break; /* to process end of line */ | |||
654 | *(p++) = ' '; | |||
655 | } | |||
656 | --p; | |||
657 | } | |||
658 | else if (*p == '\\' && (p+1) < eof && *(p+1) == '\n') { | |||
659 | /* Consume backslash line terminations */ | |||
660 | *(p++) = ' '; | |||
661 | *p = ' '; | |||
662 | lineno++; | |||
663 | } | |||
664 | else if (*p == '?' && (p+3) < eof && | |||
665 | *(p+1) == '?' && *(p+2) == '/' && *(p+3) == '\n') { | |||
666 | /* Consume trigraph'ed backslash line terminations */ | |||
667 | *(p++) = ' '; | |||
668 | *(p++) = ' '; | |||
669 | *(p++) = ' '; | |||
670 | *p = ' '; | |||
671 | lineno++; | |||
672 | } | |||
673 | else if (*p == '\n') { | |||
674 | lineno++; | |||
675 | if (*bol == '#') { | |||
676 | char *cp; | |||
677 | ||||
678 | *(p++) = '\0'; | |||
679 | /* punt lines with just # (yacc generated) */ | |||
680 | for (cp = bol+1; | |||
681 | *cp && (*cp == ' ' || *cp == '\t'); cp++); | |||
682 | if (*cp) goto done; | |||
683 | --p; | |||
684 | } | |||
685 | bol = p+1; | |||
686 | whitespace = FALSE0; | |||
687 | } | |||
688 | } | |||
689 | if (*bol != '#') | |||
690 | bol = NULL((void *)0); | |||
691 | done: | |||
692 | filep->f_p = p; | |||
693 | filep->f_line = lineno; | |||
694 | #ifdef DEBUG_DUMP | |||
695 | if (bol) | |||
696 | DBG_PRINT(stderr,"%s\n",bol); | |||
697 | #endif | |||
698 | return(bol); | |||
699 | } | |||
700 | ||||
701 | /* | |||
702 | * Strip the file name down to what we want to see in the Makefile. | |||
703 | * It will have objprefix and objsuffix around it. | |||
704 | */ | |||
705 | char *base_name(const char *in_file) | |||
706 | { | |||
707 | char *p; | |||
708 | char *file = strdup(in_file); | |||
709 | for(p=file+strlen(file); p>file && *p != '.'; p--) ; | |||
710 | ||||
711 | if (*p == '.') | |||
712 | *p = '\0'; | |||
713 | return(file); | |||
714 | } | |||
715 | ||||
716 | #ifndef HAVE_RENAME1 | |||
717 | int rename (char *from, char *to) | |||
718 | { | |||
719 | (void) unlink (to); | |||
720 | if (link (from, to) == 0) { | |||
721 | unlink (from); | |||
722 | return 0; | |||
723 | } else { | |||
724 | return -1; | |||
725 | } | |||
726 | } | |||
727 | #endif /* !HAVE_RENAME */ | |||
728 | ||||
729 | static void | |||
730 | redirect(const char *line, const char *makefile) | |||
731 | { | |||
732 | struct stat st; | |||
733 | FILE *fdin, *fdout; | |||
734 | char backup[ BUFSIZ1024 ], | |||
735 | buf[ BUFSIZ1024 ]; | |||
736 | boolean found = FALSE0; | |||
737 | size_t len; | |||
738 | ||||
739 | /* | |||
740 | * if makefile is "-" then let it pour onto stdout. | |||
741 | */ | |||
742 | if (makefile && *makefile == '-' && *(makefile+1) == '\0') { | |||
743 | puts(line); | |||
744 | return; | |||
745 | } | |||
746 | ||||
747 | /* | |||
748 | * use a default if makefile is not specified. | |||
749 | */ | |||
750 | if (!makefile) { | |||
751 | if (stat("Makefile", &st) == 0) | |||
752 | makefile = "Makefile"; | |||
753 | else if (stat("makefile", &st) == 0) | |||
754 | makefile = "makefile"; | |||
755 | else | |||
756 | fatalerr("[mM]akefile is not present\n"); | |||
757 | } | |||
758 | else { | |||
759 | if (stat(makefile, &st) != 0) | |||
760 | fatalerr("\"%s\" is not present\n", makefile); | |||
761 | } | |||
762 | ||||
763 | snprintf(backup, sizeof(backup), "%s.bak", makefile)__builtin___snprintf_chk (backup, sizeof(backup), 0, __builtin_object_size (backup, 2 > 1 ? 1 : 0), "%s.bak", makefile); | |||
764 | unlink(backup); | |||
765 | ||||
766 | /* rename() won't work on WIN32, CYGWIN, or CIFS if src file is open */ | |||
767 | if (rename(makefile, backup) < 0) | |||
768 | fatalerr("cannot rename %s to %s\n", makefile, backup); | |||
769 | if ((fdin = fopen(backup, "r")) == NULL((void *)0)) { | |||
770 | if (rename(backup, makefile) < 0) | |||
771 | warning("renamed %s to %s, but can't move it back\n", | |||
772 | makefile, backup); | |||
773 | fatalerr("cannot open \"%s\"\n", makefile); | |||
774 | } | |||
775 | if ((fdout = freopen(makefile, "w", stdout__stdoutp)) == NULL((void *)0)) | |||
776 | fatalerr("cannot open \"%s\"\n", backup); | |||
777 | len = strlen(line); | |||
778 | while (!found && fgets(buf, BUFSIZ1024, fdin)) { | |||
779 | if (*buf == '#' && strncmp(line, buf, len) == 0) | |||
780 | found = TRUE1; | |||
781 | fputs(buf, fdout); | |||
782 | } | |||
783 | if (!found) { | |||
784 | if (verbose) | |||
785 | warning("Adding new delimiting line \"%s\" and dependencies...\n", | |||
786 | line); | |||
787 | puts(line); /* same as fputs(fdout); but with newline */ | |||
788 | } else if (append) { | |||
789 | while (fgets(buf, BUFSIZ1024, fdin)) { | |||
790 | fputs(buf, fdout); | |||
791 | } | |||
792 | } | |||
793 | fflush(fdout); | |||
794 | #ifndef HAVE_FCHMOD1 | |||
795 | chmod(makefile, st.st_mode); | |||
796 | #else | |||
797 | fchmod(fileno(fdout), st.st_mode); | |||
798 | #endif /* HAVE_FCHMOD */ | |||
799 | } | |||
800 | ||||
801 | void | |||
802 | fatalerr(const char *msg, ...) | |||
803 | { | |||
804 | va_list args; | |||
805 | fprintf(stderr__stderrp, "%s: error: ", ProgramName); | |||
806 | va_start(args, msg)__builtin_va_start(args, msg); | |||
807 | vfprintf(stderr__stderrp, msg, args); | |||
808 | va_end(args)__builtin_va_end(args); | |||
809 | exit (1); | |||
810 | } | |||
811 | ||||
812 | void | |||
813 | warning(const char *msg, ...) | |||
814 | { | |||
815 | va_list args; | |||
816 | fprintf(stderr__stderrp, "%s: warning: ", ProgramName); | |||
817 | va_start(args, msg)__builtin_va_start(args, msg); | |||
818 | vfprintf(stderr__stderrp, msg, args); | |||
819 | va_end(args)__builtin_va_end(args); | |||
820 | } | |||
821 | ||||
822 | void | |||
823 | warning1(const char *msg, ...) | |||
824 | { | |||
825 | va_list args; | |||
826 | va_start(args, msg)__builtin_va_start(args, msg); | |||
827 | vfprintf(stderr__stderrp, msg, args); | |||
828 | va_end(args)__builtin_va_end(args); | |||
829 | } |