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