]>
Commit | Line | Data |
---|---|---|
455e8271 | 1 | /* |
2 | * $XConsortium: main.c,v 1.20 88/10/22 11:26:14 jim Exp $ | |
3 | */ | |
4 | #include "def.h" | |
5 | #ifdef hpux | |
6 | #define sigvec sigvector | |
7 | #endif /* hpux */ | |
8 | #include <sys/signal.h> | |
9 | ||
10 | #ifdef DEBUG | |
11 | int debug; | |
12 | #endif | |
13 | ||
14 | char *directives[] = { | |
15 | "if", | |
16 | "ifdef", | |
17 | "ifndef", | |
18 | "else", | |
19 | "endif", | |
20 | "define", | |
21 | "undef", | |
22 | "include", | |
23 | "line", | |
24 | "pragma", | |
25 | "elif", | |
26 | "eject", | |
27 | NULL | |
28 | }; | |
29 | ||
30 | struct symtab predefs[] = { | |
31 | #ifdef apollo | |
32 | {"apollo", NULL}, | |
33 | #endif | |
34 | #ifdef ibm032 | |
35 | {"ibm032", NULL}, | |
36 | #endif | |
37 | #ifdef sun | |
38 | {"sun", NULL}, | |
598947e3 | 39 | #ifdef sparc |
40 | {"sparc", NULL}, | |
41 | #endif | |
455e8271 | 42 | #endif |
43 | #ifdef hpux | |
44 | {"hpux", NULL}, | |
45 | #endif | |
46 | #ifdef vax | |
47 | {"vax", NULL}, | |
48 | #endif | |
49 | #ifdef VMS | |
50 | {"VMS", NULL}, | |
bbf51bb6 | 51 | #endif |
52 | #ifdef ultrix | |
53 | {"ultrix", NULL}, | |
54 | #endif | |
55 | #ifdef mips | |
56 | {"mips", NULL}, | |
455e8271 | 57 | #endif |
58 | {NULL, NULL} | |
59 | }; | |
60 | ||
61 | struct symtab deflist[ MAXDEFINES ]; | |
62 | struct inclist inclist[ MAXFILES ], | |
63 | *inclistp = inclist; | |
64 | ||
65 | char *filelist[ MAXFILES ]; | |
66 | char *includedirs[ MAXDIRS ]; | |
67 | char *notdotdot[ MAXDIRS ]; | |
68 | char *objfile = ".o"; | |
69 | char *startat = "# DO NOT DELETE THIS LINE -- make depend depends on it."; | |
70 | int width = 78; | |
71 | boolean printed = FALSE; | |
72 | boolean verbose = FALSE; | |
73 | boolean show_where_not = FALSE; | |
bbf51bb6 | 74 | |
75 | #if defined(POSIX) || (defined(mips) && defined(SYSTYPE_SYSV)) | |
76 | typedef void sigreturn_t; | |
455e8271 | 77 | #else |
bbf51bb6 | 78 | typedef int sigreturn_t; |
455e8271 | 79 | #endif |
bbf51bb6 | 80 | sigreturn_t catch(); |
455e8271 | 81 | |
a06380b2 | 82 | #if !(defined(mips) && defined(SYSTYPE_SYSV)) |
455e8271 | 83 | struct sigvec sig_vec = { |
84 | catch, | |
85 | (1<<(SIGINT -1)) | |
86 | |(1<<(SIGQUIT-1)) | |
87 | |(1<<(SIGBUS-1)) | |
88 | |(1<<(SIGILL-1)) | |
89 | |(1<<(SIGSEGV-1)) | |
90 | |(1<<(SIGHUP-1)) | |
91 | |(1<<(SIGPIPE-1)) | |
92 | |(1<<(SIGSYS-1)), | |
93 | 0 | |
94 | }; | |
95 | #endif /* mips && SYSTYPE_SYSV */ | |
96 | ||
97 | main(argc, argv) | |
98 | int argc; | |
99 | char **argv; | |
100 | { | |
101 | register struct symtab *symp = deflist; | |
102 | register char **fp = filelist; | |
103 | register char **incp = includedirs; | |
104 | register char *p; | |
105 | register struct inclist *ip; | |
106 | char *makefile = NULL; | |
107 | struct filepointer *filecontent; | |
108 | struct symtab *psymp = predefs; | |
109 | char *endmarker = NULL; | |
110 | ||
111 | while (psymp->s_name) | |
112 | *symp++ = *psymp++; | |
113 | for(argc--, argv++; argc; argc--, argv++) { | |
114 | /* if looking for endmarker then check before parsing */ | |
115 | if (endmarker && strcmp (endmarker, *argv) == 0) { | |
116 | endmarker = NULL; | |
117 | continue; | |
118 | } | |
119 | if (**argv != '-') { | |
120 | *fp++ = argv[0]; | |
121 | continue; | |
122 | } | |
123 | switch(argv[0][1]) { | |
124 | case '-': | |
125 | endmarker = &argv[0][2]; | |
126 | if (endmarker[0] == '\0') endmarker = "--"; | |
127 | break; | |
128 | case 'D': | |
129 | symp->s_name = argv[0]+2; | |
130 | if (*symp->s_name == '\0') { | |
131 | symp->s_name = *(++argv); | |
132 | argc--; | |
133 | } | |
134 | for (p=symp->s_name; *p ; p++) | |
135 | if (*p == '=') { | |
136 | *p++ = '\0'; | |
137 | break; | |
138 | } | |
139 | symp->s_value = p; | |
140 | symp++; | |
141 | break; | |
142 | case 'I': | |
143 | *incp++ = argv[0]+2; | |
144 | if (**(incp-1) == '\0') { | |
145 | *(incp-1) = *(++argv); | |
146 | argc--; | |
147 | } | |
148 | break; | |
149 | /* do not use if endmarker processing */ | |
150 | case 'w': | |
151 | if (endmarker) break; | |
152 | if (argv[0][2] == '\0') { | |
153 | argv++; | |
154 | argc--; | |
155 | width = atoi(argv[0]); | |
156 | } else | |
157 | width = atoi(argv[0]+2); | |
158 | break; | |
159 | case 'o': | |
160 | if (endmarker) break; | |
161 | if (argv[0][2] == '\0') { | |
162 | argv++; | |
163 | argc--; | |
164 | objfile = argv[0]; | |
165 | } else | |
166 | objfile = argv[0]+2; | |
167 | break; | |
168 | case 'v': | |
169 | if (endmarker) break; | |
170 | verbose = TRUE; | |
171 | #ifdef DEBUG | |
172 | if (argv[0][2]) | |
173 | debug = atoi(argv[0]+2); | |
174 | #endif | |
175 | break; | |
176 | case 's': | |
177 | if (endmarker) break; | |
178 | startat = argv[0]+2; | |
179 | if (*startat == '\0') { | |
180 | startat = *(++argv); | |
181 | argc--; | |
182 | } | |
183 | if (*startat != '#') | |
184 | log_fatal("-s flag's value should start %s\n", | |
185 | "with '#'."); | |
186 | break; | |
187 | case 'f': | |
188 | if (endmarker) break; | |
189 | makefile = argv[0]+2; | |
190 | if (*makefile == '\0') { | |
191 | makefile = *(++argv); | |
192 | argc--; | |
193 | } | |
194 | break; | |
195 | ||
196 | /* Ignore -O, -g so we can just pass ${CFLAGS} to | |
197 | makedepend | |
198 | */ | |
199 | case 'O': | |
200 | case 'g': | |
201 | break; | |
202 | default: | |
203 | if (endmarker) break; | |
204 | /* log_fatal("unknown opt = %s\n", argv[0]); */ | |
205 | log("ignoring option %s\n", argv[0]); | |
206 | } | |
207 | } | |
208 | *incp++ = INCLUDEDIR; | |
209 | ||
210 | redirect(startat, makefile); | |
211 | ||
212 | /* | |
213 | * catch signals. | |
214 | */ | |
215 | #if defined (mips) && defined (SYSTYPE_SYSV) | |
216 | /* should really reset SIGINT to SIG_IGN if it was. */ | |
217 | signal (SIGHUP, catch); | |
218 | signal (SIGINT, catch); | |
219 | signal (SIGQUIT, catch); | |
220 | signal (SIGILL, catch); | |
221 | signal (SIGBUS, catch); | |
222 | signal (SIGSEGV, catch); | |
223 | signal (SIGSYS, catch); | |
224 | #else /* not (mips && SYSTYPE_SYSV) */ | |
225 | sigvec(SIGHUP, &sig_vec, (struct sigvec *)0); | |
226 | sigvec(SIGINT, &sig_vec, (struct sigvec *)0); | |
227 | sigvec(SIGQUIT, &sig_vec, (struct sigvec *)0); | |
228 | sigvec(SIGILL, &sig_vec, (struct sigvec *)0); | |
229 | sigvec(SIGBUS, &sig_vec, (struct sigvec *)0); | |
230 | sigvec(SIGSEGV, &sig_vec, (struct sigvec *)0); | |
231 | sigvec(SIGSYS, &sig_vec, (struct sigvec *)0); | |
232 | #endif /* mips && SYSTYPE_SYSV */ | |
233 | ||
234 | /* | |
235 | * now peruse through the list of files. | |
236 | */ | |
237 | for(fp=filelist; *fp; fp++) { | |
238 | filecontent = getfile(*fp); | |
239 | ip = newinclude(*fp, (char *)NULL); | |
240 | ||
241 | find_includes(filecontent, ip, ip, 0); | |
242 | freefile(filecontent); | |
243 | recursive_pr_include(ip, ip->i_file, basename(*fp)); | |
244 | inc_clean(); | |
245 | } | |
246 | if (printed) | |
247 | printf("\n"); | |
248 | exit(0); | |
249 | } | |
250 | ||
251 | struct filepointer *getfile(file) | |
252 | char *file; | |
253 | { | |
254 | register int fd; | |
255 | struct filepointer *content; | |
256 | struct stat st; | |
257 | ||
258 | content = (struct filepointer *)malloc(sizeof(struct filepointer)); | |
259 | if ((fd = open(file, O_RDONLY)) < 0) { | |
260 | log("cannot open \"%s\"\n", file); | |
261 | content->f_p = content->f_base = content->f_end = malloc(1); | |
262 | *content->f_p = '\0'; | |
263 | return(content); | |
264 | } | |
265 | fstat(fd, &st); | |
266 | content->f_len = st.st_size+1; | |
267 | content->f_base = malloc(content->f_len); | |
268 | if (content->f_base == NULL) | |
269 | log_fatal("cannot allocate mem\n"); | |
270 | if (read(fd, content->f_base, st.st_size) != st.st_size) | |
271 | log_fatal("cannot read all of %s\n", file); | |
272 | close(fd); | |
273 | content->f_p = content->f_base; | |
274 | content->f_end = content->f_base + st.st_size; | |
275 | *content->f_end = '\0'; | |
276 | content->f_line = 0; | |
277 | return(content); | |
278 | } | |
279 | ||
280 | freefile(fp) | |
281 | struct filepointer *fp; | |
282 | { | |
283 | free(fp->f_base); | |
284 | free(fp); | |
285 | } | |
286 | ||
287 | /*VARARGS*/ | |
288 | log_fatal(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9) | |
289 | { | |
290 | log(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9); | |
291 | exit (1); | |
292 | } | |
293 | ||
294 | /*VARARGS0*/ | |
295 | log(x0,x1,x2,x3,x4,x5,x6,x7,x8,x9) | |
296 | { | |
297 | fprintf(stderr, x0,x1,x2,x3,x4,x5,x6,x7,x8,x9); | |
298 | } | |
299 | ||
300 | char *copy(str) | |
301 | register char *str; | |
302 | { | |
303 | register char *p = malloc(strlen(str) + 1); | |
304 | ||
305 | strcpy(p, str); | |
306 | return(p); | |
307 | } | |
308 | ||
309 | match(str, list) | |
310 | register char *str, **list; | |
311 | { | |
312 | register int i; | |
313 | ||
314 | for (i=0; *list; i++, list++) | |
315 | if (strcmp(str, *list) == 0) | |
316 | return(i); | |
317 | return(-1); | |
318 | } | |
319 | ||
320 | /* | |
321 | * Get the next line. We only return lines beginning with '#' since that | |
322 | * is all this program is ever interested in. | |
323 | */ | |
324 | char *getline(filep) | |
325 | register struct filepointer *filep; | |
326 | { | |
327 | register char *p, /* walking pointer */ | |
328 | *eof, /* end of file pointer */ | |
329 | *bol; /* beginning of line pointer */ | |
330 | register lineno; /* line number */ | |
331 | ||
332 | p = filep->f_p; | |
333 | eof = filep->f_end; | |
334 | if (p >= eof) | |
335 | return((char *)NULL); | |
336 | lineno = filep->f_line; | |
337 | ||
338 | for(bol = p--; ++p < eof; ) { | |
339 | if (*p == '/' && *(p+1) == '*') { /* consume comments */ | |
340 | *p++ = ' ', *p++ = ' '; | |
341 | while (*p) { | |
342 | if (*p == '*' && *(p+1) == '/') { | |
343 | *p++ = ' ', *p = ' '; | |
344 | break; | |
345 | } | |
346 | else if (*p == '\n') | |
347 | lineno++; | |
348 | *p++ = ' '; | |
349 | } | |
350 | continue; | |
351 | } | |
352 | else if (*p == '\n') { | |
353 | lineno++; | |
354 | if (*bol == '#') { | |
355 | *p++ = '\0'; | |
356 | goto done; | |
357 | } | |
358 | bol = p+1; | |
359 | } | |
360 | } | |
361 | if (*bol != '#') | |
362 | bol = NULL; | |
363 | done: | |
364 | filep->f_p = p; | |
365 | filep->f_line = lineno; | |
366 | return(bol); | |
367 | } | |
368 | ||
369 | char *basename(file) | |
370 | register char *file; | |
371 | { | |
372 | register char *p; | |
373 | ||
374 | for (p=file+strlen(file); p>file && *p != '/'; p--) ; | |
375 | ||
376 | if (*p == '/') | |
377 | p++; | |
378 | ||
379 | file = copy(p); | |
380 | for(p=file+strlen(file); p>file && *p != '.'; p--) ; | |
381 | ||
382 | if (*p == '.') | |
383 | *p = '\0'; | |
384 | return(file); | |
385 | } | |
386 | ||
387 | redirect(line, makefile) | |
388 | char *line, | |
389 | *makefile; | |
390 | { | |
391 | struct stat st; | |
392 | FILE *fdin, *fdout; | |
393 | char backup[ BUFSIZ ], | |
394 | buf[ BUFSIZ ]; | |
395 | boolean found = FALSE; | |
396 | int len; | |
397 | ||
398 | /* | |
399 | * if makefile is "-" then let it pour onto stdout. | |
400 | */ | |
401 | if (makefile && *makefile == '-' && *(makefile+1) == '\0') | |
402 | return; | |
403 | ||
404 | /* | |
405 | * use a default makefile is not specified. | |
406 | */ | |
407 | if (!makefile) { | |
408 | if (stat("makefile", &st) == 0) | |
409 | makefile = "makefile"; | |
410 | else if (stat("Makefile", &st) == 0) | |
411 | makefile = "Makefile"; | |
412 | else | |
413 | log_fatal("[mM]akefile is not present\n"); | |
414 | } | |
415 | else | |
416 | stat(makefile, &st); | |
417 | if ((fdin = fopen(makefile, "r")) == NULL) | |
418 | log_fatal("cannot open \"%s\"\n", makefile); | |
419 | sprintf(backup, "%s.bak", makefile); | |
420 | unlink(backup); | |
421 | if (rename(makefile, backup) < 0) | |
422 | log_fatal("cannot rename %s to %s\n", makefile, backup); | |
423 | if ((fdout = freopen(makefile, "w", stdout)) == NULL) | |
424 | log_fatal("cannot open \"%s\"\n", backup); | |
425 | len = strlen(line); | |
426 | while (fgets(buf, BUFSIZ, fdin) && !found) { | |
427 | if (*buf == '#' && strncmp(line, buf, len) == 0) | |
428 | found = TRUE; | |
429 | fputs(buf, fdout); | |
430 | } | |
431 | if (!found) { | |
432 | log("Adding new delimiting line \"%s\"\nAdding dependencies...\n", | |
433 | line); | |
434 | puts(line); /* same as fputs(fdout); but with newline */ | |
435 | } | |
436 | fflush(fdout); | |
437 | #if defined (mips) && defined (SYSTYPE_SYSV) | |
438 | chmod(makefile, st.st_mode); | |
439 | #else /* not (mips && SYSTYPE_SYSV) */ | |
440 | fchmod(fileno(fdout), st.st_mode); | |
441 | #endif /* mips && SYSTYPE_SYSV */ | |
442 | } |