00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifdef __WIN32__
00031 #pragma warning(disable : 4996)
00032 #endif
00033
00034 #include "def.h"
00035
00036 #ifdef _MSC_VER
00037 #include <io.h>
00038 #else
00039 #include <unistd.h>
00040 #endif
00041 #include <stdio.h>
00042 #include <string.h>
00043
00044 #ifdef hpux
00045 #define sigvec sigvector
00046 #endif
00047
00048 #ifdef X_POSIX_C_SOURCE
00049 #define _POSIX_C_SOURCE X_POSIX_C_SOURCE
00050 #include <signal.h>
00051 #undef _POSIX_C_SOURCE
00052 #else
00053 #if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
00054 #include <signal.h>
00055 #else
00056 #define _POSIX_SOURCE
00057 #include <signal.h>
00058 #undef _POSIX_SOURCE
00059 #endif
00060 #endif
00061
00062 #if NeedVarargsPrototypes
00063 #include <stdarg.h>
00064 #endif
00065
00067
00068 #ifdef MINIX
00069 #define USE_CHMOD 1
00070 #endif
00071
00072 #ifdef DEBUG
00073 int _debugmask;
00074 #endif
00075
00076 char *ProgramName;
00077
00078 const char *directives[] = {
00079 "if",
00080 "ifdef",
00081 "ifndef",
00082 "else",
00083 "endif",
00084 "define",
00085 "undef",
00086 "include",
00087 "line",
00088 "pragma",
00089 "error",
00090 "ident",
00091 "sccs",
00092 "elif",
00093 "eject",
00094 "import",
00095 NULL
00096 };
00097
00098 #define MAKEDEPEND
00099 #include "imakemdep.h"
00100 #undef MAKEDEPEND
00101
00102 struct inclist inc_list[ MAXFILES ], *inclistp = inc_list, maininclist;
00103
00104 char *filelist[ MAXFILES ];
00105 char *includedirs[ MAXDIRS + 1 ];
00106 char *excludedirs[ MAXDIRS + 1 ];
00107 char *notdotdot[ MAXDIRS ];
00108 char *objprefix = (char *)"";
00109 char *objsuffix = (char *)".obj";
00110 char *startat = (char *)"# DO NOT DELETE";
00111 int width = 78;
00112 bool append = false;
00113 bool printed = false;
00114 bool verbose = false;
00115 bool show_where_not = false;
00116 bool warn_multiple = false;
00117
00118 static
00119 #ifdef SIGNALRETURNSINT
00120 int
00121 #else
00122 void
00123 #endif
00124 c_catch(int sig)
00125 {
00126 fflush (stdout);
00127 fatalerr ((char *)"got signal %d\n", sig);
00128 }
00129
00130 #if defined(USG) || (defined(i386) && defined(SYSV)) || defined(WIN32) || defined(__EMX__) || defined(__OS2__)
00131 #define USGISH
00132 #endif
00133
00134 #ifndef USGISH
00135 #ifndef _POSIX_SOURCE
00136 #define sigaction sigvec
00137 #define sa_handler sv_handler
00138 #define sa_mask sv_mask
00139 #define sa_flags sv_flags
00140 #endif
00141 struct sigaction sig_act;
00142 #endif
00143
00144 int main(int argc, char **argv)
00145 {
00146 register char **fp = filelist;
00147 register char **incp = includedirs;
00148 register char **excp = excludedirs;
00149 register char *p;
00150 register struct inclist *ip;
00151 char *makefile = NULL;
00152 struct filepointer *filecontent;
00153 struct symtab *psymp = predefs;
00154 char *endmarker = NULL;
00155 char *defincdir = NULL;
00156
00157 ProgramName = argv[0];
00158
00159 while (psymp->s_name)
00160 {
00161 define2(psymp->s_name, psymp->s_value, &maininclist);
00162 psymp++;
00163 }
00164 if (argc == 2 && argv[1][0] == '@') {
00165 struct stat ast;
00166 int afd;
00167 char *args;
00168 char **nargv;
00169 int nargc;
00170 char quotechar = '\0';
00171
00172 nargc = 1;
00173 if ((afd = open(argv[1]+1, O_RDONLY)) < 0)
00174 fatalerr("cannot open \"%s\"\n", argv[1]+1);
00175 fstat(afd, &ast);
00176 args = (char *)malloc(ast.st_size + 2);
00177 if ((ast.st_size = read(afd, args, ast.st_size)) < 0)
00178 fatalerr("failed to read %s\n", argv[1]+1);
00179 args[ast.st_size] = '\n';
00180 args[ast.st_size + 1] = '\0';
00181 close(afd);
00182 for (p = args; *p; p++) {
00183 if (quotechar) {
00184 if (quotechar == '\\' ||
00185 (*p == quotechar && p[-1] != '\\'))
00186 quotechar = '\0';
00187 continue;
00188 }
00189 switch (*p) {
00190 case '\\':
00191 case '"':
00192 case '\'':
00193 quotechar = *p;
00194 break;
00195 case ' ':
00196 case '\n':
00197 *p = '\0';
00198 if (p > args && p[-1])
00199 nargc++;
00200 break;
00201 }
00202 }
00203 if (p[-1])
00204 nargc++;
00205 nargv = (char **)malloc(nargc * sizeof(char *));
00206 nargv[0] = argv[0];
00207 argc = 1;
00208 for (p = args; argc < nargc; p += strlen(p) + 1)
00209 if (*p) nargv[argc++] = p;
00210 argv = nargv;
00211 }
00212 for(argc--, argv++; argc; argc--, argv++) {
00213
00214 if (endmarker && strcmp (endmarker, *argv) == 0) {
00215 endmarker = NULL;
00216 continue;
00217 }
00218 if (**argv != '-') {
00219
00220 if (endmarker && **argv == '+')
00221 continue;
00222 *fp++ = argv[0];
00223 continue;
00224 }
00225 switch(argv[0][1]) {
00226 case '-':
00227 endmarker = &argv[0][2];
00228 if (endmarker[0] == '\0') endmarker = (char *)"--";
00229 break;
00230 case 'D':
00231 if (argv[0][2] == '\0') {
00232 argv++;
00233 argc--;
00234 }
00235 for (p=argv[0] + 2; *p ; p++)
00236 if (*p == '=') {
00237 *p = ' ';
00238 break;
00239 }
00240 define(argv[0] + 2, &maininclist);
00241 break;
00242 case 'i':
00243 {
00244 char* delim;
00245 char* envinclude;
00246 char* prevdir;
00247 if (endmarker) break;
00248 if (argv[0][2] == '\0') {
00249 argv++;
00250 argc--;
00251 envinclude = getenv(argv[0]);
00252 } else envinclude = getenv(argv[0]+2);
00253 if (!envinclude) break;
00254 prevdir = envinclude;
00255 delim = (char*)strchr(envinclude, ';');
00256 while(delim)
00257 {
00258 if (incp >= includedirs + MAXDIRS) fatalerr("Too many Include directories.\n");
00259 *delim = '\0';
00260 delim++;
00261 *incp++ = prevdir;
00262 prevdir = delim;
00263 delim = (char*)strchr(delim, ';');
00264 }
00265 }
00266 break;
00267 case 'X':
00268
00269
00270 if (excp >= excludedirs + MAXDIRS)
00271 fatalerr("Too many -X flags.\n");
00272 *excp++ = argv[0]+2;
00273 if (**(excp-1) == '\0') {
00274
00275
00276 *(excp-1) = *(argv + 1);
00277 }
00278 if (incp >= includedirs + MAXDIRS)
00279 fatalerr("Too many -I flags via -X.\n");
00280 *incp++ = argv[0]+2;
00281 if (**(incp-1) == '\0') {
00282 *(incp-1) = *(++argv);
00283 argc--;
00284 }
00285 break;
00286 case 'I':
00287 if (incp >= includedirs + MAXDIRS)
00288 fatalerr("Too many -I flags.\n");
00289 *incp++ = argv[0]+2;
00290 if (**(incp-1) == '\0') {
00291 *(incp-1) = *(++argv);
00292 argc--;
00293 }
00294 break;
00295 case 'Y':
00296 defincdir = argv[0]+2;
00297 break;
00298
00299 case 'a':
00300 if (endmarker) break;
00301 append = true;
00302 break;
00303 case 'w':
00304 if (endmarker) break;
00305 if (argv[0][2] == '\0') {
00306 argv++;
00307 argc--;
00308 width = atoi(argv[0]);
00309 } else
00310 width = atoi(argv[0]+2);
00311 break;
00312 case 'o':
00313 if (endmarker) break;
00314 if (argv[0][2] == '\0') {
00315 argv++;
00316 argc--;
00317 objsuffix = argv[0];
00318 } else
00319 objsuffix = argv[0]+2;
00320 break;
00321 case 'p':
00322 if (endmarker) break;
00323 if (argv[0][2] == '\0') {
00324 argv++;
00325 argc--;
00326 objprefix = argv[0];
00327 } else
00328 objprefix = argv[0]+2;
00329 break;
00330 case 'v':
00331 if (endmarker) break;
00332 verbose = true;
00333 #ifdef DEBUG
00334 if (argv[0][2])
00335 _debugmask = atoi(argv[0]+2);
00336 #endif
00337 break;
00338 case 's':
00339 if (endmarker) break;
00340 startat = argv[0]+2;
00341 if (*startat == '\0') {
00342 startat = *(++argv);
00343 argc--;
00344 }
00345 if (*startat != '#')
00346 fatalerr("-s flag's value should start %s\n",
00347 "with '#'.");
00348 break;
00349 case 'f':
00350 if (endmarker) break;
00351 makefile = argv[0]+2;
00352 if (*makefile == '\0') {
00353 makefile = *(++argv);
00354 argc--;
00355 }
00356 break;
00357 case 'm':
00358 warn_multiple = true;
00359 break;
00360
00361
00362
00363
00364 case 'O':
00365 case 'g':
00366 break;
00367 default:
00368 if (endmarker) break;
00369
00370 warning("ignoring option %s\n", argv[0]);
00371 }
00372 }
00373
00374 if (!defincdir) {
00375 #ifdef PREINCDIR
00376 if (incp >= includedirs + MAXDIRS)
00377 fatalerr("Too many -I flags.\n");
00378 *incp++ = PREINCDIR;
00379 #endif
00380 #ifdef INCLUDEDIR
00381 if (incp >= includedirs + MAXDIRS)
00382 fatalerr("Too many -I flags.\n");
00383 *incp++ = INCLUDEDIR;
00384 #endif
00385 #ifdef POSTINCDIR
00386 if (incp >= includedirs + MAXDIRS)
00387 fatalerr("Too many -I flags.\n");
00388 *incp++ = POSTINCDIR;
00389 #endif
00390 } else if (*defincdir) {
00391 if (incp >= includedirs + MAXDIRS)
00392 fatalerr("Too many -I flags.\n");
00393 *incp++ = defincdir;
00394 }
00395
00396 redirect(startat, makefile);
00397
00398
00399
00400
00401 #ifdef USGISH
00402
00403 #ifdef SIGHUP
00404 signal (SIGHUP, c_catch);
00405 #endif
00406 signal (SIGINT, c_catch);
00407 #ifdef SIGQUIT
00408 signal (SIGQUIT, c_catch);
00409 #endif
00410 signal (SIGILL, c_catch);
00411 #ifdef SIGBUS
00412 signal (SIGBUS, c_catch);
00413 #endif
00414 signal (SIGSEGV, c_catch);
00415 #ifdef SIGSYS
00416 signal (SIGSYS, c_catch);
00417 #endif
00418 #else
00419 sig_act.sa_handler = c_catch;
00420 #ifdef _POSIX_SOURCE
00421 sigemptyset(&sig_act.sa_mask);
00422 sigaddset(&sig_act.sa_mask, SIGINT);
00423 sigaddset(&sig_act.sa_mask, SIGQUIT);
00424 #ifdef SIGBUS
00425 sigaddset(&sig_act.sa_mask, SIGBUS);
00426 #endif
00427 sigaddset(&sig_act.sa_mask, SIGILL);
00428 sigaddset(&sig_act.sa_mask, SIGSEGV);
00429 sigaddset(&sig_act.sa_mask, SIGHUP);
00430 sigaddset(&sig_act.sa_mask, SIGPIPE);
00431 #ifdef SIGSYS
00432 sigaddset(&sig_act.sa_mask, SIGSYS);
00433 #endif
00434 #else
00435 sig_act.sa_mask = ((1<<(SIGINT -1))
00436 |(1<<(SIGQUIT-1))
00437 #ifdef SIGBUS
00438 |(1<<(SIGBUS-1))
00439 #endif
00440 |(1<<(SIGILL-1))
00441 |(1<<(SIGSEGV-1))
00442 |(1<<(SIGHUP-1))
00443 |(1<<(SIGPIPE-1))
00444 #ifdef SIGSYS
00445 |(1<<(SIGSYS-1))
00446 #endif
00447 );
00448 #endif
00449 sig_act.sa_flags = 0;
00450 sigaction(SIGHUP, &sig_act, (struct sigaction *)0);
00451 sigaction(SIGINT, &sig_act, (struct sigaction *)0);
00452 sigaction(SIGQUIT, &sig_act, (struct sigaction *)0);
00453 sigaction(SIGILL, &sig_act, (struct sigaction *)0);
00454 #ifdef SIGBUS
00455 sigaction(SIGBUS, &sig_act, (struct sigaction *)0);
00456 #endif
00457 sigaction(SIGSEGV, &sig_act, (struct sigaction *)0);
00458 #ifdef SIGSYS
00459 sigaction(SIGSYS, &sig_act, (struct sigaction *)0);
00460 #endif
00461 #endif
00462
00463
00464
00465
00466 for(fp=filelist; *fp; fp++) {
00467 filecontent = getfile(*fp);
00468 ip = newinclude(*fp, (char *)NULL);
00469
00470 find_includes(filecontent, ip, ip, 0, false);
00471 freefile(filecontent);
00472 recursive_pr_include(ip, ip->i_file, base_name(*fp));
00473 inc_clean();
00474 }
00475 if (printed)
00476 printf("\n");
00477
00478 return 0;
00479 }
00480
00481 struct filepointer *getfile(char *file)
00482 {
00483 register int fd;
00484 struct filepointer *content;
00485 struct stat st;
00486
00487 content = (struct filepointer *)malloc(sizeof(struct filepointer));
00488 content->f_name = strdup(file);
00489 if ((fd = open(file, O_RDONLY)) < 0) {
00490 warning("cannot open \"%s\"\n", file);
00491 content->f_p = content->f_base = content->f_end = (char *)malloc(1);
00492 *content->f_p = '\0';
00493 return(content);
00494 }
00495 fstat(fd, &st);
00496 content->f_base = (char *)malloc(st.st_size+1);
00497 if (content->f_base == NULL)
00498 fatalerr("cannot allocate mem\n");
00499 if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0)
00500 fatalerr("failed to read %s\n", file);
00501 close(fd);
00502 content->f_len = st.st_size+1;
00503 content->f_p = content->f_base;
00504 content->f_end = content->f_base + st.st_size;
00505 *content->f_end = '\0';
00506 content->f_line = 0;
00507 return(content);
00508 }
00509
00510 void freefile(struct filepointer *fp)
00511 {
00512 free(fp->f_name);
00513 free(fp->f_base);
00514 free(fp);
00515 }
00516
00517 char *copy(register char *str)
00518 {
00519 register char *p = (char *)malloc(strlen(str) + 1);
00520
00521 strcpy(p, str);
00522 return(p);
00523 }
00524
00525 int match(register const char *str, register const char **list)
00526 {
00527 register int i;
00528
00529 for (i=0; *list; i++, list++)
00530 if (strcmp(str, *list) == 0)
00531 return i;
00532 return -1;
00533 }
00534
00535
00536
00537
00538
00539 char *getline(register struct filepointer *filep)
00540 {
00541 register char *p,
00542 *eof,
00543 *bol;
00544 register int lineno;
00545
00546 eof = filep->f_end;
00548 lineno = filep->f_line;
00549 bol = filep->f_p;
00550
00551
00552
00553
00554 for (p = filep->f_p; p < eof; p++) {
00555 if (bol > p) fatalerr("somehow bol got ahead of p.");
00556 if (*p == '/' && *(p+1) == '*') {
00557
00558 *p++ = ' '; *p++ = ' ';
00559 while (p < eof) {
00560 if (*p == '*' && *(p+1) == '/') {
00561 *p++ = ' '; *p = ' ';
00562
00563 break;
00564 } else if (*p == '\n') lineno++;
00565 p++;
00566 }
00567 continue;
00568 } else if (*p == '/' && *(p+1) == '/') {
00569
00570 *p++ = ' '; *p++ = ' ';
00571 while (p < eof && (*p != '\n') ) *p++ = ' ';
00572
00574 p--;
00575 continue;
00576 } else if (*p == '\\') {
00577
00578 if (*(p+1) == '\n') {
00579
00580 *p = ' ';
00581 *(p+1) = ' ';
00582 lineno++;
00583 }
00584 } else if (*p == '\n') {
00585
00586 lineno++;
00587 *p = '\0';
00588 if (bol < p) {
00589
00590
00591 while ( (bol < p) && ((*bol == ' ') || (*bol == '\t')) ) bol++;
00594 if (*bol == '#') {
00595 register char *cp;
00596
00597 for (cp = bol+1; *cp && (*cp == ' ' || *cp == '\t'); cp++);
00598 if (*cp) { p++; goto done; }
00599 }
00600 }
00601
00602 bol = p+1;
00603 }
00604 }
00605 if (*bol != '#') bol = NULL;
00606 done:
00607 filep->f_p = p;
00608 filep->f_line = lineno;
00609 return bol;
00610 }
00611
00612
00613
00614
00615
00616 char *base_name(register char *file)
00617 {
00618 register char *p;
00619
00620 file = copy(file);
00621 for(p=file+strlen(file); p>file && *p != '.'; p--) ;
00622
00623 if (*p == '.')
00624 *p = '\0';
00625 return(file);
00626 }
00627
00628 #if defined(USG) && !defined(CRAY) && !defined(SVR4) && !defined(__EMX__)
00629 int rename(char *from, char *to)
00630 {
00631 (void) unlink (to);
00632 if (link (from, to) == 0) {
00633 unlink (from);
00634 return 0;
00635 } else {
00636 return -1;
00637 }
00638 }
00639 #endif
00640
00641 void redirect(char *line, char *makefile)
00642 {
00643 struct stat st;
00644 FILE *fdin, *fdout;
00645 char backup[ BUFSIZ ],
00646 buf[ BUFSIZ ];
00647 bool found = false;
00648 int len;
00649
00650
00651
00652
00653 if (makefile && *makefile == '-' && *(makefile+1) == '\0')
00654 return;
00655
00656
00657
00658
00659 if (!makefile) {
00660 if (stat("Makefile", &st) == 0)
00661 makefile = (char *)"Makefile";
00662 else if (stat("makefile", &st) == 0)
00663 makefile = (char *)"makefile";
00664 else
00665 fatalerr("[mM]akefile is not present\n");
00666 }
00667 else
00668 stat(makefile, &st);
00669 if ((fdin = fopen(makefile, "r")) == NULL)
00670 fatalerr("cannot open \"%s\"\n", makefile);
00671 sprintf(backup, "%s.bak", makefile);
00672 unlink(backup);
00673 #if defined(WIN32) || defined(__EMX__) || defined(__OS2__)
00674 fclose(fdin);
00675 #endif
00676 if (rename(makefile, backup) < 0)
00677 fatalerr("cannot rename %s to %s\n", makefile, backup);
00678 #if defined(WIN32) || defined(__EMX__) || defined(__OS2__)
00679 if ((fdin = fopen(backup, "r")) == NULL)
00680 fatalerr("cannot open \"%s\"\n", backup);
00681 #endif
00682 if ((fdout = freopen(makefile, "w", stdout)) == NULL)
00683 fatalerr("cannot open \"%s\"\n", backup);
00684 len = int(strlen(line));
00685 while (!found && fgets(buf, BUFSIZ, fdin)) {
00686 if (*buf == '#' && strncmp(line, buf, len) == 0)
00687 found = true;
00688 fputs(buf, fdout);
00689 }
00690 if (!found) {
00691 if (verbose)
00692 warning("Adding new delimiting line \"%s\" and dependencies...\n",
00693 line);
00694 puts(line);
00695 } else if (append) {
00696 while (fgets(buf, BUFSIZ, fdin)) {
00697 fputs(buf, fdout);
00698 }
00699 }
00700 fflush(fdout);
00701 #if defined(USGISH) || defined(_SEQUENT_) || defined(USE_CHMOD)
00702 chmod(makefile, st.st_mode);
00703 #else
00704 fchmod(fileno(fdout), st.st_mode);
00705 #endif
00706 }
00707
00708 #if NeedVarargsPrototypes
00709 void fatalerr(const char *msg, ...)
00710 #else
00711
00712 void fatalerr(char *msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
00713 #endif
00714 {
00715 #if NeedVarargsPrototypes
00716 va_list args;
00717 #endif
00718 fprintf(stderr, "%s: error: ", ProgramName);
00719 #if NeedVarargsPrototypes
00720 va_start(args, msg);
00721 vfprintf(stderr, msg, args);
00722 va_end(args);
00723 #else
00724 fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
00725 #endif
00726 exit (1);
00727 }
00728
00729 #if NeedVarargsPrototypes
00730 void warning(const char *msg, ...)
00731 #else
00732
00733 void warning(const char *msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
00734 #endif
00735 {
00736 #if NeedVarargsPrototypes
00737 va_list args;
00738 #endif
00739 fprintf(stderr, "%s: warning: ", ProgramName);
00740 #if NeedVarargsPrototypes
00741 va_start(args, msg);
00742 vfprintf(stderr, msg, args);
00743 va_end(args);
00744 #else
00745 fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
00746 #endif
00747 }
00748
00749 #if NeedVarargsPrototypes
00750 void warning1(const char *msg, ...)
00751 #else
00752
00753 void warning1(const char *msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
00754 #endif
00755 {
00756 #if NeedVarargsPrototypes
00757 va_list args;
00758 va_start(args, msg);
00759 vfprintf(stderr, msg, args);
00760 va_end(args);
00761 #else
00762 fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
00763 #endif
00764 }