home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / util / makedepend / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-25  |  10.9 KB  |  540 lines

  1. /*
  2.  * $XConsortium: main.c,v 1.56 91/07/25 11:50:59 rws Exp $
  3.  */
  4. #include "def.h"
  5. #ifdef hpux
  6. #define sigvec sigvector
  7. #endif /* hpux */
  8.  
  9. #ifndef X_NOT_POSIX
  10. #ifndef _POSIX_SOURCE
  11. #define _POSIX_SOURCE
  12. #endif
  13. #endif
  14. #include <signal.h>
  15.  
  16. #ifdef DEBUG
  17. int    _debugmask;
  18. #endif
  19.  
  20. char *ProgramName;
  21.  
  22. char    *directives[] = {
  23.     "if",
  24.     "ifdef",
  25.     "ifndef",
  26.     "else",
  27.     "endif",
  28.     "define",
  29.     "undef",
  30.     "include",
  31.     "line",
  32.     "pragma",
  33.     "error",
  34.     "ident",
  35.     "sccs",
  36.     "elif",
  37.     "eject",
  38.     NULL
  39. };
  40.  
  41. #define MAKEDEPEND
  42. #include "imakemdep.h"    /* from config sources */
  43. #undef MAKEDEPEND
  44.  
  45. struct symtab    deflist[ MAXDEFINES ];
  46. struct    inclist inclist[ MAXFILES ],
  47.         *inclistp = inclist;
  48.  
  49. char    *filelist[ MAXFILES ];
  50. char    *includedirs[ MAXDIRS ];
  51. char    *notdotdot[ MAXDIRS ];
  52. char    *objprefix = "";
  53. char    *objsuffix = ".o";
  54. char    *startat = "# DO NOT DELETE THIS LINE -- make depend depends on it.";
  55. int    width = 78;
  56. boolean    append = FALSE;
  57. boolean    printed = FALSE;
  58. boolean    verbose = FALSE;
  59. boolean    show_where_not = FALSE;
  60.  
  61. static
  62. #ifdef SIGNALRETURNSINT
  63. int
  64. #else
  65. void
  66. #endif
  67. catch (sig)
  68.     int sig;
  69. {
  70.     fflush (stdout);
  71.     fatal ("got signal %d\n", sig);
  72. }
  73.  
  74. #if defined(USG) || (defined(SYSV386) && defined(SYSV))
  75. #define USGISH
  76. #endif
  77.  
  78. #ifndef USGISH
  79. #ifndef _POSIX_SOURCE
  80. #define sigaction sigvec
  81. #define sa_handler sv_handler
  82. #define sa_mask sv_mask
  83. #define sa_flags sv_flags
  84. #endif
  85. struct sigaction sig_act;
  86. #endif /* USGISH */
  87.  
  88. main(argc, argv)
  89.     int    argc;
  90.     char    **argv;
  91. {
  92.     register struct symtab    *symp = deflist;
  93.     register char    **fp = filelist;
  94.     register char    **incp = includedirs;
  95.     register char    *p;
  96.     register struct inclist    *ip;
  97.     char    *makefile = NULL;
  98.     struct filepointer    *filecontent;
  99.     struct symtab *psymp = predefs;
  100.     char *endmarker = NULL;
  101.  
  102.     ProgramName = argv[0];
  103.  
  104.     while (psymp->s_name)
  105.         *symp++ = *psymp++;
  106.     for(argc--, argv++; argc; argc--, argv++) {
  107.             /* if looking for endmarker then check before parsing */
  108.         if (endmarker && strcmp (endmarker, *argv) == 0) {
  109.             endmarker = NULL;
  110.             continue;
  111.         }
  112.         if (**argv != '-') {
  113.             /* treat +thing as an option for C++ */
  114.             if (endmarker && **argv == '+')
  115.                 continue;
  116.             *fp++ = argv[0];
  117.             continue;
  118.         }
  119.         switch(argv[0][1]) {
  120.         case '-':
  121.             endmarker = &argv[0][2];
  122.             if (endmarker[0] == '\0') endmarker = "--";
  123.             break;
  124.         case 'D':
  125.             symp->s_name = argv[0]+2;
  126.             if (*symp->s_name == '\0') {
  127.                 symp->s_name = *(++argv);
  128.                 argc--;
  129.             }
  130.             for (p=symp->s_name; *p ; p++)
  131.                 if (*p == '=') {
  132.                     *p++ = '\0';
  133.                     break;
  134.                 }
  135.             symp->s_value = p;
  136.             symp++;
  137.             break;
  138.         case 'I':
  139.             if (incp >= includedirs + MAXDIRS)
  140.                 fatal("Too many -I flags.\n");
  141.             *incp++ = argv[0]+2;
  142.             if (**(incp-1) == '\0') {
  143.                 *(incp-1) = *(++argv);
  144.                 argc--;
  145.             }
  146.             break;
  147.         /* do not use if endmarker processing */
  148.         case 'a':
  149.             if (endmarker) break;
  150.             append = TRUE;
  151.             break;
  152.         case 'w':
  153.             if (endmarker) break;
  154.             if (argv[0][2] == '\0') {
  155.                 argv++;
  156.                 argc--;
  157.                 width = atoi(argv[0]);
  158.             } else
  159.                 width = atoi(argv[0]+2);
  160.             break;
  161.         case 'o':
  162.             if (endmarker) break;
  163.             if (argv[0][2] == '\0') {
  164.                 argv++;
  165.                 argc--;
  166.                 objsuffix = argv[0];
  167.             } else
  168.                 objsuffix = argv[0]+2;
  169.             break;
  170.         case 'p':
  171.             if (endmarker) break;
  172.             if (argv[0][2] == '\0') {
  173.                 argv++;
  174.                 argc--;
  175.                 objprefix = argv[0];
  176.             } else
  177.                 objprefix = argv[0]+2;
  178.             break;
  179.         case 'v':
  180.             if (endmarker) break;
  181.             verbose = TRUE;
  182. #ifdef DEBUG
  183.             if (argv[0][2])
  184.                 _debugmask = atoi(argv[0]+2);
  185. #endif
  186.             break;
  187.         case 's':
  188.             if (endmarker) break;
  189.             startat = argv[0]+2;
  190.             if (*startat == '\0') {
  191.                 startat = *(++argv);
  192.                 argc--;
  193.             }
  194.             if (*startat != '#')
  195.                 fatal("-s flag's value should start %s\n",
  196.                     "with '#'.");
  197.             break;
  198.         case 'f':
  199.             if (endmarker) break;
  200.             makefile = argv[0]+2;
  201.             if (*makefile == '\0') {
  202.                 makefile = *(++argv);
  203.                 argc--;
  204.             }
  205.             break;
  206.         
  207.         /* Ignore -O, -g so we can just pass ${CFLAGS} to
  208.            makedepend
  209.          */
  210.         case 'O':
  211.         case 'g':
  212.             break;
  213.         default:
  214.             if (endmarker) break;
  215.     /*        fatal("unknown opt = %s\n", argv[0]); */
  216.             warning("ignoring option %s\n", argv[0]);
  217.         }
  218.     }
  219. #ifdef __GNUC__
  220.     if (incp >= includedirs + MAXDIRS)
  221.         fatal("Too many -I flags.\n");
  222. #ifdef luna88k
  223.     *incp++ = "/usr/local/lib/gcc/gcc-include";
  224. #else
  225.     *incp++ = "/usr/local/lib/gcc-include";
  226. #endif
  227. #else
  228. #ifdef luna88k
  229.     if (incp >= includedirs + MAXDIRS)
  230.         fatal("Too many -I flags.\n");
  231.     *incp++ = "/usr/lib/ccom/include";
  232. #endif
  233. #endif
  234.     if (incp >= includedirs + MAXDIRS)
  235.         fatal("Too many -I flags.\n");
  236.     *incp++ = INCLUDEDIR;
  237. #ifdef CRAY
  238.     if (incp >= includedirs + MAXDIRS)
  239.         fatal("Too many -I flags.\n");
  240.     *incp++ = "/usr/include/stdc";
  241. #endif
  242. #ifdef Mips
  243. # ifdef BSD43
  244.     if (incp >= includedirs + MAXDIRS)
  245.         fatal("Too many -I flags.\n");
  246.     *incp++ = "/usr/include/bsd43";
  247. # endif
  248. #endif
  249.  
  250.     redirect(startat, makefile);
  251.  
  252.     /*
  253.      * catch signals.
  254.      */
  255. #ifdef USGISH
  256. /*  should really reset SIGINT to SIG_IGN if it was.  */
  257.     signal (SIGHUP, catch);
  258.     signal (SIGINT, catch);
  259.     signal (SIGQUIT, catch);
  260.     signal (SIGILL, catch);
  261.     signal (SIGBUS, catch);
  262.     signal (SIGSEGV, catch);
  263.     signal (SIGSYS, catch);
  264. #else
  265.     sig_act.sa_handler = catch;
  266. #ifdef _POSIX_SOURCE
  267.     sigemptyset(&sig_act.sa_mask);
  268.     sigaddset(&sig_act.sa_mask, SIGINT);
  269.     sigaddset(&sig_act.sa_mask, SIGQUIT);
  270.     sigaddset(&sig_act.sa_mask, SIGBUS);
  271.     sigaddset(&sig_act.sa_mask, SIGILL);
  272.     sigaddset(&sig_act.sa_mask, SIGSEGV);
  273.     sigaddset(&sig_act.sa_mask, SIGHUP);
  274.     sigaddset(&sig_act.sa_mask, SIGPIPE);
  275.     sigaddset(&sig_act.sa_mask, SIGSYS);
  276. #else
  277.     sig_act.sa_mask = ((1<<(SIGINT -1))
  278.                |(1<<(SIGQUIT-1))
  279.                |(1<<(SIGBUS-1))
  280.                |(1<<(SIGILL-1))
  281.                |(1<<(SIGSEGV-1))
  282.                |(1<<(SIGHUP-1))
  283.                |(1<<(SIGPIPE-1))
  284.                |(1<<(SIGSYS-1)));
  285. #endif /* _POSIX_SOURCE */
  286.     sig_act.sa_flags = 0;
  287.     sigaction(SIGHUP, &sig_act, (struct sigaction *)0);
  288.     sigaction(SIGINT, &sig_act, (struct sigaction *)0);
  289.     sigaction(SIGQUIT, &sig_act, (struct sigaction *)0);
  290.     sigaction(SIGILL, &sig_act, (struct sigaction *)0);
  291.     sigaction(SIGBUS, &sig_act, (struct sigaction *)0);
  292.     sigaction(SIGSEGV, &sig_act, (struct sigaction *)0);
  293.     sigaction(SIGSYS, &sig_act, (struct sigaction *)0);
  294. #endif /* USGISH */
  295.  
  296.     /*
  297.      * now peruse through the list of files.
  298.      */
  299.     for(fp=filelist; *fp; fp++) {
  300.         filecontent = getfile(*fp);
  301.         ip = newinclude(*fp, (char *)NULL);
  302.  
  303.         find_includes(filecontent, ip, ip, 0, FALSE);
  304.         freefile(filecontent);
  305.         recursive_pr_include(ip, ip->i_file, basename(*fp));
  306.         inc_clean();
  307.     }
  308.     if (printed)
  309.         printf("\n");
  310.     exit(0);
  311. }
  312.  
  313. struct filepointer *getfile(file)
  314.     char    *file;
  315. {
  316.     register int    fd;
  317.     struct filepointer    *content;
  318.     struct stat    st;
  319.  
  320.     content = (struct filepointer *)malloc(sizeof(struct filepointer));
  321.     if ((fd = open(file, O_RDONLY)) < 0) {
  322.         warning("cannot open \"%s\"\n", file);
  323.         content->f_p = content->f_base = content->f_end = malloc(1);
  324.         *content->f_p = '\0';
  325.         return(content);
  326.     }
  327.     fstat(fd, &st);
  328.     content->f_len = st.st_size+1;
  329.     content->f_base = malloc(content->f_len);
  330.     if (content->f_base == NULL)
  331.         fatal("cannot allocate mem\n");
  332.     if (read(fd, content->f_base, st.st_size) != st.st_size)
  333.         fatal("cannot read all of %s\n", file);
  334.     close(fd);
  335.     content->f_p = content->f_base;
  336.     content->f_end = content->f_base + st.st_size;
  337.     *content->f_end = '\0';
  338.     content->f_line = 0;
  339.     return(content);
  340. }
  341.  
  342. freefile(fp)
  343.     struct filepointer    *fp;
  344. {
  345.     free(fp->f_base);
  346.     free(fp);
  347. }
  348.  
  349. char *copy(str)
  350.     register char    *str;
  351. {
  352.     register char    *p = malloc(strlen(str) + 1);
  353.  
  354.     strcpy(p, str);
  355.     return(p);
  356. }
  357.  
  358. match(str, list)
  359.     register char    *str, **list;
  360. {
  361.     register int    i;
  362.  
  363.     for (i=0; *list; i++, list++)
  364.         if (strcmp(str, *list) == 0)
  365.             return(i);
  366.     return(-1);
  367. }
  368.  
  369. /*
  370.  * Get the next line.  We only return lines beginning with '#' since that
  371.  * is all this program is ever interested in.
  372.  */
  373. char *getline(filep)
  374.     register struct filepointer    *filep;
  375. {
  376.     register char    *p,    /* walking pointer */
  377.             *eof,    /* end of file pointer */
  378.             *bol;    /* beginning of line pointer */
  379.     register    lineno;    /* line number */
  380.  
  381.     p = filep->f_p;
  382.     eof = filep->f_end;
  383.     if (p >= eof)
  384.         return((char *)NULL);
  385.     lineno = filep->f_line;
  386.  
  387.     for(bol = p--; ++p < eof; ) {
  388.         if (*p == '/' && *(p+1) == '*') { /* consume comments */
  389.             *p++ = ' ', *p++ = ' ';
  390.             while (*p) {
  391.                 if (*p == '*' && *(p+1) == '/') {
  392.                     *p++ = ' ', *p = ' ';
  393.                     break;
  394.                 }
  395.                 else if (*p == '\n')
  396.                     lineno++;
  397.                 *p++ = ' ';
  398.             }
  399.             continue;
  400.         }
  401.         else if (*p == '\n') {
  402.             lineno++;
  403.             if (*bol == '#') {
  404.                 register char *cp;
  405.  
  406.                 *p++ = '\0';
  407.                 /* punt lines with just # (yacc generated) */
  408.                 for (cp = bol+1; 
  409.                      *cp && (*cp == ' ' || *cp == '\t'); cp++);
  410.                 if (*cp) goto done;
  411.             }
  412.             bol = p+1;
  413.         }
  414.     }
  415.     if (*bol != '#')
  416.         bol = NULL;
  417. done:
  418.     filep->f_p = p;
  419.     filep->f_line = lineno;
  420.     return(bol);
  421. }
  422.  
  423. char *basename(file)
  424.     register char    *file;
  425. {
  426.     register char    *p;
  427.  
  428.     for (p=file+strlen(file); p>file && *p != '/'; p--) ;
  429.  
  430.     if (*p == '/')
  431.         p++;
  432.  
  433.     file = copy(p);
  434.     for(p=file+strlen(file); p>file && *p != '.'; p--) ;
  435.  
  436.     if (*p == '.')
  437.         *p = '\0';
  438.     return(file);
  439. }
  440.  
  441. #if defined(USG) && !defined(CRAY) && !defined(SVR4)
  442. int rename (from, to)
  443.     char *from, *to;
  444. {
  445.     (void) unlink (to);
  446.     if (link (from, to) == 0) {
  447.     unlink (from);
  448.     return 0;
  449.     } else {
  450.     return -1;
  451.     }
  452. }
  453. #endif /* USGISH */
  454.  
  455. redirect(line, makefile)
  456.     char    *line,
  457.         *makefile;
  458. {
  459.     struct stat    st;
  460.     FILE    *fdin, *fdout;
  461.     char    backup[ BUFSIZ ],
  462.         buf[ BUFSIZ ];
  463.     boolean    found = FALSE;
  464.     int    len;
  465.  
  466.     /*
  467.      * if makefile is "-" then let it pour onto stdout.
  468.      */
  469.     if (makefile && *makefile == '-' && *(makefile+1) == '\0')
  470.         return;
  471.  
  472.     /*
  473.      * use a default makefile is not specified.
  474.      */
  475.     if (!makefile) {
  476.         if (stat("makefile", &st) == 0)
  477.             makefile = "makefile";
  478.         else if (stat("Makefile", &st) == 0)
  479.             makefile = "Makefile";
  480.         else
  481.             fatal("[mM]akefile is not present\n");
  482.     }
  483.     else
  484.         stat(makefile, &st);
  485.     if ((fdin = fopen(makefile, "r")) == NULL)
  486.         fatal("cannot open \"%s\"\n", makefile);
  487.     sprintf(backup, "%s.bak", makefile);
  488.     unlink(backup);
  489.     if (rename(makefile, backup) < 0)
  490.         fatal("cannot rename %s to %s\n", makefile, backup);
  491.     if ((fdout = freopen(makefile, "w", stdout)) == NULL)
  492.         fatal("cannot open \"%s\"\n", backup);
  493.     len = strlen(line);
  494.     while (!found && fgets(buf, BUFSIZ, fdin)) {
  495.         if (*buf == '#' && strncmp(line, buf, len) == 0)
  496.             found = TRUE;
  497.         fputs(buf, fdout);
  498.     }
  499.     if (!found) {
  500.         if (verbose)
  501.         warning("Adding new delimiting line \"%s\" and dependencies...\n",
  502.             line);
  503.         puts(line); /* same as fputs(fdout); but with newline */
  504.     } else if (append) {
  505.         while (fgets(buf, BUFSIZ, fdin)) {
  506.         fputs(buf, fdout);
  507.         }
  508.     }
  509.     fflush(fdout);
  510. #ifdef USGISH
  511.     chmod(makefile, st.st_mode);
  512. #else
  513.         fchmod(fileno(fdout), st.st_mode);
  514. #endif /* USGISH */
  515. }
  516.  
  517. /*VARARGS*/
  518. fatal(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
  519.     char *x0;
  520. {
  521.     fprintf(stderr, "%s: error:  ", ProgramName);
  522.     fprintf(stderr, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
  523.     exit (1);
  524. }
  525.  
  526. /*VARARGS0*/
  527. warning(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
  528.     char *x0;
  529. {
  530.     fprintf(stderr, "%s: warning:  ", ProgramName);
  531.     fprintf(stderr, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
  532. }
  533.  
  534. /*VARARGS0*/
  535. warning1(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
  536.     char *x0;
  537. {
  538.     fprintf(stderr, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
  539. }
  540.