2 dawes 1.1 /*
3
4 Copyright (c) 1993, 1994 X Consortium
5
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
20 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23 dawes 1.1 Except as contained in this notice, the name of the X Consortium shall not be
24 used in advertising or otherwise to promote the sale, use or other dealings
25 in this Software without prior written authorization from the X Consortium.
26
27 */
28
29 #include "def.h"
30 #ifdef hpux
31 #define sigvec sigvector
32 #endif /* hpux */
33
34 #ifdef X_POSIX_C_SOURCE
35 #define _POSIX_C_SOURCE X_POSIX_C_SOURCE
36 #include <signal.h>
37 #undef _POSIX_C_SOURCE
38 #else
39 #if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
40 #include <signal.h>
41 #else
42 #define _POSIX_SOURCE
43 #include <signal.h>
44 dawes 1.1 #undef _POSIX_SOURCE
45 #endif
46 #endif
47
48 #if NeedVarargsPrototypes
49 #include <stdarg.h>
50 #endif
51
52 #ifdef DEBUG
53 int _debugmask;
54 #endif
55
56 char *ProgramName;
57
58 char *directives[] = {
59 "if",
60 "ifdef",
61 "ifndef",
62 "else",
63 "endif",
64 "define",
65 dawes 1.1 "undef",
66 "include",
67 "line",
68 "pragma",
69 "error",
70 "ident",
71 "sccs",
72 "elif",
73 "eject",
74 NULL
75 };
76
77 #define MAKEDEPEND
78 #include "imakemdep.h" /* from config sources */
79 #undef MAKEDEPEND
80
81 struct inclist inclist[ MAXFILES ],
82 *inclistp = inclist,
83 maininclist;
84
85 char *filelist[ MAXFILES ];
86 dawes 1.1 char *includedirs[ MAXDIRS + 1 ];
87 char *notdotdot[ MAXDIRS ];
88 char *objprefix = "";
89 char *objsuffix = OBJSUFFIX;
90 char *startat = "# DO NOT DELETE";
91 int width = 78;
92 boolean append = FALSE;
93 boolean printed = FALSE;
94 boolean verbose = FALSE;
95 boolean show_where_not = FALSE;
96 boolean warn_multiple = FALSE; /* Warn on multiple includes of same file */
97
98 static
99 #ifdef SIGNALRETURNSINT
100 int
101 #else
102 void
103 #endif
104 catch (sig)
105 int sig;
106 {
107 dawes 1.1 fflush (stdout);
108 fatalerr ("got signal %d\n", sig);
109 }
110
|
112 dawes 1.1 #define USGISH
113 #endif
114
115 #ifndef USGISH
116 #ifndef _POSIX_SOURCE
117 #define sigaction sigvec
118 #define sa_handler sv_handler
119 #define sa_mask sv_mask
120 #define sa_flags sv_flags
121 #endif
122 struct sigaction sig_act;
123 #endif /* USGISH */
124
125 main(argc, argv)
126 int argc;
127 char **argv;
128 {
129 register char **fp = filelist;
130 register char **incp = includedirs;
131 register char *p;
132 register struct inclist *ip;
133 dawes 1.1 char *makefile = NULL;
134 struct filepointer *filecontent;
135 struct symtab *psymp = predefs;
136 char *endmarker = NULL;
137 char *defincdir = NULL;
138
139 ProgramName = argv[0];
140
141 while (psymp->s_name)
142 {
143 define2(psymp->s_name, psymp->s_value, &maininclist);
144 psymp++;
145 }
146 if (argc == 2 && argv[1][0] == '@') {
147 struct stat ast;
148 int afd;
149 char *args;
150 char **nargv;
151 int nargc;
152 char quotechar = '\0';
153
154 dawes 1.1 nargc = 1;
155 if ((afd = open(argv[1]+1, O_RDONLY)) < 0)
156 fatalerr("cannot open \"%s\"\n", argv[1]+1);
157 fstat(afd, &ast);
158 args = (char *)malloc(ast.st_size + 1);
159 if ((ast.st_size = read(afd, args, ast.st_size)) < 0)
160 fatalerr("failed to read %s\n", argv[1]+1);
161 args[ast.st_size] = '\0';
162 close(afd);
163 for (p = args; *p; p++) {
164 if (quotechar) {
165 if (quotechar == '\\' ||
166 (*p == quotechar && p[-1] != '\\'))
167 quotechar = '\0';
168 continue;
169 }
170 switch (*p) {
171 case '\\':
172 case '"':
173 case '\'':
174 quotechar = *p;
175 dawes 1.1 break;
176 case ' ':
177 case '\n':
178 *p = '\0';
179 if (p > args && p[-1])
180 nargc++;
181 break;
182 }
183 }
184 if (p[-1])
185 nargc++;
186 nargv = (char **)malloc(nargc * sizeof(char *));
187 nargv[0] = argv[0];
188 argc = 1;
189 for (p = args; argc < nargc; p += strlen(p) + 1)
190 if (*p) nargv[argc++] = p;
191 argv = nargv;
192 }
193 for(argc--, argv++; argc; argc--, argv++) {
194 /* if looking for endmarker then check before parsing */
195 if (endmarker && strcmp (endmarker, *argv) == 0) {
196 dawes 1.1 endmarker = NULL;
197 continue;
198 }
199 if (**argv != '-') {
200 /* treat +thing as an option for C++ */
201 if (endmarker && **argv == '+')
202 continue;
203 *fp++ = argv[0];
204 continue;
205 }
206 switch(argv[0][1]) {
207 case '-':
208 endmarker = &argv[0][2];
209 if (endmarker[0] == '\0') endmarker = "--";
210 break;
211 case 'D':
212 if (argv[0][2] == '\0') {
213 argv++;
214 argc--;
215 }
216 for (p=argv[0] + 2; *p ; p++)
217 dawes 1.1 if (*p == '=') {
218 *p = ' ';
219 break;
220 }
221 define(argv[0] + 2, &maininclist);
222 break;
223 case 'I':
224 if (incp >= includedirs + MAXDIRS)
225 fatalerr("Too many -I flags.\n");
226 *incp++ = argv[0]+2;
227 if (**(incp-1) == '\0') {
228 *(incp-1) = *(++argv);
229 argc--;
230 }
231 break;
232 case 'Y':
233 defincdir = argv[0]+2;
234 break;
235 /* do not use if endmarker processing */
236 case 'a':
237 if (endmarker) break;
238 dawes 1.1 append = TRUE;
239 break;
240 case 'w':
241 if (endmarker) break;
242 if (argv[0][2] == '\0') {
243 argv++;
244 argc--;
245 width = atoi(argv[0]);
246 } else
247 width = atoi(argv[0]+2);
248 break;
249 case 'o':
250 if (endmarker) break;
251 if (argv[0][2] == '\0') {
252 argv++;
253 argc--;
254 objsuffix = argv[0];
255 } else
256 objsuffix = argv[0]+2;
257 break;
258 case 'p':
259 dawes 1.1 if (endmarker) break;
260 if (argv[0][2] == '\0') {
261 argv++;
262 argc--;
263 objprefix = argv[0];
264 } else
265 objprefix = argv[0]+2;
266 break;
267 case 'v':
268 if (endmarker) break;
269 verbose = TRUE;
270 #ifdef DEBUG
271 if (argv[0][2])
272 _debugmask = atoi(argv[0]+2);
273 #endif
274 break;
275 case 's':
276 if (endmarker) break;
277 startat = argv[0]+2;
278 if (*startat == '\0') {
279 startat = *(++argv);
280 dawes 1.1 argc--;
281 }
282 if (*startat != '#')
283 fatalerr("-s flag's value should start %s\n",
284 "with '#'.");
285 break;
286 case 'f':
287 if (endmarker) break;
288 makefile = argv[0]+2;
289 if (*makefile == '\0') {
290 makefile = *(++argv);
291 argc--;
292 }
293 break;
294
295 case 'm':
296 warn_multiple = TRUE;
297 break;
298
299 /* Ignore -O, -g so we can just pass ${CFLAGS} to
300 makedepend
301 dawes 1.1 */
302 case 'O':
303 case 'g':
304 break;
305 default:
306 if (endmarker) break;
307 /* fatalerr("unknown opt = %s\n", argv[0]); */
308 warning("ignoring option %s\n", argv[0]);
309 }
310 }
311 if (!defincdir) {
312 #ifdef PREINCDIR
313 if (incp >= includedirs + MAXDIRS)
314 fatalerr("Too many -I flags.\n");
315 *incp++ = PREINCDIR;
316 #endif
317 if (incp >= includedirs + MAXDIRS)
318 fatalerr("Too many -I flags.\n");
319 *incp++ = INCLUDEDIR;
320 #ifdef POSTINCDIR
321 if (incp >= includedirs + MAXDIRS)
322 dawes 1.1 fatalerr("Too many -I flags.\n");
323 *incp++ = POSTINCDIR;
324 #endif
325 } else if (*defincdir) {
326 if (incp >= includedirs + MAXDIRS)
327 fatalerr("Too many -I flags.\n");
328 *incp++ = defincdir;
329 }
330
331 redirect(startat, makefile);
332
333 /*
334 * catch signals.
335 */
336 #ifdef USGISH
337 /* should really reset SIGINT to SIG_IGN if it was. */
338 #ifdef SIGHUP
339 signal (SIGHUP, catch);
340 #endif
341 signal (SIGINT, catch);
342 #ifdef SIGQUIT
343 dawes 1.1 signal (SIGQUIT, catch);
344 #endif
345 signal (SIGILL, catch);
346 #ifdef SIGBUS
347 signal (SIGBUS, catch);
348 #endif
349 signal (SIGSEGV, catch);
350 #ifdef SIGSYS
351 signal (SIGSYS, catch);
352 #endif
353 #else
354 sig_act.sa_handler = catch;
355 #ifdef _POSIX_SOURCE
356 sigemptyset(&sig_act.sa_mask);
357 sigaddset(&sig_act.sa_mask, SIGINT);
358 sigaddset(&sig_act.sa_mask, SIGQUIT);
359 #ifdef SIGBUS
360 sigaddset(&sig_act.sa_mask, SIGBUS);
361 #endif
362 sigaddset(&sig_act.sa_mask, SIGILL);
363 sigaddset(&sig_act.sa_mask, SIGSEGV);
364 dawes 1.1 sigaddset(&sig_act.sa_mask, SIGHUP);
365 sigaddset(&sig_act.sa_mask, SIGPIPE);
366 #ifdef SIGSYS
367 sigaddset(&sig_act.sa_mask, SIGSYS);
368 #endif
369 #else
370 sig_act.sa_mask = ((1<<(SIGINT -1))
371 |(1<<(SIGQUIT-1))
372 #ifdef SIGBUS
373 |(1<<(SIGBUS-1))
374 #endif
375 |(1<<(SIGILL-1))
376 |(1<<(SIGSEGV-1))
377 |(1<<(SIGHUP-1))
378 |(1<<(SIGPIPE-1))
379 #ifdef SIGSYS
380 |(1<<(SIGSYS-1))
381 #endif
382 );
383 #endif /* _POSIX_SOURCE */
384 sig_act.sa_flags = 0;
385 dawes 1.1 sigaction(SIGHUP, &sig_act, (struct sigaction *)0);
386 sigaction(SIGINT, &sig_act, (struct sigaction *)0);
387 sigaction(SIGQUIT, &sig_act, (struct sigaction *)0);
388 sigaction(SIGILL, &sig_act, (struct sigaction *)0);
389 #ifdef SIGBUS
390 sigaction(SIGBUS, &sig_act, (struct sigaction *)0);
391 #endif
392 sigaction(SIGSEGV, &sig_act, (struct sigaction *)0);
393 #ifdef SIGSYS
394 sigaction(SIGSYS, &sig_act, (struct sigaction *)0);
395 #endif
396 #endif /* USGISH */
397
398 /*
399 * now peruse through the list of files.
400 */
401 for(fp=filelist; *fp; fp++) {
402 filecontent = getfile(*fp);
403 ip = newinclude(*fp, (char *)NULL);
404
405 find_includes(filecontent, ip, ip, 0, FALSE);
406 dawes 1.1 freefile(filecontent);
407 recursive_pr_include(ip, ip->i_file, base_name(*fp));
408 inc_clean();
409 }
410 if (printed)
411 printf("\n");
412 exit(0);
413 }
414
415 struct filepointer *getfile(file)
416 char *file;
417 {
418 register int fd;
419 struct filepointer *content;
420 struct stat st;
421
422 content = (struct filepointer *)malloc(sizeof(struct filepointer));
423 if ((fd = open(file, O_RDONLY)) < 0) {
424 warning("cannot open \"%s\"\n", file);
425 content->f_p = content->f_base = content->f_end = (char *)malloc(1);
426 *content->f_p = '\0';
427 dawes 1.1 return(content);
428 }
429 fstat(fd, &st);
430 content->f_base = (char *)malloc(st.st_size+1);
431 if (content->f_base == NULL)
432 fatalerr("cannot allocate mem\n");
433 if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0)
434 fatalerr("failed to read %s\n", file);
435 close(fd);
436 content->f_len = st.st_size+1;
437 content->f_p = content->f_base;
438 content->f_end = content->f_base + st.st_size;
439 *content->f_end = '\0';
440 content->f_line = 0;
441 return(content);
442 }
443
444 freefile(fp)
445 struct filepointer *fp;
446 {
447 free(fp->f_base);
448 dawes 1.1 free(fp);
449 }
450
451 char *copy(str)
452 register char *str;
453 {
454 register char *p = (char *)malloc(strlen(str) + 1);
455
456 strcpy(p, str);
457 return(p);
458 }
459
460 match(str, list)
461 register char *str, **list;
462 {
463 register int i;
464
465 for (i=0; *list; i++, list++)
466 if (strcmp(str, *list) == 0)
467 return(i);
468 return(-1);
469 dawes 1.1 }
470
471 /*
472 * Get the next line. We only return lines beginning with '#' since that
473 * is all this program is ever interested in.
474 */
475 char *getline(filep)
476 register struct filepointer *filep;
477 {
478 register char *p, /* walking pointer */
479 *eof, /* end of file pointer */
480 *bol; /* beginning of line pointer */
481 register lineno; /* line number */
482
483 p = filep->f_p;
484 eof = filep->f_end;
485 if (p >= eof)
486 return((char *)NULL);
487 lineno = filep->f_line;
488
489 for(bol = p--; ++p < eof; ) {
490 dawes 1.1 if (*p == '/' && *(p+1) == '*') { /* consume comments */
491 *p++ = ' ', *p++ = ' ';
492 while (*p) {
493 if (*p == '*' && *(p+1) == '/') {
494 *p++ = ' ', *p = ' ';
495 break;
496 }
497 else if (*p == '\n')
498 lineno++;
499 *p++ = ' ';
500 }
501 continue;
502 }
503 #ifdef WIN32
504 else if (*p == '/' && *(p+1) == '/') { /* consume comments */
505 *p++ = ' ', *p++ = ' ';
506 while (*p && *p != '\n')
507 *p++ = ' ';
508 lineno++;
509 continue;
510 }
511 dawes 1.1 #endif
512 else if (*p == '\\') {
513 if (*(p+1) == '\n') {
514 *p = ' ';
515 *(p+1) = ' ';
516 lineno++;
517 }
518 }
519 else if (*p == '\n') {
520 lineno++;
521 if (*bol == '#') {
522 register char *cp;
523
524 *p++ = '\0';
525 /* punt lines with just # (yacc generated) */
526 for (cp = bol+1;
527 *cp && (*cp == ' ' || *cp == '\t'); cp++);
528 if (*cp) goto done;
529 }
530 bol = p+1;
531 }
532 dawes 1.1 }
533 if (*bol != '#')
534 bol = NULL;
535 done:
536 filep->f_p = p;
537 filep->f_line = lineno;
538 return(bol);
539 }
540
541 /*
542 * Strip the file name down to what we want to see in the Makefile.
543 * It will have objprefix and objsuffix around it.
544 */
545 char *base_name(file)
546 register char *file;
547 {
548 register char *p;
549
550 file = copy(file);
551 for(p=file+strlen(file); p>file && *p != '.'; p--) ;
552
553 dawes 1.1 if (*p == '.')
554 *p = '\0';
555 return(file);
556 }
557
558 #if defined(USG) && !defined(CRAY) && !defined(SVR4)
559 int rename (from, to)
560 char *from, *to;
561 {
562 (void) unlink (to);
563 if (link (from, to) == 0) {
564 unlink (from);
565 return 0;
566 } else {
567 return -1;
568 }
569 }
570 #endif /* USGISH */
571
572 redirect(line, makefile)
573 char *line,
574 dawes 1.1 *makefile;
575 {
576 struct stat st;
577 FILE *fdin, *fdout;
578 char backup[ BUFSIZ ],
579 buf[ BUFSIZ ];
580 boolean found = FALSE;
581 int len;
582
583 /*
584 * if makefile is "-" then let it pour onto stdout.
585 */
|
590 dawes 1.1
591 /*
592 * use a default makefile is not specified.
593 */
594 if (!makefile) {
595 if (stat("Makefile", &st) == 0)
596 makefile = "Makefile";
597 else if (stat("makefile", &st) == 0)
598 makefile = "makefile";
599 else
600 fatalerr("[mM]akefile is not present\n");
601 }
602 else
603 stat(makefile, &st);
604 if ((fdin = fopen(makefile, "r")) == NULL)
605 fatalerr("cannot open \"%s\"\n", makefile);
606 sprintf(backup, "%s.bak", makefile);
607 unlink(backup);
608 #ifdef WIN32
609 fclose(fdin);
610 #endif
611 dawes 1.1 if (rename(makefile, backup) < 0)
612 fatalerr("cannot rename %s to %s\n", makefile, backup);
613 #ifdef WIN32
614 if ((fdin = fopen(backup, "r")) == NULL)
615 fatalerr("cannot open \"%s\"\n", backup);
616 #endif
617 if ((fdout = freopen(makefile, "w", stdout)) == NULL)
618 fatalerr("cannot open \"%s\"\n", backup);
619 len = strlen(line);
620 while (!found && fgets(buf, BUFSIZ, fdin)) {
621 if (*buf == '#' && strncmp(line, buf, len) == 0)
622 found = TRUE;
623 fputs(buf, fdout);
624 }
625 if (!found) {
626 if (verbose)
627 warning("Adding new delimiting line \"%s\" and dependencies...\n",
628 line);
629 puts(line); /* same as fputs(fdout); but with newline */
630 } else if (append) {
631 while (fgets(buf, BUFSIZ, fdin)) {
632 dawes 1.1 fputs(buf, fdout);
633 }
634 }
635 fflush(fdout);
636 #if defined(USGISH) || defined(_SEQUENT_)
637 chmod(makefile, st.st_mode);
638 #else
639 fchmod(fileno(fdout), st.st_mode);
640 #endif /* USGISH */
641 }
642
643 #if NeedVarargsPrototypes
644 fatalerr(char *msg, ...)
645 #else
646 /*VARARGS*/
647 fatalerr(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
648 char *msg;
649 #endif
650 {
651 #if NeedVarargsPrototypes
652 va_list args;
653 dawes 1.1 #endif
654 fprintf(stderr, "%s: error: ", ProgramName);
655 #if NeedVarargsPrototypes
656 va_start(args, msg);
657 vfprintf(stderr, msg, args);
658 va_end(args);
659 #else
660 fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
661 #endif
662 exit (1);
663 }
664
665 #if NeedVarargsPrototypes
666 warning(char *msg, ...)
667 #else
668 /*VARARGS0*/
669 warning(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
670 char *msg;
671 #endif
672 {
673 #if NeedVarargsPrototypes
674 dawes 1.1 va_list args;
675 #endif
676 fprintf(stderr, "%s: warning: ", ProgramName);
677 #if NeedVarargsPrototypes
678 va_start(args, msg);
679 vfprintf(stderr, msg, args);
680 va_end(args);
681 #else
682 fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
683 #endif
684 }
685
686 #if NeedVarargsPrototypes
687 warning1(char *msg, ...)
688 #else
689 /*VARARGS0*/
690 warning1(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
691 char *msg;
692 #endif
693 {
694 #if NeedVarargsPrototypes
695 dawes 1.1 va_list args;
696 va_start(args, msg);
697 vfprintf(stderr, msg, args);
698 va_end(args);
699 #else
700 fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
701 #endif
702 }
|