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