1 /* $XConsortium: main.c /main/84 1996/12/04 10:11:23 swick $ */
2 /* $XFree86: xc/config/makedepend/main.c,v 3.11.2.1 1997/05/11 05:04:07 dawes Exp $ */
5 Copyright (c) 1993, 1994 X Consortium
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 Except as contained in this notice, the name of the X Consortium shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from the X Consortium.
32 #define sigvec sigvector
35 #ifdef X_POSIX_C_SOURCE
36 #define _POSIX_C_SOURCE X_POSIX_C_SOURCE
38 #undef _POSIX_C_SOURCE
40 #if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
49 #if NeedVarargsPrototypes
63 char *directives[] = {
84 #include "imakemdep.h" /* from config sources */
87 struct inclist inclist[ MAXFILES ],
91 char *filelist[ MAXFILES ];
92 char *includedirs[ MAXDIRS + 1 ];
93 char *notdotdot[ MAXDIRS ];
95 char *objsuffix = OBJSUFFIX;
96 char *startat = "# DO NOT DELETE";
98 boolean append = FALSE;
99 boolean printed = FALSE;
100 boolean verbose = FALSE;
101 boolean show_where_not = FALSE;
102 boolean warn_multiple = FALSE; /* Warn on multiple includes of same file */
106 #if !NeedVarargsPrototypes
113 #ifdef SIGNALRETURNSINT
122 fatalerr ("got signal %d\n", sig);
125 #if defined(USG) || (defined(i386) && defined(SYSV)) || defined(WIN32) || defined(__EMX__) || defined(Lynx_22)
130 #ifndef _POSIX_SOURCE
131 #define sigaction sigvec
132 #define sa_handler sv_handler
133 #define sa_mask sv_mask
134 #define sa_flags sv_flags
136 struct sigaction sig_act;
143 register char **fp = filelist;
144 register char **incp = includedirs;
146 register struct inclist *ip;
147 char *makefile = NULL;
148 struct filepointer *filecontent;
149 struct symtab *psymp = predefs;
150 char *endmarker = NULL;
151 char *defincdir = NULL;
152 char **undeflist = NULL;
153 int numundefs = 0, i;
155 ProgramName = argv[0];
157 while (psymp->s_name)
159 define2(psymp->s_name, psymp->s_value, &maininclist);
162 if (argc == 2 && argv[1][0] == '@') {
168 char quotechar = '\0';
171 if ((afd = open(argv[1]+1, O_RDONLY)) < 0)
172 fatalerr("cannot open \"%s\"\n", argv[1]+1);
174 args = (char *)malloc(ast.st_size + 1);
175 if ((ast.st_size = read(afd, args, ast.st_size)) < 0)
176 fatalerr("failed to read %s\n", argv[1]+1);
177 args[ast.st_size] = '\0';
179 for (p = args; *p; p++) {
181 if (quotechar == '\\' ||
182 (*p == quotechar && p[-1] != '\\'))
195 if (p > args && p[-1])
202 nargv = (char **)malloc(nargc * sizeof(char *));
205 for (p = args; argc < nargc; p += strlen(p) + 1)
206 if (*p) nargv[argc++] = p;
209 for(argc--, argv++; argc; argc--, argv++) {
210 /* if looking for endmarker then check before parsing */
211 if (endmarker && strcmp (endmarker, *argv) == 0) {
216 /* treat +thing as an option for C++ */
217 if (endmarker && **argv == '+')
224 endmarker = &argv[0][2];
225 if (endmarker[0] == '\0') endmarker = "--";
228 if (argv[0][2] == '\0') {
232 for (p=argv[0] + 2; *p ; p++)
237 define(argv[0] + 2, &maininclist);
240 if (incp >= includedirs + MAXDIRS)
241 fatalerr("Too many -I flags.\n");
243 if (**(incp-1) == '\0') {
244 *(incp-1) = *(++argv);
249 /* Undef's override all -D's so save them up */
252 undeflist = malloc(sizeof(char *));
254 undeflist = realloc(undeflist,
255 numundefs * sizeof(char *));
256 if (argv[0][2] == '\0') {
260 undeflist[numundefs - 1] = argv[0] + 2;
263 defincdir = argv[0]+2;
265 /* do not use if endmarker processing */
267 if (endmarker) break;
271 if (endmarker) break;
272 if (argv[0][2] == '\0') {
275 width = atoi(argv[0]);
277 width = atoi(argv[0]+2);
280 if (endmarker) break;
281 if (argv[0][2] == '\0') {
286 objsuffix = argv[0]+2;
289 if (endmarker) break;
290 if (argv[0][2] == '\0') {
295 objprefix = argv[0]+2;
298 if (endmarker) break;
302 _debugmask = atoi(argv[0]+2);
306 if (endmarker) break;
308 if (*startat == '\0') {
313 fatalerr("-s flag's value should start %s\n",
317 if (endmarker) break;
318 makefile = argv[0]+2;
319 if (*makefile == '\0') {
320 makefile = *(++argv);
326 warn_multiple = TRUE;
329 /* Ignore -O, -g so we can just pass ${CFLAGS} to
336 if (endmarker) break;
337 /* fatalerr("unknown opt = %s\n", argv[0]); */
338 warning("ignoring option %s\n", argv[0]);
341 /* Now do the undefs from the command line */
342 for (i = 0; i < numundefs; i++)
343 undefine(undeflist[i], &maininclist);
349 if (incp >= includedirs + MAXDIRS)
350 fatalerr("Too many -I flags.\n");
355 char *emxinc = getenv("C_INCLUDE_PATH");
356 /* can have more than one component */
359 beg= (char*)strdup(emxinc);
361 end = (char*)strchr(beg,';');
363 if (incp >= includedirs + MAXDIRS)
364 fatalerr("Too many include dirs\n");
371 #else /* !__EMX__, does not use INCLUDEDIR at all */
372 if (incp >= includedirs + MAXDIRS)
373 fatalerr("Too many -I flags.\n");
374 *incp++ = INCLUDEDIR;
378 if (incp >= includedirs + MAXDIRS)
379 fatalerr("Too many -I flags.\n");
380 *incp++ = POSTINCDIR;
382 } else if (*defincdir) {
383 if (incp >= includedirs + MAXDIRS)
384 fatalerr("Too many -I flags.\n");
388 redirect(startat, makefile);
394 /* should really reset SIGINT to SIG_IGN if it was. */
396 signal (SIGHUP, catch);
398 signal (SIGINT, catch);
400 signal (SIGQUIT, catch);
402 signal (SIGILL, catch);
404 signal (SIGBUS, catch);
406 signal (SIGSEGV, catch);
408 signal (SIGSYS, catch);
411 sig_act.sa_handler = catch;
413 sigemptyset(&sig_act.sa_mask);
414 sigaddset(&sig_act.sa_mask, SIGINT);
415 sigaddset(&sig_act.sa_mask, SIGQUIT);
417 sigaddset(&sig_act.sa_mask, SIGBUS);
419 sigaddset(&sig_act.sa_mask, SIGILL);
420 sigaddset(&sig_act.sa_mask, SIGSEGV);
421 sigaddset(&sig_act.sa_mask, SIGHUP);
422 sigaddset(&sig_act.sa_mask, SIGPIPE);
424 sigaddset(&sig_act.sa_mask, SIGSYS);
427 sig_act.sa_mask = ((1<<(SIGINT -1))
440 #endif /* _POSIX_SOURCE */
441 sig_act.sa_flags = 0;
442 sigaction(SIGHUP, &sig_act, (struct sigaction *)0);
443 sigaction(SIGINT, &sig_act, (struct sigaction *)0);
444 sigaction(SIGQUIT, &sig_act, (struct sigaction *)0);
445 sigaction(SIGILL, &sig_act, (struct sigaction *)0);
447 sigaction(SIGBUS, &sig_act, (struct sigaction *)0);
449 sigaction(SIGSEGV, &sig_act, (struct sigaction *)0);
451 sigaction(SIGSYS, &sig_act, (struct sigaction *)0);
456 * now peruse through the list of files.
458 for(fp=filelist; *fp; fp++) {
459 filecontent = getfile(*fp);
460 ip = newinclude(*fp, (char *)NULL);
462 find_includes(filecontent, ip, ip, 0, FALSE);
463 freefile(filecontent);
464 recursive_pr_include(ip, ip->i_file, base_name(*fp));
474 * eliminate \r chars from file
476 static int elim_cr(char *buf, int sz)
479 for (i= wp = 0; i<sz; i++) {
487 struct filepointer *getfile(file)
491 struct filepointer *content;
494 content = (struct filepointer *)malloc(sizeof(struct filepointer));
495 if ((fd = open(file, O_RDONLY)) < 0) {
496 warning("cannot open \"%s\"\n", file);
497 content->f_p = content->f_base = content->f_end = (char *)malloc(1);
498 *content->f_p = '\0';
502 content->f_base = (char *)malloc(st.st_size+1);
503 if (content->f_base == NULL)
504 fatalerr("cannot allocate mem\n");
505 if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0)
506 fatalerr("failed to read %s\n", file);
508 st.st_size = elim_cr(content->f_base,st.st_size);
511 content->f_len = st.st_size+1;
512 content->f_p = content->f_base;
513 content->f_end = content->f_base + st.st_size;
514 *content->f_end = '\0';
521 struct filepointer *fp;
530 register char *p = (char *)malloc(strlen(str) + 1);
537 register char *str, **list;
541 for (i=0; *list; i++, list++)
542 if (strcmp(str, *list) == 0)
548 * Get the next line. We only return lines beginning with '#' since that
549 * is all this program is ever interested in.
551 char *x_getline(filep)
552 register struct filepointer *filep;
554 register char *p, /* walking pointer */
555 *eof, /* end of file pointer */
556 *bol; /* beginning of line pointer */
557 register int lineno; /* line number */
562 return((char *)NULL);
563 lineno = filep->f_line;
565 for(bol = p--; ++p < eof; ) {
566 if (*p == '/' && *(p+1) == '*') { /* consume comments */
567 *p++ = ' ', *p++ = ' ';
569 if (*p == '*' && *(p+1) == '/') {
570 *p++ = ' ', *p = ' ';
579 #if defined(WIN32) || defined(__EMX__)
580 else if (*p == '/' && *(p+1) == '/') { /* consume comments */
581 *p++ = ' ', *p++ = ' ';
582 while (*p && *p != '\n')
588 else if (*p == '\\') {
589 if (*(p+1) == '\n') {
595 else if (*p == '\n') {
601 /* punt lines with just # (yacc generated) */
603 *cp && (*cp == ' ' || *cp == '\t'); cp++);
613 filep->f_line = lineno;
618 * Strip the file name down to what we want to see in the Makefile.
619 * It will have objprefix and objsuffix around it.
621 char *base_name(file)
627 for(p=file+strlen(file); p>file && *p != '.'; p--) ;
634 #if defined(USG) && !defined(CRAY) && !defined(SVR4) && !defined(__EMX__) && !defined(clipper) && !defined(__clipper__)
635 int rename (from, to)
639 if (link (from, to) == 0) {
649 redirect(line, makefile)
655 char backup[ BUFSIZ ],
657 boolean found = FALSE;
661 * if makefile is "-" then let it pour onto stdout.
663 if (makefile && *makefile == '-' && *(makefile+1) == '\0') {
669 * use a default makefile is not specified.
672 if (stat("Makefile", &st) == 0)
673 makefile = "Makefile";
674 else if (stat("makefile", &st) == 0)
675 makefile = "makefile";
677 fatalerr("[mM]akefile is not present\n");
681 if ((fdin = fopen(makefile, "r")) == NULL)
682 fatalerr("cannot open \"%s\"\n", makefile);
683 sprintf(backup, "%s.bak", makefile);
685 #if defined(WIN32) || defined(__EMX__)
688 if (rename(makefile, backup) < 0)
689 fatalerr("cannot rename %s to %s\n", makefile, backup);
690 #if defined(WIN32) || defined(__EMX__)
691 if ((fdin = fopen(backup, "r")) == NULL)
692 fatalerr("cannot open \"%s\"\n", backup);
694 if ((fdout = freopen(makefile, "w", stdout)) == NULL)
695 fatalerr("cannot open \"%s\"\n", backup);
697 while (!found && fgets(buf, BUFSIZ, fdin)) {
698 if (*buf == '#' && strncmp(line, buf, len) == 0)
704 warning("Adding new delimiting line \"%s\" and dependencies...\n",
706 puts(line); /* same as fputs(fdout); but with newline */
708 while (fgets(buf, BUFSIZ, fdin)) {
713 #if defined(USGISH) || defined(_SEQUENT_) || defined(USE_CHMOD)
714 chmod(makefile, st.st_mode);
716 fchmod(fileno(fdout), st.st_mode);
721 #if NeedVarargsPrototypes
722 fatalerr(char *msg, ...)
725 fatalerr(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
729 #if NeedVarargsPrototypes
732 fprintf(stderr, "%s: error: ", ProgramName);
733 #if NeedVarargsPrototypes
735 vfprintf(stderr, msg, args);
738 fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
744 #if NeedVarargsPrototypes
745 warning(char *msg, ...)
748 warning(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
752 #if NeedVarargsPrototypes
755 fprintf(stderr, "%s: warning: ", ProgramName);
756 #if NeedVarargsPrototypes
758 vfprintf(stderr, msg, args);
761 fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
766 #if NeedVarargsPrototypes
767 warning1(char *msg, ...)
770 warning1(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
774 #if NeedVarargsPrototypes
777 vfprintf(stderr, msg, args);
780 fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);