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

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

Don't require makefile to exist.

  • Property svn:eol-style set to native
File size: 19.1 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#ifdef __UNIXOS2__
390 {
391 char *emxinc = getenv("C_INCLUDE_PATH");
392 /* can have more than one component */
393 if (emxinc) {
394 char *beg, *end;
395 beg= (char*)strdup(emxinc);
396 for (;;) {
397 end = (char*)strchr(beg,';');
398 if (end) *end = 0;
399 if (incp >= includedirs + MAXDIRS)
400 fatalerr("Too many include dirs\n");
401 *incp++ = beg;
402 if (!end) break;
403 beg = end+1;
404 }
405 }
406 }
407#else /* !__UNIXOS2__, does not use INCLUDEDIR at all */
408 if (incp >= includedirs + MAXDIRS)
409 fatalerr("Too many -I flags.\n");
410 *incp++ = INCLUDEDIR;
411#endif
412
413#ifdef EXTRAINCDIR
414 if (incp >= includedirs + MAXDIRS)
415 fatalerr("Too many -I flags.\n");
416 *incp++ = EXTRAINCDIR;
417#endif
418
419#ifdef POSTINCDIR
420 if (incp >= includedirs + MAXDIRS)
421 fatalerr("Too many -I flags.\n");
422 *incp++ = POSTINCDIR;
423#endif
424 } else if (*defincdir) {
425 if (incp >= includedirs + MAXDIRS)
426 fatalerr("Too many -I flags.\n");
427 *incp++ = defincdir;
428 }
429
430 redirect(startat, makefile);
431
432 /*
433 * catch signals.
434 */
435#ifdef USGISH
436/* should really reset SIGINT to SIG_IGN if it was. */
437#ifdef SIGHUP
438 signal (SIGHUP, catch);
439#endif
440 signal (SIGINT, catch);
441#ifdef SIGQUIT
442 signal (SIGQUIT, catch);
443#endif
444 signal (SIGILL, catch);
445#ifdef SIGBUS
446 signal (SIGBUS, catch);
447#endif
448 signal (SIGSEGV, catch);
449#ifdef SIGSYS
450 signal (SIGSYS, catch);
451#endif
452#else
453 sig_act.sa_handler = catch;
454#if defined(_POSIX_SOURCE) || !defined(X_NOT_POSIX)
455 sigemptyset(&sig_act.sa_mask);
456 sigaddset(&sig_act.sa_mask, SIGINT);
457 sigaddset(&sig_act.sa_mask, SIGQUIT);
458#ifdef SIGBUS
459 sigaddset(&sig_act.sa_mask, SIGBUS);
460#endif
461 sigaddset(&sig_act.sa_mask, SIGILL);
462 sigaddset(&sig_act.sa_mask, SIGSEGV);
463 sigaddset(&sig_act.sa_mask, SIGHUP);
464 sigaddset(&sig_act.sa_mask, SIGPIPE);
465#ifdef SIGSYS
466 sigaddset(&sig_act.sa_mask, SIGSYS);
467#endif
468#else
469 sig_act.sa_mask = ((1<<(SIGINT -1))
470 |(1<<(SIGQUIT-1))
471#ifdef SIGBUS
472 |(1<<(SIGBUS-1))
473#endif
474 |(1<<(SIGILL-1))
475 |(1<<(SIGSEGV-1))
476 |(1<<(SIGHUP-1))
477 |(1<<(SIGPIPE-1))
478#ifdef SIGSYS
479 |(1<<(SIGSYS-1))
480#endif
481 );
482#endif /* _POSIX_SOURCE */
483 sig_act.sa_flags = 0;
484 sigaction(SIGHUP, &sig_act, (struct sigaction *)0);
485 sigaction(SIGINT, &sig_act, (struct sigaction *)0);
486 sigaction(SIGQUIT, &sig_act, (struct sigaction *)0);
487 sigaction(SIGILL, &sig_act, (struct sigaction *)0);
488#ifdef SIGBUS
489 sigaction(SIGBUS, &sig_act, (struct sigaction *)0);
490#endif
491 sigaction(SIGSEGV, &sig_act, (struct sigaction *)0);
492#ifdef SIGSYS
493 sigaction(SIGSYS, &sig_act, (struct sigaction *)0);
494#endif
495#endif /* USGISH */
496
497 /*
498 * now peruse through the list of files.
499 */
500 for(fp=filelist; *fp; fp++) {
501 DBG_PRINT(stderr,"file: %s\n",*fp);
502 filecontent = getfile(*fp);
503 setfile_cmdinc(filecontent, cmdinc_count, cmdinc_list);
504 ip = newinclude(*fp, (char *)NULL);
505
506 find_includes(filecontent, ip, ip, 0, FALSE);
507 freefile(filecontent);
508 recursive_pr_include(ip, ip->i_file, base_name(*fp));
509 inc_clean();
510 }
511 if (printed)
512 printf("\n");
513 return 0;
514}
515
516#ifdef __UNIXOS2__
517/*
518 * eliminate \r chars from file
519 */
520static int
521elim_cr(char *buf, int sz)
522{
523 int i,wp;
524 for (i= wp = 0; i<sz; i++) {
525 if (buf[i] != '\r')
526 buf[wp++] = buf[i];
527 }
528 return wp;
529}
530#endif
531
532struct filepointer *
533getfile(char *file)
534{
535 int fd;
536 struct filepointer *content;
537 struct stat st;
538
539 content = (struct filepointer *)malloc(sizeof(struct filepointer));
540 content->f_name = file;
541 if ((fd = open(file, O_RDONLY)) < 0) {
542 warning("cannot open \"%s\"\n", file);
543 content->f_p = content->f_base = content->f_end = (char *)malloc(1);
544 *content->f_p = '\0';
545 return(content);
546 }
547 fstat(fd, &st);
548 content->f_base = (char *)malloc(st.st_size+1);
549 if (content->f_base == NULL)
550 fatalerr("cannot allocate mem\n");
551 if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0)
552 fatalerr("failed to read %s\n", file);
553#ifdef __UNIXOS2__
554 st.st_size = elim_cr(content->f_base,st.st_size);
555#endif
556 close(fd);
557 content->f_len = st.st_size+1;
558 content->f_p = content->f_base;
559 content->f_end = content->f_base + st.st_size;
560 *content->f_end = '\0';
561 content->f_line = 0;
562 content->cmdinc_count = 0;
563 content->cmdinc_list = NULL;
564 content->cmdinc_line = 0;
565 return(content);
566}
567
568void
569setfile_cmdinc(struct filepointer* filep, long count, char** list)
570{
571 filep->cmdinc_count = count;
572 filep->cmdinc_list = list;
573 filep->cmdinc_line = 0;
574}
575
576void
577freefile(struct filepointer *fp)
578{
579 free(fp->f_base);
580 free(fp);
581}
582
583char *copy(char *str)
584{
585 char *p = (char *)malloc(strlen(str) + 1);
586
587 strcpy(p, str);
588 return(p);
589}
590
591int
592match(char *str, char **list)
593{
594 int i;
595
596 for (i=0; *list; i++, list++)
597 if (strcmp(str, *list) == 0)
598 return(i);
599 return(-1);
600}
601
602/*
603 * Get the next line. We only return lines beginning with '#' since that
604 * is all this program is ever interested in.
605 */
606char *getnextline(struct filepointer *filep)
607{
608 char *p, /* walking pointer */
609 *eof, /* end of file pointer */
610 *bol; /* beginning of line pointer */
611 int lineno; /* line number */
612 boolean whitespace = FALSE;
613
614 /*
615 * Fake the "-include" line files in form of #include to the
616 * start of each file.
617 */
618 if (filep->cmdinc_line < filep->cmdinc_count) {
619 char *inc = filep->cmdinc_list[2 * filep->cmdinc_line + 0];
620 char *buf = filep->cmdinc_list[2 * filep->cmdinc_line + 1];
621 filep->cmdinc_line++;
622 sprintf(buf,"%s%s%s",DASH_INC_PRE,inc,DASH_INC_POST);
623 DBG_PRINT(stderr,"%s\n",buf);
624 return(buf);
625 }
626
627 p = filep->f_p;
628 eof = filep->f_end;
629 if (p >= eof)
630 return((char *)NULL);
631 lineno = filep->f_line;
632
633 for (bol = p--; ++p < eof; ) {
634 if ((bol == p) && ((*p == ' ') || (*p == '\t')))
635 {
636 /* Consume leading white-spaces for this line */
637 while (((p+1) < eof) && ((*p == ' ') || (*p == '\t')))
638 {
639 p++;
640 bol++;
641 }
642 whitespace = TRUE;
643 }
644
645 if (*p == '/' && (p+1) < eof && *(p+1) == '*') {
646 /* Consume C comments */
647 *(p++) = ' ';
648 *(p++) = ' ';
649 while (p < eof && *p) {
650 if (*p == '*' && (p+1) < eof && *(p+1) == '/') {
651 *(p++) = ' ';
652 *(p++) = ' ';
653 break;
654 }
655 if (*p == '\n')
656 lineno++;
657 *(p++) = ' ';
658 }
659 --p;
660 }
661 else if (*p == '/' && (p+1) < eof && *(p+1) == '/') {
662 /* Consume C++ comments */
663 *(p++) = ' ';
664 *(p++) = ' ';
665 while (p < eof && *p) {
666 if (*p == '\\' && (p+1) < eof &&
667 *(p+1) == '\n') {
668 *(p++) = ' ';
669 lineno++;
670 }
671 else if (*p == '?' && (p+3) < eof &&
672 *(p+1) == '?' &&
673 *(p+2) == '/' &&
674 *(p+3) == '\n') {
675 *(p++) = ' ';
676 *(p++) = ' ';
677 *(p++) = ' ';
678 lineno++;
679 }
680 else if (*p == '\n')
681 break; /* to process end of line */
682 *(p++) = ' ';
683 }
684 --p;
685 }
686 else if (*p == '\\' && (p+1) < eof && *(p+1) == '\n') {
687 /* Consume backslash line terminations */
688 *(p++) = ' ';
689 *p = ' ';
690 lineno++;
691 }
692 else if (*p == '?' && (p+3) < eof &&
693 *(p+1) == '?' && *(p+2) == '/' && *(p+3) == '\n') {
694 /* Consume trigraph'ed backslash line terminations */
695 *(p++) = ' ';
696 *(p++) = ' ';
697 *(p++) = ' ';
698 *p = ' ';
699 lineno++;
700 }
701 else if (*p == '\n') {
702 lineno++;
703 if (*bol == '#') {
704 char *cp;
705
706 *(p++) = '\0';
707 /* punt lines with just # (yacc generated) */
708 for (cp = bol+1;
709 *cp && (*cp == ' ' || *cp == '\t'); cp++);
710 if (*cp) goto done;
711 --p;
712 }
713 bol = p+1;
714 whitespace = FALSE;
715 }
716 }
717 if (*bol != '#')
718 bol = NULL;
719done:
720 if (bol && whitespace) {
721 warning("%s: non-portable whitespace encountered at line %d\n",
722 filep->f_name, lineno);
723 }
724 filep->f_p = p;
725 filep->f_line = lineno;
726#ifdef DEBUG_DUMP
727 if (bol)
728 DBG_PRINT(stderr,"%s\n",bol);
729#endif
730 return(bol);
731}
732
733/*
734 * Strip the file name down to what we want to see in the Makefile.
735 * It will have objprefix and objsuffix around it.
736 */
737char *base_name(char *file)
738{
739 char *p;
740
741 file = copy(file);
742 for(p=file+strlen(file); p>file && *p != '.'; p--) ;
743
744 if (*p == '.')
745 *p = '\0';
746 return(file);
747}
748
749#if defined(USG) && !defined(CRAY) && !defined(SVR4) && !defined(__UNIXOS2__) && !defined(clipper) && !defined(__clipper__)
750int rename (char *from, char *to)
751{
752 (void) unlink (to);
753 if (link (from, to) == 0) {
754 unlink (from);
755 return 0;
756 } else {
757 return -1;
758 }
759}
760#endif /* USGISH */
761
762void
763redirect(char *line, char *makefile)
764{
765 struct stat st;
766 FILE *fdin, *fdout;
767 char backup[ BUFSIZ ],
768 buf[ BUFSIZ ];
769 boolean found = FALSE;
770 int len;
771
772 /*
773 * if makefile is "-" then let it pour onto stdout.
774 */
775 if (makefile && *makefile == '-' && *(makefile+1) == '\0') {
776 puts(line);
777 return;
778 }
779
780 /*
781 * use a default makefile is not specified.
782 */
783 if (!makefile) {
784 if (stat("Makefile", &st) == 0)
785 makefile = "Makefile";
786 else if (stat("makefile", &st) == 0)
787 makefile = "makefile";
788 else
789 fatalerr("[mM]akefile is not present\n");
790 }
791 else
792 stat(makefile, &st);
793 if ((fdin = fopen(makefile, "r")) == NULL) { /* bird */
794 if (!stat(makefile, &st))
795 fatalerr("cannot open \"%s\"\n", makefile);
796 /* create the file */
797 if ((fdout = freopen(makefile, "w", stdout)) == NULL)
798 fatalerr("cannot create \"%s\"\n", makefile);
799 puts(line);
800 fflush(fdout);
801 return;
802 }
803 sprintf(backup, "%s.bak", makefile);
804 unlink(backup);
805#if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__)
806 fclose(fdin);
807#endif
808 if (rename(makefile, backup) < 0)
809 fatalerr("cannot rename %s to %s\n", makefile, backup);
810#if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__)
811 if ((fdin = fopen(backup, "r")) == NULL)
812 fatalerr("cannot open \"%s\"\n", backup);
813#endif
814 if ((fdout = freopen(makefile, "w", stdout)) == NULL)
815 fatalerr("cannot open \"%s\"\n", backup);
816 len = strlen(line);
817 while (!found && fgets(buf, BUFSIZ, fdin)) {
818 if (*buf == '#' && strncmp(line, buf, len) == 0)
819 found = TRUE;
820 fputs(buf, fdout);
821 }
822 if (!found) {
823 if (verbose)
824 warning("Adding new delimiting line \"%s\" and dependencies...\n",
825 line);
826 puts(line); /* same as fputs(fdout); but with newline */
827 } else if (append) {
828 while (fgets(buf, BUFSIZ, fdin)) {
829 fputs(buf, fdout);
830 }
831 }
832 fflush(fdout);
833#if defined(USGISH) || defined(_SEQUENT_) || defined(USE_CHMOD)
834 chmod(makefile, st.st_mode);
835#else
836 fchmod(fileno(fdout), st.st_mode);
837#endif /* USGISH */
838}
839
840void
841fatalerr(char *msg, ...)
842{
843 va_list args;
844 fprintf(stderr, "%s: error: ", ProgramName);
845 va_start(args, msg);
846 vfprintf(stderr, msg, args);
847 va_end(args);
848 exit (1);
849}
850
851void
852warning(char *msg, ...)
853{
854 va_list args;
855 fprintf(stderr, "%s: warning: ", ProgramName);
856 va_start(args, msg);
857 vfprintf(stderr, msg, args);
858 va_end(args);
859}
860
861void
862warning1(char *msg, ...)
863{
864 va_list args;
865 va_start(args, msg);
866 vfprintf(stderr, msg, args);
867 va_end(args);
868}
Note: See TracBrowser for help on using the repository browser.