|
|
1.1 root 1: /*
2: * $Header: main.c,v 1.6 87/08/14 17:59:51 toddb Exp $
3: *
4: * $Log: main.c,v $
5: * Revision 1.6 87/08/14 17:59:51 toddb
6: * Added call to inc_clean() after traversing graph.
7: *
8: * Revision 1.5 87/06/29 16:16:50 toddb
9: * One too few bytes allocated.
10: *
11: * Revision 1.4 87/06/29 16:13:18 toddb
12: * Initial revision.
13: *
14: * Revision 1.4 87/04/28 19:04:06 karlton
15: * make sure makefile has contents before dereferencing
16: *
17: * Revision 1.3 87/04/09 17:25:30 karlton
18: * restore stat of Makefile
19: *
20: * Revision 1.2 87/04/09 13:45:24 rich
21: * added code to ignore unknown options.
22: *
23: * Revision 1.1 87/04/08 16:40:48 rich
24: * Initial revision
25: *
26: * Revision 1.2 86/04/18 14:07:07 toddb
27: * main() now initializes the delimiter message in the makefile if
28: * one does not exist.
29: *
30: * Revision 1.1 86/04/15 08:34:35 toddb
31: * Initial revision
32: *
33: */
34: #include "def.h"
35: #include <sys/signal.h>
36:
37: #ifdef DEBUG
38: int debug;
39: #endif DEBUG
40:
41: char *directives[] = {
42: "if",
43: "ifdef",
44: "ifndef",
45: "else",
46: "endif",
47: "define",
48: "undef",
49: "include",
50: "line",
51: NULL
52: };
53:
54: struct symtab deflist[ MAXDEFINES ];
55: struct inclist inclist[ MAXFILES ],
56: *inclistp = inclist;
57:
58: char *filelist[ MAXFILES ];
59: char *includedirs[ MAXDIRS ];
60: char *notdotdot[ MAXDIRS ];
61: char *objfile = ".o";
62: char *startat = "# DO NOT DELETE THIS LINE -- make depend depends on it.";
63: int width = 78;
64: boolean printed = FALSE;
65: boolean verbose = FALSE;
66: boolean show_where_not = FALSE;
67: int catch();
68:
69: struct sigvec sig_vec = {
70: catch,
71: (1<<(SIGINT -1))
72: |(1<<(SIGQUIT-1))
73: |(1<<(SIGBUS-1))
74: |(1<<(SIGILL-1))
75: |(1<<(SIGSEGV-1))
76: |(1<<(SIGHUP-1))
77: |(1<<(SIGPIPE-1))
78: |(1<<(SIGSYS-1)),
79: 0
80: };
81:
82: main(argc, argv)
83: int argc;
84: char **argv;
85: {
86: register struct symtab *symp = deflist;
87: register char **fp = filelist;
88: register char **incp = includedirs;
89: register char *p;
90: register int i;
91: register struct inclist *ip;
92: char *makefile = NULL;
93: struct filepointer *filecontent;
94:
95: for(argc--, argv++; argc; argc--, argv++) {
96: if (**argv != '-') {
97: *fp++ = argv[0];
98: continue;
99: }
100: switch(argv[0][1]) {
101: case 'D':
102: symp->s_name = argv[0]+2;
103: if (*symp->s_name == '\0') {
104: symp->s_name = *(++argv);
105: argc--;
106: }
107: for (p=symp->s_name; *p ; p++)
108: if (*p == '=') {
109: *p++ = '\0';
110: break;
111: }
112: symp->s_value = p;
113: symp++;
114: break;
115: case 'I':
116: *incp++ = argv[0]+2;
117: if (**(incp-1) == '\0') {
118: *(incp-1) = *(++argv);
119: argc--;
120: }
121: break;
122: case 'w':
123: if (argv[0][2] == '\0') {
124: argv++;
125: argc--;
126: width = atoi(argv[0]);
127: } else
128: width = atoi(argv[0]+2);
129: break;
130: case 'o':
131: if (argv[0][2] == '\0') {
132: argv++;
133: argc--;
134: objfile = argv[0];
135: } else
136: objfile = argv[0]+2;
137: break;
138: case 'v':
139: verbose = TRUE;
140: #ifdef DEBUG
141: if (argv[0][2])
142: debug = atoi(argv[0]+2);
143: #endif DEBUG
144: break;
145: case 's':
146: startat = argv[0]+2;
147: if (*startat == '\0') {
148: startat = *(++argv);
149: argc--;
150: }
151: if (*startat != '#')
152: log_fatal("-s flag's value should start %s\n",
153: "with '#'.");
154: break;
155: case 'f':
156: makefile = argv[0]+2;
157: if (*makefile == '\0') {
158: makefile = *(++argv);
159: argc--;
160: }
161: break;
162: default:
163: /* log_fatal("unknown opt = %s\n", argv[0]); */
164: log("ignoring option %s\n", argv[0]);
165: }
166: }
167: *incp++ = INCLUDEDIR;
168:
169: redirect(startat, makefile);
170:
171: /*
172: * catch signals.
173: */
174: sigvec(SIGHUP, &sig_vec, (struct sigvec *)0);
175: sigvec(SIGINT, &sig_vec, (struct sigvec *)0);
176: sigvec(SIGQUIT, &sig_vec, (struct sigvec *)0);
177: sigvec(SIGILL, &sig_vec, (struct sigvec *)0);
178: sigvec(SIGBUS, &sig_vec, (struct sigvec *)0);
179: sigvec(SIGSEGV, &sig_vec, (struct sigvec *)0);
180: sigvec(SIGSYS, &sig_vec, (struct sigvec *)0);
181:
182: /*
183: * now peruse through the list of files.
184: */
185: for(fp=filelist; *fp; fp++) {
186: filecontent = getfile(*fp);
187: ip = newinclude(*fp, (char *)NULL);
188:
189: find_includes(filecontent, ip, ip, 0);
190: freefile(filecontent);
191: recursive_pr_include(ip, ip->i_file, basename(*fp));
192: inc_clean();
193: }
194: if (printed)
195: printf("\n");
196: exit(0);
197: }
198:
199: struct filepointer *getfile(file)
200: char *file;
201: {
202: register int fd;
203: struct filepointer *content;
204: struct stat st;
205:
206: content = (struct filepointer *)malloc(sizeof(struct filepointer));
207: if ((fd = open(file, O_RDONLY)) < 0) {
208: log("cannot open \"%s\"\n", file);
209: content->f_p = content->f_base = content->f_end = malloc(1);
210: *content->f_p = '\0';
211: return(content);
212: }
213: fstat(fd, &st);
214: content->f_len = st.st_size+1;
215: content->f_base = malloc(content->f_len);
216: if (content->f_base == NULL)
217: log_fatal("cannot allocate mem\n");
218: if (read(fd, content->f_base, st.st_size) != st.st_size)
219: log_fatal("cannot read all of %s\n", file);
220: close(fd);
221: content->f_p = content->f_base;
222: content->f_end = content->f_base + st.st_size;
223: *content->f_end = '\0';
224: content->f_line = 0;
225: return(content);
226: }
227:
228: freefile(fp)
229: struct filepointer *fp;
230: {
231: free(fp->f_base);
232: free(fp);
233: }
234:
235: /*VARARGS*/
236: log_fatal(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
237: {
238: log(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
239: exit (1);
240: }
241:
242: /*VARARGS0*/
243: log(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9)
244: {
245: fprintf(stderr, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9);
246: }
247:
248: char *copy(str)
249: register char *str;
250: {
251: register char *p = malloc(strlen(str) + 1);
252:
253: strcpy(p, str);
254: return(p);
255: }
256:
257: match(str, list)
258: register char *str, **list;
259: {
260: register int i;
261:
262: for (i=0; *list; i++, list++)
263: if (strcmp(str, *list) == 0)
264: return(i);
265: return(-1);
266: }
267:
268: /*
269: * Get the next line. We only return lines beginning with '#' since that
270: * is all this program is ever interested in.
271: */
272: char *getline(filep)
273: register struct filepointer *filep;
274: {
275: register char *p, /* walking pointer */
276: *eof, /* end of file pointer */
277: *bol; /* beginning of line pointer */
278: register lineno; /* line number */
279: register boolean interesting = FALSE;
280:
281: p = filep->f_p;
282: eof = filep->f_end;
283: if (p >= eof)
284: return((char *)NULL);
285: lineno = filep->f_line;
286:
287: for(bol = p--; ++p < eof; ) {
288: if (*p == '/' && *(p+1) == '*') { /* consume comments */
289: *p++ = ' ', *p++ = ' ';
290: while (*p) {
291: if (*p == '*' && *(p+1) == '/') {
292: *p++ = ' ', *p = ' ';
293: break;
294: }
295: else if (*p == '\n')
296: lineno++;
297: *p++ = ' ';
298: }
299: continue;
300: }
301: else if (*p == '\n') {
302: lineno++;
303: if (*bol == '#') {
304: *p++ = '\0';
305: goto done;
306: }
307: bol = p+1;
308: }
309: }
310: if (*bol != '#')
311: bol = NULL;
312: done:
313: filep->f_p = p;
314: filep->f_line = lineno;
315: return(bol);
316: }
317:
318: char *basename(file)
319: register char *file;
320: {
321: register char *p;
322:
323: for (p=file+strlen(file); p>file && *p != '/'; p--) ;
324:
325: if (*p == '/')
326: p++;
327:
328: file = copy(p);
329: for(p=file+strlen(file); p>file && *p != '.'; p--) ;
330:
331: if (*p == '.')
332: *p = '\0';
333: return(file);
334: }
335:
336: redirect(line, makefile)
337: char *line,
338: *makefile;
339: {
340: struct stat st;
341: FILE *fdin, *fdout;
342: char backup[ BUFSIZ ],
343: buf[ BUFSIZ ];
344: boolean found = FALSE;
345: int len;
346:
347: /*
348: * if makefile is "-" then let it pour onto stdout.
349: */
350: if (makefile && *makefile == '-' && *(makefile+1) == '\0')
351: return;
352:
353: /*
354: * use a default makefile is not specified.
355: */
356: if (!makefile) {
357: if (stat("makefile", &st) == 0)
358: makefile = "makefile";
359: else if (stat("Makefile", &st) == 0)
360: makefile = "Makefile";
361: else
362: log_fatal("[mM]akefile is not present\n");
363: }
364: else
365: stat(makefile, &st);
366: if ((fdin = fopen(makefile, "r")) == NULL)
367: log_fatal("cannot open \"%s\"\n", makefile);
368: sprintf(backup, "%s.bak", makefile);
369: unlink(backup);
370: if (rename(makefile, backup) < 0)
371: log_fatal("cannot rename %s to %s\n", makefile, backup);
372: if ((fdout = freopen(makefile, "w", stdout)) == NULL)
373: log_fatal("cannot open \"%s\"\n", backup);
374: len = strlen(line);
375: while (fgets(buf, BUFSIZ, fdin) && !found) {
376: if (*buf == '#' && strncmp(line, buf, len) == 0)
377: found = TRUE;
378: fputs(buf, fdout);
379: }
380: if (!found) {
381: log("delimiting line \"%s\" not found...\nAppending...\n",
382: line);
383: puts(line); /* same as fputs(fdout); but with newline */
384: }
385: fflush(fdout);
386: fchmod(fileno(fdout), st.st_mode);
387: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.