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