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