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