You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.c 12KB

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