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

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

quiet option and objname option.

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