source: trunk/src/makedep/main.c@ 170

Last change on this file since 170 was 170, checked in by bird, 21 years ago

fixed includedir

  • Property svn:eol-style set to native
File size: 19.2 KB
Line 
1/* $Xorg: main.c,v 1.5 2001/02/09 02:03:16 xorgcvs Exp $ */
2/*
3
4Copyright (c) 1993, 1994, 1998 The Open Group
5
6Permission to use, copy, modify, distribute, and sell this software and its
7documentation for any purpose is hereby granted without fee, provided that
8the above copyright notice appear in all copies and that both that
9copyright notice and this permission notice appear in supporting
10documentation.
11
12The above copyright notice and this permission notice shall be included in
13all copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall not be
23used in advertising or otherwise to promote the sale, use or other dealings
24in this Software without prior written authorization from The Open Group.
25
26*/
27/* $XFree86: xc/config/makedepend/main.c,v 3.31tsi Exp $ */
28
29#include "def.h"
30#ifdef hpux
31#define sigvec sigvector
32#endif /* hpux */
33
34#ifdef X_POSIX_C_SOURCE
35#define _POSIX_C_SOURCE X_POSIX_C_SOURCE
36#include <signal.h>
37#undef _POSIX_C_SOURCE
38#else
39#if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
40#include <signal.h>
41#else
42#define _POSIX_SOURCE
43#include <signal.h>
44#undef _POSIX_SOURCE
45#endif
46#endif
47
48#include <stdarg.h>
49
50#ifdef MINIX
51#define USE_CHMOD 1
52#endif
53
54#ifdef DEBUG
55int _debugmask;
56#endif
57
58/* #define DEBUG_DUMP */
59#ifdef DEBUG_DUMP
60#define DBG_PRINT(file, fmt, args) fprintf(file, fmt, args)
61#else
62#define DBG_PRINT(file, fmt, args) /* empty */
63#endif
64
65#define DASH_INC_PRE "#include \""
66#define DASH_INC_POST "\""
67
68char *ProgramName;
69
70char *directives[] = {
71 "if",
72 "ifdef",
73 "ifndef",
74 "else",
75 "endif",
76 "define",
77 "undef",
78 "include",
79 "line",
80 "pragma",
81 "error",
82 "ident",
83 "sccs",
84 "elif",
85 "eject",
86 "warning",
87 "include_next",
88 NULL
89};
90
91#define MAKEDEPEND
92#include "imakemdep.h" /* from config sources */
93#undef MAKEDEPEND
94
95struct inclist inclist[ MAXFILES ],
96 *inclistp = inclist,
97 *inclistnext = inclist,
98 maininclist;
99
100static char *filelist[ MAXFILES ];
101char *includedirs[ MAXDIRS + 1 ],
102 **includedirsnext = includedirs;
103char *notdotdot[ MAXDIRS ];
104static int cmdinc_count = 0;
105static char *cmdinc_list[ 2 * MAXINCFILES ];
106char *objprefix = "";
107char *objsuffix = OBJSUFFIX;
108static char *startat = "# DO NOT DELETE";
109int width = 78;
110static boolean append = FALSE;
111boolean printed = FALSE;
112boolean verbose = FALSE;
113boolean show_where_not = FALSE;
114/* Warn on multiple includes of same file */
115boolean warn_multiple = FALSE;
116
117static void setfile_cmdinc(struct filepointer *filep, long count, char **list);
118static void redirect(char *line, char *makefile);
119
120static
121#ifdef SIGNALRETURNSINT
122int
123#else
124void
125#endif
126catch (int sig)
127{
128 fflush (stdout);
129 fatalerr ("got signal %d\n", sig);
130}
131
132#if defined(USG) || (defined(i386) && defined(SYSV)) || defined(WIN32) || defined(__UNIXOS2__) || defined(Lynx_22) || defined(__CYGWIN__)
133#define USGISH
134#endif
135
136#ifndef USGISH
137#ifdef X_NOT_POSIX
138#define sigaction sigvec
139#define sa_handler sv_handler
140#define sa_mask sv_mask
141#define sa_flags sv_flags
142#endif
143struct sigaction sig_act;
144#endif /* USGISH */
145
146int
147main(int argc, char *argv[])
148{
149 char **fp = filelist;
150 char **incp = includedirs;
151 char *p;
152 struct inclist *ip;
153 char *makefile = NULL;
154 struct filepointer *filecontent;
155 struct symtab *psymp = predefs;
156 char *endmarker = NULL;
157 char *defincdir = NULL;
158 char **undeflist = NULL;
159 int numundefs = 0, i;
160 register char offset; /* mozilla */
161
162 ProgramName = argv[0];
163
164 while (psymp->s_name)
165 {
166 define2(psymp->s_name, psymp->s_value, &maininclist);
167 psymp++;
168 }
169 if (argc == 2 && argv[1][0] == '@') {
170 struct stat ast;
171 int afd;
172 char *args;
173 char **nargv;
174 int nargc;
175 char quotechar = '\0';
176
177 nargc = 1;
178 if ((afd = open(argv[1]+1, O_RDONLY)) < 0)
179 fatalerr("cannot open \"%s\"\n", argv[1]+1);
180 fstat(afd, &ast);
181 args = (char *)malloc(ast.st_size + 1);
182 if ((ast.st_size = read(afd, args, ast.st_size)) < 0)
183 fatalerr("failed to read %s\n", argv[1]+1);
184 args[ast.st_size] = '\0';
185 close(afd);
186 for (p = args; *p; p++) {
187 if (quotechar) {
188 if (quotechar == '\\' ||
189 (*p == quotechar && p[-1] != '\\'))
190 quotechar = '\0';
191 continue;
192 }
193 switch (*p) {
194 case '\\':
195 case '"':
196 case '\'':
197 quotechar = *p;
198 break;
199 case ' ':
200 case '\n':
201 *p = '\0';
202 if (p > args && p[-1])
203 nargc++;
204 break;
205 }
206 }
207 if (p[-1])
208 nargc++;
209 nargv = (char **)malloc(nargc * sizeof(char *));
210 nargv[0] = argv[0];
211 argc = 1;
212 for (p = args; argc < nargc; p += strlen(p) + 1)
213 if (*p) nargv[argc++] = p;
214 argv = nargv;
215 }
216 for(argc--, argv++; argc; argc--, argv++) {
217 /* if looking for endmarker then check before parsing */
218 if (endmarker && strcmp (endmarker, *argv) == 0) {
219 endmarker = NULL;
220 continue;
221 }
222 if (**argv != '-') {
223 /* treat +thing as an option for C++ */
224 if (endmarker && **argv == '+')
225 continue;
226 *fp++ = argv[0];
227 continue;
228 }
229 switch(argv[0][1]) {
230 case '-':
231 endmarker = &argv[0][2];
232 if (endmarker[0] == '\0') endmarker = "--";
233 break;
234 case 'D':
235 offset = 2; /* mozilla */
236 if (argv[0][2] == '\0') {
237 argv++;
238 argc--;
239 offset = 0;
240 }
241 /* offset +1 here since first def letter
242 * cannot be `=`
243 */
244 for (p = argv[0] + offset + 1; *p; p++) /* mozilla */
245 if (*p == '=') {
246 *p = ' ';
247 break;
248 }
249 define(argv[0] + offset, &maininclist); /* mozilla */
250 break;
251 case 'I':
252 if (incp >= includedirs + MAXDIRS)
253 fatalerr("Too many -I flags.\n");
254 *incp++ = argv[0]+2;
255 if (**(incp-1) == '\0') {
256 *(incp-1) = *(++argv);
257 argc--;
258 }
259 break;
260 case 'U':
261 /* Undef's override all -D's so save them up */
262 numundefs++;
263 if (numundefs == 1)
264 undeflist = malloc(sizeof(char *));
265 else
266 undeflist = realloc(undeflist,
267 numundefs * sizeof(char *));
268 offset = 2; /* mozilla */
269 if (argv[0][2] == '\0') {
270 argv++;
271 argc--;
272 offset = 0; /* mozilla */
273 }
274 undeflist[numundefs - 1] = argv[0] + offset; /* mozilla */
275 break;
276 case 'Y':
277 defincdir = argv[0]+2;
278 break;
279 /* do not use if endmarker processing */
280 case 'a':
281 if (endmarker) break;
282 append = TRUE;
283 break;
284 case 'w':
285 if (endmarker) break;
286 if (argv[0][2] == '\0') {
287 argv++;
288 argc--;
289 width = atoi(argv[0]);
290 } else
291 width = atoi(argv[0]+2);
292 break;
293 case 'o':
294 if (endmarker) break;
295 if (argv[0][2] == '\0') {
296 argv++;
297 argc--;
298 objsuffix = argv[0];
299 } else
300 objsuffix = argv[0]+2;
301 break;
302 case 'p':
303 if (endmarker) break;
304 if (argv[0][2] == '\0') {
305 argv++;
306 argc--;
307 objprefix = argv[0];
308 } else
309 objprefix = argv[0]+2;
310 break;
311 case 'v':
312 if (endmarker) break;
313 verbose = TRUE;
314#ifdef DEBUG
315 if (argv[0][2])
316 _debugmask = atoi(argv[0]+2);
317#endif
318 break;
319 case 's':
320 if (endmarker) break;
321 startat = argv[0]+2;
322 if (*startat == '\0') {
323 startat = *(++argv);
324 argc--;
325 }
326 if (*startat != '#')
327 fatalerr("-s flag's value should start %s\n",
328 "with '#'.");
329 break;
330 case 'f':
331 if (endmarker) break;
332 makefile = argv[0]+2;
333 if (*makefile == '\0') {
334 makefile = *(++argv);
335 argc--;
336 }
337 break;
338
339 case 'm':
340 warn_multiple = TRUE;
341 break;
342
343 /* Ignore -O, -g so we can just pass ${CFLAGS} to
344 makedepend
345 */
346 case 'O':
347 case 'g':
348 break;
349 case 'i':
350 if (strcmp(&argv[0][1],"include") == 0) {
351 char *buf;
352 if (argc<2)
353 fatalerr("option -include is a "
354 "missing its parameter\n");
355 if (cmdinc_count >= MAXINCFILES)
356 fatalerr("Too many -include flags.\n");
357 argc--;
358 argv++;
359 buf = malloc(strlen(DASH_INC_PRE) +
360 strlen(argv[0]) +
361 strlen(DASH_INC_POST) + 1);
362 if(!buf)
363 fatalerr("out of memory at "
364 "-include string\n");
365 cmdinc_list[2 * cmdinc_count + 0] = argv[0];
366 cmdinc_list[2 * cmdinc_count + 1] = buf;
367 cmdinc_count++;
368 break;
369 }
370 /* intentional fall through */
371 default:
372 if (endmarker) break;
373 /* fatalerr("unknown opt = %s\n", argv[0]); */
374 warning("ignoring option %s\n", argv[0]);
375 }
376 }
377 /* Now do the undefs from the command line */
378 for (i = 0; i < numundefs; i++)
379 undefine(undeflist[i], &maininclist);
380 if (numundefs > 0)
381 free(undeflist);
382
383 if (!defincdir) {
384#ifdef PREINCDIR
385 if (incp >= includedirs + MAXDIRS)
386 fatalerr("Too many -I flags.\n");
387 *incp++ = PREINCDIR;
388#endif
389
390// This is bull, all gcc versions use this - OS/2 is not special case.
391//#ifdef __UNIXOS2__
392// {
393// char *emxinc = getenv("C_INCLUDE_PATH");
394// /* can have more than one component */
395// if (emxinc) {
396// char *beg, *end;
397// beg= (char*)strdup(emxinc);
398// for (;;) {
399// end = (char*)strchr(beg,';');
400// if (end) *end = 0;
401// if (incp >= includedirs + MAXDIRS)
402// fatalerr("Too many include dirs\n");
403// *incp++ = beg;
404// if (!end) break;
405// beg = end+1;
406// }
407// }
408// }
409//#else /* !__UNIXOS2__, does not use INCLUDEDIR at all */
410#ifdef INCLUDEDIR /* bird */
411 if (incp >= includedirs + MAXDIRS)
412 fatalerr("Too many -I flags.\n");
413 *incp++ = INCLUDEDIR;
414#endif
415//#endif
416
417#ifdef EXTRAINCDIR
418 if (incp >= includedirs + MAXDIRS)
419 fatalerr("Too many -I flags.\n");
420 *incp++ = EXTRAINCDIR;
421#endif
422
423#ifdef POSTINCDIR
424 if (incp >= includedirs + MAXDIRS)
425 fatalerr("Too many -I flags.\n");
426 *incp++ = POSTINCDIR;
427#endif
428 } else if (*defincdir) {
429 if (incp >= includedirs + MAXDIRS)
430 fatalerr("Too many -I flags.\n");
431 *incp++ = defincdir;
432 }
433
434 redirect(startat, makefile);
435
436 /*
437 * catch signals.
438 */
439#ifdef USGISH
440/* should really reset SIGINT to SIG_IGN if it was. */
441#ifdef SIGHUP
442 signal (SIGHUP, catch);
443#endif
444 signal (SIGINT, catch);
445#ifdef SIGQUIT
446 signal (SIGQUIT, catch);
447#endif
448 signal (SIGILL, catch);
449#ifdef SIGBUS
450 signal (SIGBUS, catch);
451#endif
452 signal (SIGSEGV, catch);
453#ifdef SIGSYS
454 signal (SIGSYS, catch);
455#endif
456#else
457 sig_act.sa_handler = catch;
458#if defined(_POSIX_SOURCE) || !defined(X_NOT_POSIX)
459 sigemptyset(&sig_act.sa_mask);
460 sigaddset(&sig_act.sa_mask, SIGINT);
461 sigaddset(&sig_act.sa_mask, SIGQUIT);
462#ifdef SIGBUS
463 sigaddset(&sig_act.sa_mask, SIGBUS);
464#endif
465 sigaddset(&sig_act.sa_mask, SIGILL);
466 sigaddset(&sig_act.sa_mask, SIGSEGV);
467 sigaddset(&sig_act.sa_mask, SIGHUP);
468 sigaddset(&sig_act.sa_mask, SIGPIPE);
469#ifdef SIGSYS
470 sigaddset(&sig_act.sa_mask, SIGSYS);
471#endif
472#else
473 sig_act.sa_mask = ((1<<(SIGINT -1))
474 |(1<<(SIGQUIT-1))
475#ifdef SIGBUS
476 |(1<<(SIGBUS-1))
477#endif
478 |(1<<(SIGILL-1))
479 |(1<<(SIGSEGV-1))
480 |(1<<(SIGHUP-1))
481 |(1<<(SIGPIPE-1))
482#ifdef SIGSYS
483 |(1<<(SIGSYS-1))
484#endif
485 );
486#endif /* _POSIX_SOURCE */
487 sig_act.sa_flags = 0;
488 sigaction(SIGHUP, &sig_act, (struct sigaction *)0);
489 sigaction(SIGINT, &sig_act, (struct sigaction *)0);
490 sigaction(SIGQUIT, &sig_act, (struct sigaction *)0);
491 sigaction(SIGILL, &sig_act, (struct sigaction *)0);
492#ifdef SIGBUS
493 sigaction(SIGBUS, &sig_act, (struct sigaction *)0);
494#endif
495 sigaction(SIGSEGV, &sig_act, (struct sigaction *)0);
496#ifdef SIGSYS
497 sigaction(SIGSYS, &sig_act, (struct sigaction *)0);
498#endif
499#endif /* USGISH */
500
501 /*
502 * now peruse through the list of files.
503 */
504 for(fp=filelist; *fp; fp++) {
505 DBG_PRINT(stderr,"file: %s\n",*fp);
506 filecontent = getfile(*fp);
507 setfile_cmdinc(filecontent, cmdinc_count, cmdinc_list);
508 ip = newinclude(*fp, (char *)NULL);
509
510 find_includes(filecontent, ip, ip, 0, FALSE);
511 freefile(filecontent);
512 recursive_pr_include(ip, ip->i_file, base_name(*fp));
513 inc_clean();
514 }
515 if (printed)
516 printf("\n");
517 return 0;
518}
519
520#ifdef __UNIXOS2__
521/*
522 * eliminate \r chars from file
523 */
524static int
525elim_cr(char *buf, int sz)
526{
527 int i,wp;
528 for (i= wp = 0; i<sz; i++) {
529 if (buf[i] != '\r')
530 buf[wp++] = buf[i];
531 }
532 return wp;
533}
534#endif
535
536struct filepointer *
537getfile(char *file)
538{
539 int fd;
540 struct filepointer *content;
541 struct stat st;
542
543 content = (struct filepointer *)malloc(sizeof(struct filepointer));
544 content->f_name = file;
545 if ((fd = open(file, O_RDONLY)) < 0) {
546 warning("cannot open \"%s\"\n", file);
547 content->f_p = content->f_base = content->f_end = (char *)malloc(1);
548 *content->f_p = '\0';
549 return(content);
550 }
551 fstat(fd, &st);
552 content->f_base = (char *)malloc(st.st_size+1);
553 if (content->f_base == NULL)
554 fatalerr("cannot allocate mem\n");
555 if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0)
556 fatalerr("failed to read %s\n", file);
557#ifdef __UNIXOS2__
558 st.st_size = elim_cr(content->f_base,st.st_size);
559#endif
560 close(fd);
561 content->f_len = st.st_size+1;
562 content->f_p = content->f_base;
563 content->f_end = content->f_base + st.st_size;
564 *content->f_end = '\0';
565 content->f_line = 0;
566 content->cmdinc_count = 0;
567 content->cmdinc_list = NULL;
568 content->cmdinc_line = 0;
569 return(content);
570}
571
572void
573setfile_cmdinc(struct filepointer* filep, long count, char** list)
574{
575 filep->cmdinc_count = count;
576 filep->cmdinc_list = list;
577 filep->cmdinc_line = 0;
578}
579
580void
581freefile(struct filepointer *fp)
582{
583 free(fp->f_base);
584 free(fp);
585}
586
587char *copy(char *str)
588{
589 char *p = (char *)malloc(strlen(str) + 1);
590
591 strcpy(p, str);
592 return(p);
593}
594
595int
596match(char *str, char **list)
597{
598 int i;
599
600 for (i=0; *list; i++, list++)
601 if (strcmp(str, *list) == 0)
602 return(i);
603 return(-1);
604}
605
606/*
607 * Get the next line. We only return lines beginning with '#' since that
608 * is all this program is ever interested in.
609 */
610char *getnextline(struct filepointer *filep)
611{
612 char *p, /* walking pointer */
613 *eof, /* end of file pointer */
614 *bol; /* beginning of line pointer */
615 int lineno; /* line number */
616 boolean whitespace = FALSE;
617
618 /*
619 * Fake the "-include" line files in form of #include to the
620 * start of each file.
621 */
622 if (filep->cmdinc_line < filep->cmdinc_count) {
623 char *inc = filep->cmdinc_list[2 * filep->cmdinc_line + 0];
624 char *buf = filep->cmdinc_list[2 * filep->cmdinc_line + 1];
625 filep->cmdinc_line++;
626 sprintf(buf,"%s%s%s",DASH_INC_PRE,inc,DASH_INC_POST);
627 DBG_PRINT(stderr,"%s\n",buf);
628 return(buf);
629 }
630
631 p = filep->f_p;
632 eof = filep->f_end;
633 if (p >= eof)
634 return((char *)NULL);
635 lineno = filep->f_line;
636
637 for (bol = p--; ++p < eof; ) {
638 if ((bol == p) && ((*p == ' ') || (*p == '\t')))
639 {
640 /* Consume leading white-spaces for this line */
641 while (((p+1) < eof) && ((*p == ' ') || (*p == '\t')))
642 {
643 p++;
644 bol++;
645 }
646 whitespace = TRUE;
647 }
648
649 if (*p == '/' && (p+1) < eof && *(p+1) == '*') {
650 /* Consume C comments */
651 *(p++) = ' ';
652 *(p++) = ' ';
653 while (p < eof && *p) {
654 if (*p == '*' && (p+1) < eof && *(p+1) == '/') {
655 *(p++) = ' ';
656 *(p++) = ' ';
657 break;
658 }
659 if (*p == '\n')
660 lineno++;
661 *(p++) = ' ';
662 }
663 --p;
664 }
665 else if (*p == '/' && (p+1) < eof && *(p+1) == '/') {
666 /* Consume C++ comments */
667 *(p++) = ' ';
668 *(p++) = ' ';
669 while (p < eof && *p) {
670 if (*p == '\\' && (p+1) < eof &&
671 *(p+1) == '\n') {
672 *(p++) = ' ';
673 lineno++;
674 }
675 else if (*p == '?' && (p+3) < eof &&
676 *(p+1) == '?' &&
677 *(p+2) == '/' &&
678 *(p+3) == '\n') {
679 *(p++) = ' ';
680 *(p++) = ' ';
681 *(p++) = ' ';
682 lineno++;
683 }
684 else if (*p == '\n')
685 break; /* to process end of line */
686 *(p++) = ' ';
687 }
688 --p;
689 }
690 else if (*p == '\\' && (p+1) < eof && *(p+1) == '\n') {
691 /* Consume backslash line terminations */
692 *(p++) = ' ';
693 *p = ' ';
694 lineno++;
695 }
696 else if (*p == '?' && (p+3) < eof &&
697 *(p+1) == '?' && *(p+2) == '/' && *(p+3) == '\n') {
698 /* Consume trigraph'ed backslash line terminations */
699 *(p++) = ' ';
700 *(p++) = ' ';
701 *(p++) = ' ';
702 *p = ' ';
703 lineno++;
704 }
705 else if (*p == '\n') {
706 lineno++;
707 if (*bol == '#') {
708 char *cp;
709
710 *(p++) = '\0';
711 /* punt lines with just # (yacc generated) */
712 for (cp = bol+1;
713 *cp && (*cp == ' ' || *cp == '\t'); cp++);
714 if (*cp) goto done;
715 --p;
716 }
717 bol = p+1;
718 whitespace = FALSE;
719 }
720 }
721 if (*bol != '#')
722 bol = NULL;
723done:
724 if (bol && whitespace) {
725 warning("%s: non-portable whitespace encountered at line %d\n",
726 filep->f_name, lineno);
727 }
728 filep->f_p = p;
729 filep->f_line = lineno;
730#ifdef DEBUG_DUMP
731 if (bol)
732 DBG_PRINT(stderr,"%s\n",bol);
733#endif
734 return(bol);
735}
736
737/*
738 * Strip the file name down to what we want to see in the Makefile.
739 * It will have objprefix and objsuffix around it.
740 */
741char *base_name(char *file)
742{
743 char *p;
744
745 file = copy(file);
746 for(p=file+strlen(file); p>file && *p != '.'; p--) ;
747
748 if (*p == '.')
749 *p = '\0';
750 return(file);
751}
752
753#if defined(USG) && !defined(CRAY) && !defined(SVR4) && !defined(__UNIXOS2__) && !defined(clipper) && !defined(__clipper__)
754int rename (char *from, char *to)
755{
756 (void) unlink (to);
757 if (link (from, to) == 0) {
758 unlink (from);
759 return 0;
760 } else {
761 return -1;
762 }
763}
764#endif /* USGISH */
765
766void
767redirect(char *line, char *makefile)
768{
769 struct stat st;
770 FILE *fdin, *fdout;
771 char backup[ BUFSIZ ],
772 buf[ BUFSIZ ];
773 boolean found = FALSE;
774 int len;
775
776 /*
777 * if makefile is "-" then let it pour onto stdout.
778 */
779 if (makefile && *makefile == '-' && *(makefile+1) == '\0') {
780 puts(line);
781 return;
782 }
783
784 /*
785 * use a default makefile is not specified.
786 */
787 if (!makefile) {
788 if (stat("Makefile", &st) == 0)
789 makefile = "Makefile";
790 else if (stat("makefile", &st) == 0)
791 makefile = "makefile";
792 else
793 fatalerr("[mM]akefile is not present\n");
794 }
795 else
796 stat(makefile, &st);
797 if ((fdin = fopen(makefile, "r")) == NULL) { /* bird */
798 if (!stat(makefile, &st))
799 fatalerr("cannot open \"%s\"\n", makefile);
800 /* create the file */
801 if ((fdout = freopen(makefile, "w", stdout)) == NULL)
802 fatalerr("cannot create \"%s\"\n", makefile);
803 puts(line);
804 fflush(fdout);
805 return;
806 }
807 sprintf(backup, "%s.bak", makefile);
808 unlink(backup);
809#if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__)
810 fclose(fdin);
811#endif
812 if (rename(makefile, backup) < 0)
813 fatalerr("cannot rename %s to %s\n", makefile, backup);
814#if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__)
815 if ((fdin = fopen(backup, "r")) == NULL)
816 fatalerr("cannot open \"%s\"\n", backup);
817#endif
818 if ((fdout = freopen(makefile, "w", stdout)) == NULL)
819 fatalerr("cannot open \"%s\"\n", backup);
820 len = strlen(line);
821 while (!found && fgets(buf, BUFSIZ, fdin)) {
822 if (*buf == '#' && strncmp(line, buf, len) == 0)
823 found = TRUE;
824 fputs(buf, fdout);
825 }
826 if (!found) {
827 if (verbose)
828 warning("Adding new delimiting line \"%s\" and dependencies...\n",
829 line);
830 puts(line); /* same as fputs(fdout); but with newline */
831 } else if (append) {
832 while (fgets(buf, BUFSIZ, fdin)) {
833 fputs(buf, fdout);
834 }
835 }
836 fflush(fdout);
837#if defined(USGISH) || defined(_SEQUENT_) || defined(USE_CHMOD)
838 chmod(makefile, st.st_mode);
839#else
840 fchmod(fileno(fdout), st.st_mode);
841#endif /* USGISH */
842}
843
844void
845fatalerr(char *msg, ...)
846{
847 va_list args;
848 fprintf(stderr, "%s: error: ", ProgramName);
849 va_start(args, msg);
850 vfprintf(stderr, msg, args);
851 va_end(args);
852 exit (1);
853}
854
855void
856warning(char *msg, ...)
857{
858 va_list args;
859 fprintf(stderr, "%s: warning: ", ProgramName);
860 va_start(args, msg);
861 vfprintf(stderr, msg, args);
862 va_end(args);
863}
864
865void
866warning1(char *msg, ...)
867{
868 va_list args;
869 va_start(args, msg);
870 vfprintf(stderr, msg, args);
871 va_end(args);
872}
Note: See TracBrowser for help on using the repository browser.