1 |
/* $XConsortium: main.c,v 1.83 94/04/17 20:10:36 gildea Exp $ */ |
2 |
/* |
3 |
* Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. |
4 |
* |
5 |
* Redistribution and use in source and binary forms, with or without |
6 |
* modification, are permitted provided that the following conditions |
7 |
* are met: |
8 |
* |
9 |
* 1. Redistributions of source code must retain the above copyright |
10 |
* notice, this list of conditions and the following disclaimer. |
11 |
* |
12 |
* 2. Redistributions in binary form must reproduce the above copyright |
13 |
* notice, this list of conditions and the following disclaimer in |
14 |
* the documentation and/or other materials provided with the |
15 |
* distribution. |
16 |
* |
17 |
* 3. The name "Carnegie Mellon University" must not be used to |
18 |
* endorse or promote products derived from this software without |
19 |
* prior written permission. For permission or any other legal |
20 |
* details, please contact |
21 |
* Office of Technology Transfer |
22 |
* Carnegie Mellon University |
23 |
* 5000 Forbes Avenue |
24 |
* Pittsburgh, PA 15213-3890 |
25 |
* (412) 268-4387, fax: (412) 268-7395 |
26 |
* tech-transfer@andrew.cmu.edu |
27 |
* |
28 |
* 4. Redistributions of any form whatsoever must retain the following |
29 |
* acknowledgment: |
30 |
* "This product includes software developed by Computing Services |
31 |
* at Carnegie Mellon University (http://www.cmu.edu/computing/)." |
32 |
* |
33 |
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO |
34 |
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
35 |
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE |
36 |
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
37 |
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN |
38 |
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING |
39 |
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
40 |
* |
41 |
*/ |
42 |
|
43 |
/* |
44 |
|
45 |
Copyright (c) 1993, 1994 X Consortium |
46 |
|
47 |
Permission is hereby granted, free of charge, to any person obtaining a copy |
48 |
of this software and associated documentation files (the "Software"), to deal |
49 |
in the Software without restriction, including without limitation the rights |
50 |
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
51 |
copies of the Software, and to permit persons to whom the Software is |
52 |
furnished to do so, subject to the following conditions: |
53 |
|
54 |
The above copyright notice and this permission notice shall be included in |
55 |
all copies or substantial portions of the Software. |
56 |
|
57 |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
58 |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
59 |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
60 |
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN |
61 |
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
62 |
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
63 |
|
64 |
Except as contained in this notice, the name of the X Consortium shall not be |
65 |
used in advertising or otherwise to promote the sale, use or other dealings |
66 |
in this Software without prior written authorization from the X Consortium. |
67 |
|
68 |
*/ |
69 |
|
70 |
#include "def.h" |
71 |
#ifdef hpux |
72 |
#define sigvec sigvector |
73 |
#endif /* hpux */ |
74 |
|
75 |
#include <signal.h> |
76 |
|
77 |
#ifdef HAVE_STDARG_H /* NeedVarargsPrototypes */ |
78 |
#include <stdarg.h> |
79 |
#endif |
80 |
|
81 |
#ifdef DEBUG |
82 |
int _debugmask; |
83 |
#endif |
84 |
|
85 |
char *ProgramName; |
86 |
|
87 |
char *directives[] = { |
88 |
"if", |
89 |
"ifdef", |
90 |
"ifndef", |
91 |
"else", |
92 |
"endif", |
93 |
"define", |
94 |
"undef", |
95 |
"include", |
96 |
"line", |
97 |
"pragma", |
98 |
"error", |
99 |
"ident", |
100 |
"sccs", |
101 |
"elif", |
102 |
"eject", |
103 |
NULL |
104 |
}; |
105 |
|
106 |
struct symtab predefs[] = { |
107 |
#ifdef apollo |
108 |
{"apollo", "1"}, |
109 |
#endif |
110 |
#ifdef ibm032 |
111 |
{"ibm032", "1"}, |
112 |
#endif |
113 |
#ifdef sun |
114 |
{"sun", "1"}, |
115 |
#ifdef sparc |
116 |
{"sparc", "1"}, |
117 |
#endif |
118 |
#endif |
119 |
#ifdef solaris20 |
120 |
{"solaris20", "1"}, |
121 |
#endif |
122 |
#ifdef __i386 |
123 |
{"__i386", "1"}, |
124 |
#endif |
125 |
#ifdef hpux |
126 |
{"hpux", "1"}, |
127 |
#endif |
128 |
#ifdef vax |
129 |
{"vax", "1"}, |
130 |
#endif |
131 |
#ifdef VMS |
132 |
{"VMS", "1"}, |
133 |
#endif |
134 |
#ifdef ultrix |
135 |
{"ultrix", "1"}, |
136 |
#endif |
137 |
#ifdef mips |
138 |
{"mips", "1"}, |
139 |
#endif |
140 |
#ifdef __SCO__ |
141 |
{"__SCO__", "1"}, |
142 |
#endif |
143 |
#ifdef __DGUX |
144 |
{"__DGUX", "1"}, |
145 |
#endif |
146 |
#ifdef __DGUX__ |
147 |
{"__DGUX__", "1"}, |
148 |
#endif |
149 |
#ifdef __m88k__ |
150 |
{"__m88k__", "1"}, |
151 |
#endif |
152 |
{NULL, NULL} |
153 |
}; |
154 |
#define OBJSUFFIX ".o" |
155 |
#define INCLUDEDIR "/usr/include" |
156 |
|
157 |
struct inclist inclist[ MAXFILES ], |
158 |
*inclistp = inclist, |
159 |
maininclist; |
160 |
|
161 |
char *filelist[ MAXFILES ]; |
162 |
char *includedirs[ MAXDIRS + 1 ]; |
163 |
char *notdotdot[ MAXDIRS ]; |
164 |
char *objprefix = ""; |
165 |
char *objsuffix = OBJSUFFIX; |
166 |
char *startat = "# DO NOT DELETE"; |
167 |
int width = 78; |
168 |
boolean append = FALSE; |
169 |
boolean printed = FALSE; |
170 |
boolean verbose = FALSE; |
171 |
boolean show_where_not = FALSE; |
172 |
boolean warn_multiple = FALSE; /* Warn on multiple includes of same file */ |
173 |
|
174 |
static |
175 |
#ifdef SIGNALRETURNSINT |
176 |
int |
177 |
#else |
178 |
void |
179 |
#endif |
180 |
catch (sig) |
181 |
int sig; |
182 |
{ |
183 |
fflush (stdout); |
184 |
fatalerr ("got signal %d\n", sig); |
185 |
} |
186 |
|
187 |
#if defined(USG) || (defined(SYSV386) && defined(SYSV)) || defined(WIN32) || defined(__i386) |
188 |
#define USGISH |
189 |
#endif |
190 |
|
191 |
#ifndef USGISH |
192 |
#ifndef _POSIX_SOURCE |
193 |
#define sigaction sigvec |
194 |
#define sa_handler sv_handler |
195 |
#define sa_mask sv_mask |
196 |
#define sa_flags sv_flags |
197 |
#endif |
198 |
struct sigaction sig_act; |
199 |
#endif /* USGISH */ |
200 |
|
201 |
main(argc, argv) |
202 |
int argc; |
203 |
char **argv; |
204 |
{ |
205 |
register char **fp = filelist; |
206 |
register char **incp = includedirs; |
207 |
register char *p; |
208 |
register struct inclist *ip; |
209 |
char *makefile = NULL; |
210 |
struct filepointer *filecontent; |
211 |
struct symtab *psymp = predefs; |
212 |
char *endmarker = NULL; |
213 |
char *defincdir = NULL; |
214 |
|
215 |
ProgramName = argv[0]; |
216 |
|
217 |
while (psymp->s_name) |
218 |
{ |
219 |
define2(psymp->s_name, psymp->s_value, &maininclist); |
220 |
psymp++; |
221 |
} |
222 |
if (argc == 2 && argv[1][0] == '@') { |
223 |
struct stat ast; |
224 |
int afd; |
225 |
char *args; |
226 |
char **nargv; |
227 |
int nargc; |
228 |
char quotechar = '\0'; |
229 |
|
230 |
nargc = 1; |
231 |
if ((afd = open(argv[1]+1, O_RDONLY)) < 0) |
232 |
fatalerr("cannot open \"%s\"\n", argv[1]+1); |
233 |
fstat(afd, &ast); |
234 |
args = (char *)malloc(ast.st_size + 1); |
235 |
if ((ast.st_size = read(afd, args, ast.st_size)) < 0) |
236 |
fatalerr("failed to read %s\n", argv[1]+1); |
237 |
args[ast.st_size] = '\0'; |
238 |
close(afd); |
239 |
for (p = args; *p; p++) { |
240 |
if (quotechar) { |
241 |
if (quotechar == '\\' || |
242 |
(*p == quotechar && p[-1] != '\\')) |
243 |
quotechar = '\0'; |
244 |
continue; |
245 |
} |
246 |
switch (*p) { |
247 |
case '\\': |
248 |
case '"': |
249 |
case '\'': |
250 |
quotechar = *p; |
251 |
break; |
252 |
case ' ': |
253 |
case '\n': |
254 |
*p = '\0'; |
255 |
if (p > args && p[-1]) |
256 |
nargc++; |
257 |
break; |
258 |
} |
259 |
} |
260 |
if (p[-1]) |
261 |
nargc++; |
262 |
nargv = (char **)malloc(nargc * sizeof(char *)); |
263 |
nargv[0] = argv[0]; |
264 |
argc = 1; |
265 |
for (p = args; argc < nargc; p += strlen(p) + 1) |
266 |
if (*p) nargv[argc++] = p; |
267 |
argv = nargv; |
268 |
} |
269 |
for(argc--, argv++; argc; argc--, argv++) { |
270 |
/* if looking for endmarker then check before parsing */ |
271 |
if (endmarker && strcmp (endmarker, *argv) == 0) { |
272 |
endmarker = NULL; |
273 |
continue; |
274 |
} |
275 |
if (**argv != '-') { |
276 |
/* treat +thing as an option for C++ */ |
277 |
if (endmarker && **argv == '+') |
278 |
continue; |
279 |
*fp++ = argv[0]; |
280 |
continue; |
281 |
} |
282 |
switch(argv[0][1]) { |
283 |
case '-': |
284 |
endmarker = &argv[0][2]; |
285 |
if (endmarker[0] == '\0') endmarker = "--"; |
286 |
break; |
287 |
case 'D': |
288 |
if (argv[0][2] == '\0') { |
289 |
argv++; |
290 |
argc--; |
291 |
} |
292 |
for (p=argv[0] + 2; *p ; p++) |
293 |
if (*p == '=') { |
294 |
*p = ' '; |
295 |
break; |
296 |
} |
297 |
define(argv[0] + 2, &maininclist); |
298 |
break; |
299 |
case 'I': |
300 |
if (incp >= includedirs + MAXDIRS) |
301 |
fatalerr("Too many -I flags.\n"); |
302 |
*incp++ = argv[0]+2; |
303 |
if (**(incp-1) == '\0') { |
304 |
*(incp-1) = *(++argv); |
305 |
argc--; |
306 |
} |
307 |
break; |
308 |
case 'Y': |
309 |
defincdir = argv[0]+2; |
310 |
break; |
311 |
/* do not use if endmarker processing */ |
312 |
case 'a': |
313 |
if (endmarker) break; |
314 |
append = TRUE; |
315 |
break; |
316 |
case 'w': |
317 |
if (endmarker) break; |
318 |
if (argv[0][2] == '\0') { |
319 |
argv++; |
320 |
argc--; |
321 |
width = atoi(argv[0]); |
322 |
} else |
323 |
width = atoi(argv[0]+2); |
324 |
break; |
325 |
case 'o': |
326 |
if (endmarker) break; |
327 |
if (argv[0][2] == '\0') { |
328 |
argv++; |
329 |
argc--; |
330 |
objsuffix = argv[0]; |
331 |
} else |
332 |
objsuffix = argv[0]+2; |
333 |
break; |
334 |
case 'p': |
335 |
if (endmarker) break; |
336 |
if (argv[0][2] == '\0') { |
337 |
argv++; |
338 |
argc--; |
339 |
objprefix = argv[0]; |
340 |
} else |
341 |
objprefix = argv[0]+2; |
342 |
break; |
343 |
case 'v': |
344 |
if (endmarker) break; |
345 |
verbose = TRUE; |
346 |
#ifdef DEBUG |
347 |
if (argv[0][2]) |
348 |
_debugmask = atoi(argv[0]+2); |
349 |
#endif |
350 |
break; |
351 |
case 's': |
352 |
if (endmarker) break; |
353 |
startat = argv[0]+2; |
354 |
if (*startat == '\0') { |
355 |
startat = *(++argv); |
356 |
argc--; |
357 |
} |
358 |
if (*startat != '#') |
359 |
fatalerr("-s flag's value should start %s\n", |
360 |
"with '#'."); |
361 |
break; |
362 |
case 'f': |
363 |
if (endmarker) break; |
364 |
makefile = argv[0]+2; |
365 |
if (*makefile == '\0') { |
366 |
makefile = *(++argv); |
367 |
argc--; |
368 |
} |
369 |
break; |
370 |
|
371 |
case 'm': |
372 |
warn_multiple = TRUE; |
373 |
break; |
374 |
|
375 |
/* Ignore -O, -g so we can just pass ${CFLAGS} to |
376 |
makedepend |
377 |
*/ |
378 |
case 'O': |
379 |
case 'g': |
380 |
break; |
381 |
default: |
382 |
if (endmarker) break; |
383 |
/* fatalerr("unknown opt = %s\n", argv[0]); */ |
384 |
warning("ignoring option %s\n", argv[0]); |
385 |
} |
386 |
} |
387 |
if (!defincdir) { |
388 |
#ifdef PREINCDIR |
389 |
if (incp >= includedirs + MAXDIRS) |
390 |
fatalerr("Too many -I flags.\n"); |
391 |
*incp++ = PREINCDIR; |
392 |
#endif |
393 |
if (incp >= includedirs + MAXDIRS) |
394 |
fatalerr("Too many -I flags.\n"); |
395 |
*incp++ = INCLUDEDIR; |
396 |
#ifdef POSTINCDIR |
397 |
if (incp >= includedirs + MAXDIRS) |
398 |
fatalerr("Too many -I flags.\n"); |
399 |
*incp++ = POSTINCDIR; |
400 |
#endif |
401 |
} else if (*defincdir) { |
402 |
if (incp >= includedirs + MAXDIRS) |
403 |
fatalerr("Too many -I flags.\n"); |
404 |
*incp++ = defincdir; |
405 |
} |
406 |
|
407 |
redirect(startat, makefile); |
408 |
|
409 |
/* |
410 |
* catch signals. |
411 |
*/ |
412 |
#ifdef USGISH |
413 |
/* should really reset SIGINT to SIG_IGN if it was. */ |
414 |
#ifdef SIGHUP |
415 |
signal (SIGHUP, catch); |
416 |
#endif |
417 |
signal (SIGINT, catch); |
418 |
#ifdef SIGQUIT |
419 |
signal (SIGQUIT, catch); |
420 |
#endif |
421 |
signal (SIGILL, catch); |
422 |
#ifdef SIGBUS |
423 |
signal (SIGBUS, catch); |
424 |
#endif |
425 |
signal (SIGSEGV, catch); |
426 |
#ifdef SIGSYS |
427 |
signal (SIGSYS, catch); |
428 |
#endif |
429 |
#else |
430 |
sig_act.sa_handler = catch; |
431 |
#ifdef _POSIX_SOURCE |
432 |
sigemptyset(&sig_act.sa_mask); |
433 |
sigaddset(&sig_act.sa_mask, SIGINT); |
434 |
sigaddset(&sig_act.sa_mask, SIGQUIT); |
435 |
#ifdef SIGBUS |
436 |
sigaddset(&sig_act.sa_mask, SIGBUS); |
437 |
#endif |
438 |
sigaddset(&sig_act.sa_mask, SIGILL); |
439 |
sigaddset(&sig_act.sa_mask, SIGSEGV); |
440 |
sigaddset(&sig_act.sa_mask, SIGHUP); |
441 |
sigaddset(&sig_act.sa_mask, SIGPIPE); |
442 |
#ifdef SIGSYS |
443 |
sigaddset(&sig_act.sa_mask, SIGSYS); |
444 |
#endif |
445 |
#else |
446 |
sig_act.sa_mask = ((1<<(SIGINT -1)) |
447 |
|(1<<(SIGQUIT-1)) |
448 |
#ifdef SIGBUS |
449 |
|(1<<(SIGBUS-1)) |
450 |
#endif |
451 |
|(1<<(SIGILL-1)) |
452 |
|(1<<(SIGSEGV-1)) |
453 |
|(1<<(SIGHUP-1)) |
454 |
|(1<<(SIGPIPE-1)) |
455 |
#ifdef SIGSYS |
456 |
|(1<<(SIGSYS-1)) |
457 |
#endif |
458 |
); |
459 |
#endif /* _POSIX_SOURCE */ |
460 |
sig_act.sa_flags = 0; |
461 |
sigaction(SIGHUP, &sig_act, (struct sigaction *)0); |
462 |
sigaction(SIGINT, &sig_act, (struct sigaction *)0); |
463 |
sigaction(SIGQUIT, &sig_act, (struct sigaction *)0); |
464 |
sigaction(SIGILL, &sig_act, (struct sigaction *)0); |
465 |
#ifdef SIGBUS |
466 |
sigaction(SIGBUS, &sig_act, (struct sigaction *)0); |
467 |
#endif |
468 |
sigaction(SIGSEGV, &sig_act, (struct sigaction *)0); |
469 |
#ifdef SIGSYS |
470 |
sigaction(SIGSYS, &sig_act, (struct sigaction *)0); |
471 |
#endif |
472 |
#endif /* USGISH */ |
473 |
|
474 |
/* |
475 |
* now peruse through the list of files. |
476 |
*/ |
477 |
for(fp=filelist; *fp; fp++) { |
478 |
filecontent = getfile(*fp); |
479 |
ip = newinclude(*fp, (char *)NULL); |
480 |
|
481 |
find_includes(filecontent, ip, ip, 0, FALSE); |
482 |
freefile(filecontent); |
483 |
recursive_pr_include(ip, ip->i_file, base_name(*fp)); |
484 |
inc_clean(); |
485 |
} |
486 |
if (printed) |
487 |
printf("\n"); |
488 |
exit(0); |
489 |
} |
490 |
|
491 |
struct filepointer *getfile(file) |
492 |
char *file; |
493 |
{ |
494 |
register int fd; |
495 |
struct filepointer *content; |
496 |
struct stat st; |
497 |
|
498 |
content = (struct filepointer *)malloc(sizeof(struct filepointer)); |
499 |
if ((fd = open(file, O_RDONLY)) < 0) { |
500 |
warning("cannot open \"%s\"\n", file); |
501 |
content->f_p = content->f_base = content->f_end = (char *)malloc(1); |
502 |
*content->f_p = '\0'; |
503 |
return(content); |
504 |
} |
505 |
fstat(fd, &st); |
506 |
content->f_base = (char *)malloc(st.st_size+1); |
507 |
if (content->f_base == NULL) |
508 |
fatalerr("cannot allocate mem\n"); |
509 |
if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0) |
510 |
fatalerr("failed to read %s\n", file); |
511 |
close(fd); |
512 |
content->f_len = st.st_size+1; |
513 |
content->f_p = content->f_base; |
514 |
content->f_end = content->f_base + st.st_size; |
515 |
*content->f_end = '\0'; |
516 |
content->f_line = 0; |
517 |
return(content); |
518 |
} |
519 |
|
520 |
freefile(fp) |
521 |
struct filepointer *fp; |
522 |
{ |
523 |
free(fp->f_base); |
524 |
free(fp); |
525 |
} |
526 |
|
527 |
char *copy(str) |
528 |
register char *str; |
529 |
{ |
530 |
register char *p = (char *)malloc(strlen(str) + 1); |
531 |
|
532 |
strcpy(p, str); |
533 |
return(p); |
534 |
} |
535 |
|
536 |
match(str, list) |
537 |
register char *str, **list; |
538 |
{ |
539 |
register int i; |
540 |
|
541 |
for (i=0; *list; i++, list++) |
542 |
if (strcmp(str, *list) == 0) |
543 |
return(i); |
544 |
return(-1); |
545 |
} |
546 |
|
547 |
/* |
548 |
* Get the next line. We only return lines beginning with '#' since that |
549 |
* is all this program is ever interested in. |
550 |
*/ |
551 |
char *getline(filep) |
552 |
register struct filepointer *filep; |
553 |
{ |
554 |
register char *p, /* walking pointer */ |
555 |
*eof, /* end of file pointer */ |
556 |
*bol; /* beginning of line pointer */ |
557 |
register lineno; /* line number */ |
558 |
|
559 |
p = filep->f_p; |
560 |
eof = filep->f_end; |
561 |
if (p >= eof) |
562 |
return((char *)NULL); |
563 |
lineno = filep->f_line; |
564 |
|
565 |
for(bol = p--; ++p < eof; ) { |
566 |
if (*p == '/' && *(p+1) == '*') { /* consume comments */ |
567 |
*p++ = ' ', *p++ = ' '; |
568 |
while (*p) { |
569 |
if (*p == '*' && *(p+1) == '/') { |
570 |
*p++ = ' ', *p = ' '; |
571 |
break; |
572 |
} |
573 |
else if (*p == '\n') |
574 |
lineno++; |
575 |
*p++ = ' '; |
576 |
} |
577 |
continue; |
578 |
} |
579 |
#ifdef WIN32 |
580 |
else if (*p == '/' && *(p+1) == '/') { /* consume comments */ |
581 |
*p++ = ' ', *p++ = ' '; |
582 |
while (*p && *p != '\n') |
583 |
*p++ = ' '; |
584 |
lineno++; |
585 |
continue; |
586 |
} |
587 |
#endif |
588 |
else if (*p == '\\') { |
589 |
if (*(p+1) == '\n') { |
590 |
*p = ' '; |
591 |
*(p+1) = ' '; |
592 |
lineno++; |
593 |
} |
594 |
} |
595 |
else if (*p == '\n') { |
596 |
lineno++; |
597 |
if (*bol == '#') { |
598 |
register char *cp; |
599 |
|
600 |
*p++ = '\0'; |
601 |
/* punt lines with just # (yacc generated) */ |
602 |
for (cp = bol+1; |
603 |
*cp && (*cp == ' ' || *cp == '\t'); cp++); |
604 |
if (*cp) goto done; |
605 |
} |
606 |
bol = p+1; |
607 |
} |
608 |
} |
609 |
if (*bol != '#') |
610 |
bol = NULL; |
611 |
done: |
612 |
filep->f_p = p; |
613 |
filep->f_line = lineno; |
614 |
return(bol); |
615 |
} |
616 |
|
617 |
/* |
618 |
* Strip the file name down to what we want to see in the Makefile. |
619 |
* It will have objprefix and objsuffix around it. |
620 |
*/ |
621 |
char *base_name(file) |
622 |
register char *file; |
623 |
{ |
624 |
register char *p; |
625 |
|
626 |
file = copy(file); |
627 |
for(p=file+strlen(file); p>file && *p != '.'; p--) ; |
628 |
|
629 |
if (*p == '.') |
630 |
*p = '\0'; |
631 |
return(file); |
632 |
} |
633 |
|
634 |
#if defined(USG) && !defined(CRAY) && !defined(SVR4) |
635 |
int rename (from, to) |
636 |
char *from, *to; |
637 |
{ |
638 |
(void) unlink (to); |
639 |
if (link (from, to) == 0) { |
640 |
unlink (from); |
641 |
return 0; |
642 |
} else { |
643 |
return -1; |
644 |
} |
645 |
} |
646 |
#endif /* USGISH */ |
647 |
|
648 |
redirect(line, makefile) |
649 |
char *line, |
650 |
*makefile; |
651 |
{ |
652 |
struct stat st; |
653 |
FILE *fdin, *fdout; |
654 |
char backup[ BUFSIZ ], |
655 |
buf[ BUFSIZ ]; |
656 |
boolean found = FALSE; |
657 |
int len; |
658 |
|
659 |
/* |
660 |
* if makefile is "-" then let it pour onto stdout. |
661 |
*/ |
662 |
if (makefile && *makefile == '-' && *(makefile+1) == '\0') |
663 |
return; |
664 |
|
665 |
/* |
666 |
* use a default makefile is not specified. |
667 |
*/ |
668 |
if (!makefile) { |
669 |
if (stat("Makefile", &st) == 0) |
670 |
makefile = "Makefile"; |
671 |
else if (stat("makefile", &st) == 0) |
672 |
makefile = "makefile"; |
673 |
else |
674 |
fatalerr("[mM]akefile is not present\n"); |
675 |
} |
676 |
else |
677 |
stat(makefile, &st); |
678 |
if ((fdin = fopen(makefile, "r")) == NULL) |
679 |
fatalerr("cannot open \"%s\"\n", makefile); |
680 |
sprintf(backup, "%s.bak", makefile); |
681 |
unlink(backup); |
682 |
#ifdef WIN32 |
683 |
fclose(fdin); |
684 |
#endif |
685 |
if (rename(makefile, backup) < 0) |
686 |
fatalerr("cannot rename %s to %s\n", makefile, backup); |
687 |
#ifdef WIN32 |
688 |
if ((fdin = fopen(backup, "r")) == NULL) |
689 |
fatalerr("cannot open \"%s\"\n", backup); |
690 |
#endif |
691 |
if ((fdout = freopen(makefile, "w", stdout)) == NULL) |
692 |
fatalerr("cannot open \"%s\"\n", backup); |
693 |
len = strlen(line); |
694 |
while (!found && fgets(buf, BUFSIZ, fdin)) { |
695 |
if (*buf == '#' && strncmp(line, buf, len) == 0) |
696 |
found = TRUE; |
697 |
fputs(buf, fdout); |
698 |
} |
699 |
if (!found) { |
700 |
if (verbose) |
701 |
warning("Adding new delimiting line \"%s\" and dependencies...\n", |
702 |
line); |
703 |
puts(line); /* same as fputs(fdout); but with newline */ |
704 |
} else if (append) { |
705 |
while (fgets(buf, BUFSIZ, fdin)) { |
706 |
fputs(buf, fdout); |
707 |
} |
708 |
} |
709 |
fflush(fdout); |
710 |
#if defined(USGISH) || defined(_SEQUENT_) |
711 |
chmod(makefile, st.st_mode); |
712 |
#else |
713 |
fchmod(fileno(fdout), st.st_mode); |
714 |
#endif /* USGISH */ |
715 |
} |
716 |
|
717 |
#ifdef HAVE_STDARG_H /* NeedVarargsPrototypes */ |
718 |
fatalerr(char *msg, ...) |
719 |
#else |
720 |
/*VARARGS*/ |
721 |
fatalerr(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9) |
722 |
char *msg; |
723 |
#endif |
724 |
{ |
725 |
#ifdef HAVE_STDARG_H /* NeedVarargsPrototypes */ |
726 |
va_list args; |
727 |
#endif |
728 |
fprintf(stderr, "%s: error: ", ProgramName); |
729 |
#ifdef HAVE_STDARG_H /* NeedVarargsPrototypes */ |
730 |
va_start(args, msg); |
731 |
vfprintf(stderr, msg, args); |
732 |
va_end(args); |
733 |
#else |
734 |
fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9); |
735 |
#endif |
736 |
exit (1); |
737 |
} |
738 |
|
739 |
#ifdef HAVE_STDARG_H /* NeedVarargsPrototypes */ |
740 |
warning(char *msg, ...) |
741 |
#else |
742 |
/*VARARGS0*/ |
743 |
warning(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9) |
744 |
char *msg; |
745 |
#endif |
746 |
{ |
747 |
#ifdef HAVE_STDARG_H /* NeedVarargsPrototypes */ |
748 |
va_list args; |
749 |
#endif |
750 |
fprintf(stderr, "%s: warning: ", ProgramName); |
751 |
#ifdef HAVE_STDARG_H /* NeedVarargsPrototypes */ |
752 |
va_start(args, msg); |
753 |
vfprintf(stderr, msg, args); |
754 |
va_end(args); |
755 |
#else |
756 |
fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9); |
757 |
#endif |
758 |
} |
759 |
|
760 |
#ifdef HAVE_STDARG_H /* NeedVarargsPrototypes */ |
761 |
warning1(char *msg, ...) |
762 |
#else |
763 |
/*VARARGS0*/ |
764 |
warning1(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9) |
765 |
char *msg; |
766 |
#endif |
767 |
{ |
768 |
#ifdef HAVE_STDARG_H /* NeedVarargsPrototypes */ |
769 |
va_list args; |
770 |
va_start(args, msg); |
771 |
vfprintf(stderr, msg, args); |
772 |
va_end(args); |
773 |
#else |
774 |
fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9); |
775 |
#endif |
776 |
} |