1 /* $NetBSD: parse.c,v 1.286 2020/09/06 19:34:36 rillig Exp $ */ 2 3 /* 4 * Copyright (c) 1988, 1989, 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Adam de Boor. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 /* 36 * Copyright (c) 1989 by Berkeley Softworks 37 * All rights reserved. 38 * 39 * This code is derived from software contributed to Berkeley by 40 * Adam de Boor. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. All advertising materials mentioning features or use of this software 51 * must display the following acknowledgement: 52 * This product includes software developed by the University of 53 * California, Berkeley and its contributors. 54 * 4. Neither the name of the University nor the names of its contributors 55 * may be used to endorse or promote products derived from this software 56 * without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 */ 70 71 #ifndef MAKE_NATIVE 72 static char rcsid[] = "$NetBSD: parse.c,v 1.286 2020/09/06 19:34:36 rillig Exp $"; 73 #else 74 #include <sys/cdefs.h> 75 #ifndef lint 76 #if 0 77 static char sccsid[] = "@(#)parse.c 8.3 (Berkeley) 3/19/94"; 78 #else 79 __RCSID("$NetBSD: parse.c,v 1.286 2020/09/06 19:34:36 rillig Exp $"); 80 #endif 81 #endif /* not lint */ 82 #endif 83 84 /*- 85 * parse.c -- 86 * Functions to parse a makefile. 87 * 88 * One function, Parse_Init, must be called before any functions 89 * in this module are used. After that, the function Parse_File is the 90 * main entry point and controls most of the other functions in this 91 * module. 92 * 93 * Most important structures are kept in Lsts. Directories for 94 * the .include "..." function are kept in the 'parseIncPath' Lst, while 95 * those for the .include <...> are kept in the 'sysIncPath' Lst. The 96 * targets currently being defined are kept in the 'targets' Lst. 97 * 98 * The variables 'fname' and 'lineno' are used to track the name 99 * of the current file and the line number in that file so that error 100 * messages can be more meaningful. 101 * 102 * Interface: 103 * Parse_Init Initialization function which must be 104 * called before anything else in this module 105 * is used. 106 * 107 * Parse_End Cleanup the module 108 * 109 * Parse_File Function used to parse a makefile. It must 110 * be given the name of the file, which should 111 * already have been opened, and a function 112 * to call to read a character from the file. 113 * 114 * Parse_IsVar Returns TRUE if the given line is a 115 * variable assignment. Used by MainParseArgs 116 * to determine if an argument is a target 117 * or a variable assignment. Used internally 118 * for pretty much the same thing... 119 * 120 * Parse_Error Function called when an error occurs in 121 * parsing. Used by the variable and 122 * conditional modules. 123 * Parse_MainName Returns a Lst of the main target to create. 124 */ 125 126 #include <sys/types.h> 127 #include <sys/mman.h> 128 #include <sys/stat.h> 129 #include <errno.h> 130 #include <stdarg.h> 131 #include <stdio.h> 132 #include <stdint.h> 133 134 #ifndef MAP_FILE 135 #define MAP_FILE 0 136 #endif 137 #ifndef MAP_COPY 138 #define MAP_COPY MAP_PRIVATE 139 #endif 140 141 #include "make.h" 142 #include "dir.h" 143 #include "job.h" 144 #include "pathnames.h" 145 146 /* types and constants */ 147 148 /* 149 * Structure for a file being read ("included file") 150 */ 151 typedef struct IFile { 152 char *fname; /* name of file */ 153 Boolean fromForLoop; /* simulated .include by the .for loop */ 154 int lineno; /* current line number in file */ 155 int first_lineno; /* line number of start of text */ 156 int cond_depth; /* 'if' nesting when file opened */ 157 Boolean depending; /* state of doing_depend on EOF */ 158 char *P_str; /* point to base of string buffer */ 159 char *P_ptr; /* point to next char of string buffer */ 160 char *P_end; /* point to the end of string buffer */ 161 char *(*nextbuf)(void *, size_t *); /* Function to get more data */ 162 void *nextbuf_arg; /* Opaque arg for nextbuf() */ 163 struct loadedfile *lf; /* loadedfile object, if any */ 164 } IFile; 165 166 167 /* 168 * These values are returned by ParseEOF to tell Parse_File whether to 169 * CONTINUE parsing, i.e. it had only reached the end of an include file, 170 * or if it's DONE. 171 */ 172 #define CONTINUE 1 173 #define DONE 0 174 175 /* 176 * Tokens for target attributes 177 */ 178 typedef enum { 179 Begin, /* .BEGIN */ 180 Default, /* .DEFAULT */ 181 DeleteOnError, /* .DELETE_ON_ERROR */ 182 End, /* .END */ 183 dotError, /* .ERROR */ 184 Ignore, /* .IGNORE */ 185 Includes, /* .INCLUDES */ 186 Interrupt, /* .INTERRUPT */ 187 Libs, /* .LIBS */ 188 Meta, /* .META */ 189 MFlags, /* .MFLAGS or .MAKEFLAGS */ 190 Main, /* .MAIN and we don't have anything user-specified to 191 * make */ 192 NoExport, /* .NOEXPORT */ 193 NoMeta, /* .NOMETA */ 194 NoMetaCmp, /* .NOMETA_CMP */ 195 NoPath, /* .NOPATH */ 196 Not, /* Not special */ 197 NotParallel, /* .NOTPARALLEL */ 198 Null, /* .NULL */ 199 ExObjdir, /* .OBJDIR */ 200 Order, /* .ORDER */ 201 Parallel, /* .PARALLEL */ 202 ExPath, /* .PATH */ 203 Phony, /* .PHONY */ 204 #ifdef POSIX 205 Posix, /* .POSIX */ 206 #endif 207 Precious, /* .PRECIOUS */ 208 ExShell, /* .SHELL */ 209 Silent, /* .SILENT */ 210 SingleShell, /* .SINGLESHELL */ 211 Stale, /* .STALE */ 212 Suffixes, /* .SUFFIXES */ 213 Wait, /* .WAIT */ 214 Attribute /* Generic attribute */ 215 } ParseSpecial; 216 217 /* 218 * Other tokens 219 */ 220 #define LPAREN '(' 221 #define RPAREN ')' 222 223 224 /* result data */ 225 226 /* 227 * The main target to create. This is the first target on the first 228 * dependency line in the first makefile. 229 */ 230 static GNode *mainNode; 231 232 /* eval state */ 233 234 /* targets we're working on */ 235 static Lst targets; 236 237 #ifdef CLEANUP 238 /* command lines for targets */ 239 static Lst targCmds; 240 #endif 241 242 /* 243 * specType contains the SPECial TYPE of the current target. It is 244 * Not if the target is unspecial. If it *is* special, however, the children 245 * are linked as children of the parent but not vice versa. This variable is 246 * set in ParseDoDependency 247 */ 248 static ParseSpecial specType; 249 250 /* 251 * Predecessor node for handling .ORDER. Initialized to NULL when .ORDER 252 * seen, then set to each successive source on the line. 253 */ 254 static GNode *predecessor; 255 256 /* parser state */ 257 258 /* true if currently in a dependency line or its commands */ 259 static Boolean inLine; 260 261 /* number of fatal errors */ 262 static int fatals = 0; 263 264 /* 265 * Variables for doing includes 266 */ 267 268 /* current file being read */ 269 static IFile *curFile; 270 271 /* The current file from the command line (at the bottom of the stack) and 272 * further up all the files that are currently being read due to nested 273 * .include or .for directives. */ 274 static Stack /* of *IFile */ includes; 275 276 /* include paths (lists of directories) */ 277 Lst parseIncPath; /* dirs for "..." includes */ 278 Lst sysIncPath; /* dirs for <...> includes */ 279 Lst defIncPath; /* default for sysIncPath */ 280 281 /* parser tables */ 282 283 /* 284 * The parseKeywords table is searched using binary search when deciding 285 * if a target or source is special. The 'spec' field is the ParseSpecial 286 * type of the keyword ("Not" if the keyword isn't special as a target) while 287 * the 'op' field is the operator to apply to the list of targets if the 288 * keyword is used as a source ("0" if the keyword isn't special as a source) 289 */ 290 static const struct { 291 const char *name; /* Name of keyword */ 292 ParseSpecial spec; /* Type when used as a target */ 293 int op; /* Operator when used as a source */ 294 } parseKeywords[] = { 295 { ".BEGIN", Begin, 0 }, 296 { ".DEFAULT", Default, 0 }, 297 { ".DELETE_ON_ERROR", DeleteOnError, 0 }, 298 { ".END", End, 0 }, 299 { ".ERROR", dotError, 0 }, 300 { ".EXEC", Attribute, OP_EXEC }, 301 { ".IGNORE", Ignore, OP_IGNORE }, 302 { ".INCLUDES", Includes, 0 }, 303 { ".INTERRUPT", Interrupt, 0 }, 304 { ".INVISIBLE", Attribute, OP_INVISIBLE }, 305 { ".JOIN", Attribute, OP_JOIN }, 306 { ".LIBS", Libs, 0 }, 307 { ".MADE", Attribute, OP_MADE }, 308 { ".MAIN", Main, 0 }, 309 { ".MAKE", Attribute, OP_MAKE }, 310 { ".MAKEFLAGS", MFlags, 0 }, 311 { ".META", Meta, OP_META }, 312 { ".MFLAGS", MFlags, 0 }, 313 { ".NOMETA", NoMeta, OP_NOMETA }, 314 { ".NOMETA_CMP", NoMetaCmp, OP_NOMETA_CMP }, 315 { ".NOPATH", NoPath, OP_NOPATH }, 316 { ".NOTMAIN", Attribute, OP_NOTMAIN }, 317 { ".NOTPARALLEL", NotParallel, 0 }, 318 { ".NO_PARALLEL", NotParallel, 0 }, 319 { ".NULL", Null, 0 }, 320 { ".OBJDIR", ExObjdir, 0 }, 321 { ".OPTIONAL", Attribute, OP_OPTIONAL }, 322 { ".ORDER", Order, 0 }, 323 { ".PARALLEL", Parallel, 0 }, 324 { ".PATH", ExPath, 0 }, 325 { ".PHONY", Phony, OP_PHONY }, 326 #ifdef POSIX 327 { ".POSIX", Posix, 0 }, 328 #endif 329 { ".PRECIOUS", Precious, OP_PRECIOUS }, 330 { ".RECURSIVE", Attribute, OP_MAKE }, 331 { ".SHELL", ExShell, 0 }, 332 { ".SILENT", Silent, OP_SILENT }, 333 { ".SINGLESHELL", SingleShell, 0 }, 334 { ".STALE", Stale, 0 }, 335 { ".SUFFIXES", Suffixes, 0 }, 336 { ".USE", Attribute, OP_USE }, 337 { ".USEBEFORE", Attribute, OP_USEBEFORE }, 338 { ".WAIT", Wait, 0 }, 339 }; 340 341 /* file loader */ 342 343 struct loadedfile { 344 const char *path; /* name, for error reports */ 345 char *buf; /* contents buffer */ 346 size_t len; /* length of contents */ 347 size_t maplen; /* length of mmap area, or 0 */ 348 Boolean used; /* XXX: have we used the data yet */ 349 }; 350 351 static struct loadedfile * 352 loadedfile_create(const char *path) 353 { 354 struct loadedfile *lf; 355 356 lf = bmake_malloc(sizeof(*lf)); 357 lf->path = path == NULL ? "(stdin)" : path; 358 lf->buf = NULL; 359 lf->len = 0; 360 lf->maplen = 0; 361 lf->used = FALSE; 362 return lf; 363 } 364 365 static void 366 loadedfile_destroy(struct loadedfile *lf) 367 { 368 if (lf->buf != NULL) { 369 if (lf->maplen > 0) { 370 munmap(lf->buf, lf->maplen); 371 } else { 372 free(lf->buf); 373 } 374 } 375 free(lf); 376 } 377 378 /* 379 * nextbuf() operation for loadedfile, as needed by the weird and twisted 380 * logic below. Once that's cleaned up, we can get rid of lf->used... 381 */ 382 static char * 383 loadedfile_nextbuf(void *x, size_t *len) 384 { 385 struct loadedfile *lf = x; 386 387 if (lf->used) { 388 return NULL; 389 } 390 lf->used = TRUE; 391 *len = lf->len; 392 return lf->buf; 393 } 394 395 /* 396 * Try to get the size of a file. 397 */ 398 static Boolean 399 load_getsize(int fd, size_t *ret) 400 { 401 struct stat st; 402 403 if (fstat(fd, &st) < 0) { 404 return FALSE; 405 } 406 407 if (!S_ISREG(st.st_mode)) { 408 return FALSE; 409 } 410 411 /* 412 * st_size is an off_t, which is 64 bits signed; *ret is 413 * size_t, which might be 32 bits unsigned or 64 bits 414 * unsigned. Rather than being elaborate, just punt on 415 * files that are more than 2^31 bytes. We should never 416 * see a makefile that size in practice... 417 * 418 * While we're at it reject negative sizes too, just in case. 419 */ 420 if (st.st_size < 0 || st.st_size > 0x7fffffff) { 421 return FALSE; 422 } 423 424 *ret = (size_t) st.st_size; 425 return TRUE; 426 } 427 428 /* 429 * Read in a file. 430 * 431 * Until the path search logic can be moved under here instead of 432 * being in the caller in another source file, we need to have the fd 433 * passed in already open. Bleh. 434 * 435 * If the path is NULL use stdin and (to insure against fd leaks) 436 * assert that the caller passed in -1. 437 */ 438 static struct loadedfile * 439 loadfile(const char *path, int fd) 440 { 441 struct loadedfile *lf; 442 static long pagesize = 0; 443 ssize_t result; 444 size_t bufpos; 445 446 lf = loadedfile_create(path); 447 448 if (path == NULL) { 449 assert(fd == -1); 450 fd = STDIN_FILENO; 451 } else { 452 #if 0 /* notyet */ 453 fd = open(path, O_RDONLY); 454 if (fd < 0) { 455 ... 456 Error("%s: %s", path, strerror(errno)); 457 exit(1); 458 } 459 #endif 460 } 461 462 if (load_getsize(fd, &lf->len)) { 463 /* found a size, try mmap */ 464 if (pagesize == 0) 465 pagesize = sysconf(_SC_PAGESIZE); 466 if (pagesize <= 0) { 467 pagesize = 0x1000; 468 } 469 /* round size up to a page */ 470 lf->maplen = pagesize * ((lf->len + pagesize - 1)/pagesize); 471 472 /* 473 * XXX hack for dealing with empty files; remove when 474 * we're no longer limited by interfacing to the old 475 * logic elsewhere in this file. 476 */ 477 if (lf->maplen == 0) { 478 lf->maplen = pagesize; 479 } 480 481 /* 482 * FUTURE: remove PROT_WRITE when the parser no longer 483 * needs to scribble on the input. 484 */ 485 lf->buf = mmap(NULL, lf->maplen, PROT_READ|PROT_WRITE, 486 MAP_FILE|MAP_COPY, fd, 0); 487 if (lf->buf != MAP_FAILED) { 488 /* succeeded */ 489 if (lf->len == lf->maplen && lf->buf[lf->len - 1] != '\n') { 490 char *b = bmake_malloc(lf->len + 1); 491 b[lf->len] = '\n'; 492 memcpy(b, lf->buf, lf->len++); 493 munmap(lf->buf, lf->maplen); 494 lf->maplen = 0; 495 lf->buf = b; 496 } 497 goto done; 498 } 499 } 500 501 /* cannot mmap; load the traditional way */ 502 503 lf->maplen = 0; 504 lf->len = 1024; 505 lf->buf = bmake_malloc(lf->len); 506 507 bufpos = 0; 508 while (1) { 509 assert(bufpos <= lf->len); 510 if (bufpos == lf->len) { 511 if (lf->len > SIZE_MAX/2) { 512 errno = EFBIG; 513 Error("%s: file too large", path); 514 exit(1); 515 } 516 lf->len *= 2; 517 lf->buf = bmake_realloc(lf->buf, lf->len); 518 } 519 assert(bufpos < lf->len); 520 result = read(fd, lf->buf + bufpos, lf->len - bufpos); 521 if (result < 0) { 522 Error("%s: read error: %s", path, strerror(errno)); 523 exit(1); 524 } 525 if (result == 0) { 526 break; 527 } 528 bufpos += result; 529 } 530 assert(bufpos <= lf->len); 531 lf->len = bufpos; 532 533 /* truncate malloc region to actual length (maybe not useful) */ 534 if (lf->len > 0) { 535 /* as for mmap case, ensure trailing \n */ 536 if (lf->buf[lf->len - 1] != '\n') 537 lf->len++; 538 lf->buf = bmake_realloc(lf->buf, lf->len); 539 lf->buf[lf->len - 1] = '\n'; 540 } 541 542 done: 543 if (path != NULL) { 544 close(fd); 545 } 546 return lf; 547 } 548 549 /* old code */ 550 551 /* Check if the current character is escaped on the current line. */ 552 static Boolean 553 ParseIsEscaped(const char *line, const char *c) 554 { 555 Boolean active = FALSE; 556 for (;;) { 557 if (line == c) 558 return active; 559 if (*--c != '\\') 560 return active; 561 active = !active; 562 } 563 } 564 565 /* Add the filename and lineno to the GNode so that we remember where it 566 * was first defined. */ 567 static void 568 ParseMark(GNode *gn) 569 { 570 gn->fname = curFile->fname; 571 gn->lineno = curFile->lineno; 572 } 573 574 /*- 575 *---------------------------------------------------------------------- 576 * ParseFindKeyword -- 577 * Look in the table of keywords for one matching the given string. 578 * 579 * Input: 580 * str String to find 581 * 582 * Results: 583 * The index of the keyword, or -1 if it isn't there. 584 * 585 * Side Effects: 586 * None 587 *---------------------------------------------------------------------- 588 */ 589 static int 590 ParseFindKeyword(const char *str) 591 { 592 int start, end, cur; 593 int diff; 594 595 start = 0; 596 end = (sizeof(parseKeywords)/sizeof(parseKeywords[0])) - 1; 597 598 do { 599 cur = start + ((end - start) / 2); 600 diff = strcmp(str, parseKeywords[cur].name); 601 602 if (diff == 0) { 603 return cur; 604 } else if (diff < 0) { 605 end = cur - 1; 606 } else { 607 start = cur + 1; 608 } 609 } while (start <= end); 610 return -1; 611 } 612 613 /*- 614 * ParseVErrorInternal -- 615 * Error message abort function for parsing. Prints out the context 616 * of the error (line number and file) as well as the message with 617 * two optional arguments. 618 * 619 * Results: 620 * None 621 * 622 * Side Effects: 623 * "fatals" is incremented if the level is PARSE_FATAL. 624 */ 625 /* VARARGS */ 626 static void 627 ParseVErrorInternal(FILE *f, const char *cfname, size_t clineno, int type, 628 const char *fmt, va_list ap) 629 { 630 static Boolean fatal_warning_error_printed = FALSE; 631 char dirbuf[MAXPATHLEN+1]; 632 633 (void)fprintf(f, "%s: ", progname); 634 635 if (cfname != NULL) { 636 (void)fprintf(f, "\""); 637 if (*cfname != '/' && strcmp(cfname, "(stdin)") != 0) { 638 char *cp, *cp2; 639 const char *dir, *fname; 640 641 /* 642 * Nothing is more annoying than not knowing 643 * which Makefile is the culprit; we try ${.PARSEDIR} 644 * and apply realpath(3) if not absolute. 645 */ 646 dir = Var_Value(".PARSEDIR", VAR_GLOBAL, &cp); 647 if (dir == NULL) 648 dir = "."; 649 if (*dir != '/') { 650 dir = realpath(dir, dirbuf); 651 } 652 fname = Var_Value(".PARSEFILE", VAR_GLOBAL, &cp2); 653 if (fname == NULL) { 654 if ((fname = strrchr(cfname, '/'))) 655 fname++; 656 else 657 fname = cfname; 658 } 659 (void)fprintf(f, "%s/%s", dir, fname); 660 bmake_free(cp2); 661 bmake_free(cp); 662 } else 663 (void)fprintf(f, "%s", cfname); 664 665 (void)fprintf(f, "\" line %d: ", (int)clineno); 666 } 667 if (type == PARSE_WARNING) 668 (void)fprintf(f, "warning: "); 669 (void)vfprintf(f, fmt, ap); 670 (void)fprintf(f, "\n"); 671 (void)fflush(f); 672 if (type == PARSE_INFO) 673 return; 674 if (type == PARSE_FATAL || parseWarnFatal) 675 fatals += 1; 676 if (parseWarnFatal && !fatal_warning_error_printed) { 677 Error("parsing warnings being treated as errors"); 678 fatal_warning_error_printed = TRUE; 679 } 680 } 681 682 /*- 683 * ParseErrorInternal -- 684 * Error function 685 * 686 * Results: 687 * None 688 * 689 * Side Effects: 690 * None 691 */ 692 /* VARARGS */ 693 static void 694 ParseErrorInternal(const char *cfname, size_t clineno, int type, 695 const char *fmt, ...) 696 { 697 va_list ap; 698 699 va_start(ap, fmt); 700 (void)fflush(stdout); 701 ParseVErrorInternal(stderr, cfname, clineno, type, fmt, ap); 702 va_end(ap); 703 704 if (debug_file != stderr && debug_file != stdout) { 705 va_start(ap, fmt); 706 ParseVErrorInternal(debug_file, cfname, clineno, type, fmt, ap); 707 va_end(ap); 708 } 709 } 710 711 /*- 712 * Parse_Error -- 713 * External interface to ParseErrorInternal; uses the default filename 714 * Line number. 715 * 716 * Results: 717 * None 718 * 719 * Side Effects: 720 * None 721 */ 722 /* VARARGS */ 723 void 724 Parse_Error(int type, const char *fmt, ...) 725 { 726 va_list ap; 727 const char *fname; 728 size_t lineno; 729 730 if (curFile == NULL) { 731 fname = NULL; 732 lineno = 0; 733 } else { 734 fname = curFile->fname; 735 lineno = curFile->lineno; 736 } 737 738 va_start(ap, fmt); 739 (void)fflush(stdout); 740 ParseVErrorInternal(stderr, fname, lineno, type, fmt, ap); 741 va_end(ap); 742 743 if (debug_file != stderr && debug_file != stdout) { 744 va_start(ap, fmt); 745 ParseVErrorInternal(debug_file, fname, lineno, type, fmt, ap); 746 va_end(ap); 747 } 748 } 749 750 751 /* 752 * ParseMessage 753 * Parse a .info .warning or .error directive 754 * 755 * The input is the line minus the ".". We substitute 756 * variables, print the message and exit(1) (for .error) or just print 757 * a warning if the directive is malformed. 758 */ 759 static Boolean 760 ParseMessage(char *line) 761 { 762 int mtype; 763 764 switch(*line) { 765 case 'i': 766 mtype = PARSE_INFO; 767 break; 768 case 'w': 769 mtype = PARSE_WARNING; 770 break; 771 case 'e': 772 mtype = PARSE_FATAL; 773 break; 774 default: 775 Parse_Error(PARSE_WARNING, "invalid syntax: \".%s\"", line); 776 return FALSE; 777 } 778 779 while (isalpha((unsigned char)*line)) 780 line++; 781 if (!isspace((unsigned char)*line)) 782 return FALSE; /* not for us */ 783 while (isspace((unsigned char)*line)) 784 line++; 785 786 line = Var_Subst(line, VAR_CMD, VARE_WANTRES); 787 Parse_Error(mtype, "%s", line); 788 free(line); 789 790 if (mtype == PARSE_FATAL) { 791 /* Terminate immediately. */ 792 exit(1); 793 } 794 return TRUE; 795 } 796 797 /*- 798 *--------------------------------------------------------------------- 799 * ParseLinkSrc -- 800 * Link the parent node to its new child. Used in a Lst_ForEach by 801 * ParseDoDependency. If the specType isn't 'Not', the parent 802 * isn't linked as a parent of the child. 803 * 804 * Input: 805 * pgnp The parent node 806 * cgpn The child node 807 * 808 * Results: 809 * Always = 0 810 * 811 * Side Effects: 812 * New elements are added to the parents list of cgn and the 813 * children list of cgn. the unmade field of pgn is updated 814 * to reflect the additional child. 815 *--------------------------------------------------------------------- 816 */ 817 static int 818 ParseLinkSrc(void *pgnp, void *cgnp) 819 { 820 GNode *pgn = (GNode *)pgnp; 821 GNode *cgn = (GNode *)cgnp; 822 823 if ((pgn->type & OP_DOUBLEDEP) && !Lst_IsEmpty(pgn->cohorts)) 824 pgn = LstNode_Datum(Lst_Last(pgn->cohorts)); 825 Lst_Append(pgn->children, cgn); 826 if (specType == Not) 827 Lst_Append(cgn->parents, pgn); 828 pgn->unmade += 1; 829 if (DEBUG(PARSE)) { 830 fprintf(debug_file, "# %s: added child %s - %s\n", __func__, 831 pgn->name, cgn->name); 832 Targ_PrintNode(pgn, 0); 833 Targ_PrintNode(cgn, 0); 834 } 835 return 0; 836 } 837 838 /*- 839 *--------------------------------------------------------------------- 840 * ParseDoOp -- 841 * Apply the parsed operator to the given target node. Used in a 842 * Lst_ForEach call by ParseDoDependency once all targets have 843 * been found and their operator parsed. If the previous and new 844 * operators are incompatible, a major error is taken. 845 * 846 * Input: 847 * gnp The node to which the operator is to be applied 848 * opp The operator to apply 849 * 850 * Results: 851 * Always 0 852 * 853 * Side Effects: 854 * The type field of the node is altered to reflect any new bits in 855 * the op. 856 *--------------------------------------------------------------------- 857 */ 858 static int 859 ParseDoOp(void *gnp, void *opp) 860 { 861 GNode *gn = (GNode *)gnp; 862 int op = *(int *)opp; 863 /* 864 * If the dependency mask of the operator and the node don't match and 865 * the node has actually had an operator applied to it before, and 866 * the operator actually has some dependency information in it, complain. 867 */ 868 if (((op & OP_OPMASK) != (gn->type & OP_OPMASK)) && 869 !OP_NOP(gn->type) && !OP_NOP(op)) 870 { 871 Parse_Error(PARSE_FATAL, "Inconsistent operator for %s", gn->name); 872 return 1; 873 } 874 875 if (op == OP_DOUBLEDEP && (gn->type & OP_OPMASK) == OP_DOUBLEDEP) { 876 /* 877 * If the node was the object of a :: operator, we need to create a 878 * new instance of it for the children and commands on this dependency 879 * line. The new instance is placed on the 'cohorts' list of the 880 * initial one (note the initial one is not on its own cohorts list) 881 * and the new instance is linked to all parents of the initial 882 * instance. 883 */ 884 GNode *cohort; 885 886 /* 887 * Propagate copied bits to the initial node. They'll be propagated 888 * back to the rest of the cohorts later. 889 */ 890 gn->type |= op & ~OP_OPMASK; 891 892 cohort = Targ_FindNode(gn->name, TARG_NOHASH); 893 if (doing_depend) 894 ParseMark(cohort); 895 /* 896 * Make the cohort invisible as well to avoid duplicating it into 897 * other variables. True, parents of this target won't tend to do 898 * anything with their local variables, but better safe than 899 * sorry. (I think this is pointless now, since the relevant list 900 * traversals will no longer see this node anyway. -mycroft) 901 */ 902 cohort->type = op | OP_INVISIBLE; 903 Lst_Append(gn->cohorts, cohort); 904 cohort->centurion = gn; 905 gn->unmade_cohorts += 1; 906 snprintf(cohort->cohort_num, sizeof cohort->cohort_num, "#%d", 907 gn->unmade_cohorts); 908 } else { 909 /* 910 * We don't want to nuke any previous flags (whatever they were) so we 911 * just OR the new operator into the old 912 */ 913 gn->type |= op; 914 } 915 916 return 0; 917 } 918 919 /*- 920 *--------------------------------------------------------------------- 921 * ParseDoSrc -- 922 * Given the name of a source, figure out if it is an attribute 923 * and apply it to the targets if it is. Else decide if there is 924 * some attribute which should be applied *to* the source because 925 * of some special target and apply it if so. Otherwise, make the 926 * source be a child of the targets in the list 'targets' 927 * 928 * Input: 929 * tOp operator (if any) from special targets 930 * src name of the source to handle 931 * 932 * Results: 933 * None 934 * 935 * Side Effects: 936 * Operator bits may be added to the list of targets or to the source. 937 * The targets may have a new source added to their lists of children. 938 *--------------------------------------------------------------------- 939 */ 940 static void 941 ParseDoSrc(int tOp, const char *src) 942 { 943 GNode *gn = NULL; 944 static int wait_number = 0; 945 char wait_src[16]; 946 947 if (*src == '.' && isupper ((unsigned char)src[1])) { 948 int keywd = ParseFindKeyword(src); 949 if (keywd != -1) { 950 int op = parseKeywords[keywd].op; 951 if (op != 0) { 952 if (targets != NULL) 953 Lst_ForEach(targets, ParseDoOp, &op); 954 return; 955 } 956 if (parseKeywords[keywd].spec == Wait) { 957 /* 958 * We add a .WAIT node in the dependency list. 959 * After any dynamic dependencies (and filename globbing) 960 * have happened, it is given a dependency on the each 961 * previous child back to and previous .WAIT node. 962 * The next child won't be scheduled until the .WAIT node 963 * is built. 964 * We give each .WAIT node a unique name (mainly for diag). 965 */ 966 snprintf(wait_src, sizeof wait_src, ".WAIT_%u", ++wait_number); 967 gn = Targ_FindNode(wait_src, TARG_NOHASH); 968 if (doing_depend) 969 ParseMark(gn); 970 gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN; 971 if (targets != NULL) 972 Lst_ForEach(targets, ParseLinkSrc, gn); 973 return; 974 } 975 } 976 } 977 978 switch (specType) { 979 case Main: 980 /* 981 * If we have noted the existence of a .MAIN, it means we need 982 * to add the sources of said target to the list of things 983 * to create. The string 'src' is likely to be free, so we 984 * must make a new copy of it. Note that this will only be 985 * invoked if the user didn't specify a target on the command 986 * line. This is to allow #ifmake's to succeed, or something... 987 */ 988 Lst_Append(create, bmake_strdup(src)); 989 /* 990 * Add the name to the .TARGETS variable as well, so the user can 991 * employ that, if desired. 992 */ 993 Var_Append(".TARGETS", src, VAR_GLOBAL); 994 return; 995 996 case Order: 997 /* 998 * Create proper predecessor/successor links between the previous 999 * source and the current one. 1000 */ 1001 gn = Targ_FindNode(src, TARG_CREATE); 1002 if (doing_depend) 1003 ParseMark(gn); 1004 if (predecessor != NULL) { 1005 Lst_Append(predecessor->order_succ, gn); 1006 Lst_Append(gn->order_pred, predecessor); 1007 if (DEBUG(PARSE)) { 1008 fprintf(debug_file, "# %s: added Order dependency %s - %s\n", 1009 __func__, predecessor->name, gn->name); 1010 Targ_PrintNode(predecessor, 0); 1011 Targ_PrintNode(gn, 0); 1012 } 1013 } 1014 /* 1015 * The current source now becomes the predecessor for the next one. 1016 */ 1017 predecessor = gn; 1018 break; 1019 1020 default: 1021 /* 1022 * If the source is not an attribute, we need to find/create 1023 * a node for it. After that we can apply any operator to it 1024 * from a special target or link it to its parents, as 1025 * appropriate. 1026 * 1027 * In the case of a source that was the object of a :: operator, 1028 * the attribute is applied to all of its instances (as kept in 1029 * the 'cohorts' list of the node) or all the cohorts are linked 1030 * to all the targets. 1031 */ 1032 1033 /* Find/create the 'src' node and attach to all targets */ 1034 gn = Targ_FindNode(src, TARG_CREATE); 1035 if (doing_depend) 1036 ParseMark(gn); 1037 if (tOp) { 1038 gn->type |= tOp; 1039 } else { 1040 if (targets != NULL) 1041 Lst_ForEach(targets, ParseLinkSrc, gn); 1042 } 1043 break; 1044 } 1045 } 1046 1047 /*- 1048 *----------------------------------------------------------------------- 1049 * ParseFindMain -- 1050 * Find a real target in the list and set it to be the main one. 1051 * Called by ParseDoDependency when a main target hasn't been found 1052 * yet. 1053 * 1054 * Input: 1055 * gnp Node to examine 1056 * 1057 * Results: 1058 * 0 if main not found yet, 1 if it is. 1059 * 1060 * Side Effects: 1061 * mainNode is changed and Targ_SetMain is called. 1062 * 1063 *----------------------------------------------------------------------- 1064 */ 1065 static int 1066 ParseFindMain(void *gnp, void *dummy MAKE_ATTR_UNUSED) 1067 { 1068 GNode *gn = (GNode *)gnp; 1069 if (!(gn->type & OP_NOTARGET)) { 1070 mainNode = gn; 1071 Targ_SetMain(gn); 1072 return 1; 1073 } else { 1074 return 0; 1075 } 1076 } 1077 1078 /*- 1079 *----------------------------------------------------------------------- 1080 * ParseAddDir -- 1081 * Front-end for Dir_AddDir to make sure Lst_ForEach keeps going 1082 * 1083 * Results: 1084 * === 0 1085 * 1086 * Side Effects: 1087 * See Dir_AddDir. 1088 * 1089 *----------------------------------------------------------------------- 1090 */ 1091 static int 1092 ParseAddDir(void *path, void *name) 1093 { 1094 (void)Dir_AddDir((Lst) path, (char *)name); 1095 return 0; 1096 } 1097 1098 /*- 1099 *----------------------------------------------------------------------- 1100 * ParseClearPath -- 1101 * Front-end for Dir_ClearPath to make sure Lst_ForEach keeps going 1102 * 1103 * Results: 1104 * === 0 1105 * 1106 * Side Effects: 1107 * See Dir_ClearPath 1108 * 1109 *----------------------------------------------------------------------- 1110 */ 1111 static int 1112 ParseClearPath(void *path, void *dummy MAKE_ATTR_UNUSED) 1113 { 1114 Dir_ClearPath((Lst) path); 1115 return 0; 1116 } 1117 1118 /*- 1119 *--------------------------------------------------------------------- 1120 * ParseDoDependency -- 1121 * Parse the dependency line in line. 1122 * 1123 * Input: 1124 * line the line to parse 1125 * 1126 * Results: 1127 * None 1128 * 1129 * Side Effects: 1130 * The nodes of the sources are linked as children to the nodes of the 1131 * targets. Some nodes may be created. 1132 * 1133 * We parse a dependency line by first extracting words from the line and 1134 * finding nodes in the list of all targets with that name. This is done 1135 * until a character is encountered which is an operator character. Currently 1136 * these are only ! and :. At this point the operator is parsed and the 1137 * pointer into the line advanced until the first source is encountered. 1138 * The parsed operator is applied to each node in the 'targets' list, 1139 * which is where the nodes found for the targets are kept, by means of 1140 * the ParseDoOp function. 1141 * The sources are read in much the same way as the targets were except 1142 * that now they are expanded using the wildcarding scheme of the C-Shell 1143 * and all instances of the resulting words in the list of all targets 1144 * are found. Each of the resulting nodes is then linked to each of the 1145 * targets as one of its children. 1146 * Certain targets are handled specially. These are the ones detailed 1147 * by the specType variable. 1148 * The storing of transformation rules is also taken care of here. 1149 * A target is recognized as a transformation rule by calling 1150 * Suff_IsTransform. If it is a transformation rule, its node is gotten 1151 * from the suffix module via Suff_AddTransform rather than the standard 1152 * Targ_FindNode in the target module. 1153 *--------------------------------------------------------------------- 1154 */ 1155 static void 1156 ParseDoDependency(char *line) 1157 { 1158 char *cp; /* our current position */ 1159 GNode *gn = NULL; /* a general purpose temporary node */ 1160 int op; /* the operator on the line */ 1161 char savec; /* a place to save a character */ 1162 Lst paths; /* List of search paths to alter when parsing 1163 * a list of .PATH targets */ 1164 int tOp; /* operator from special target */ 1165 Lst sources; /* list of archive source names after 1166 * expansion */ 1167 Lst curTargs; /* list of target names to be found and added 1168 * to the targets list */ 1169 char *lstart = line; 1170 1171 if (DEBUG(PARSE)) 1172 fprintf(debug_file, "ParseDoDependency(%s)\n", line); 1173 tOp = 0; 1174 1175 specType = Not; 1176 paths = NULL; 1177 1178 curTargs = Lst_Init(); 1179 1180 /* 1181 * First, grind through the targets. 1182 */ 1183 1184 do { 1185 /* 1186 * Here LINE points to the beginning of the next word, and 1187 * LSTART points to the actual beginning of the line. 1188 */ 1189 1190 /* Find the end of the next word. */ 1191 for (cp = line; *cp && (ParseIsEscaped(lstart, cp) || 1192 !(isspace((unsigned char)*cp) || 1193 *cp == '!' || *cp == ':' || *cp == LPAREN)); 1194 cp++) { 1195 if (*cp == '$') { 1196 /* 1197 * Must be a dynamic source (would have been expanded 1198 * otherwise), so call the Var module to parse the puppy 1199 * so we can safely advance beyond it...There should be 1200 * no errors in this, as they would have been discovered 1201 * in the initial Var_Subst and we wouldn't be here. 1202 */ 1203 int length; 1204 void *freeIt; 1205 1206 (void)Var_Parse(cp, VAR_CMD, VARE_UNDEFERR|VARE_WANTRES, 1207 &length, &freeIt); 1208 free(freeIt); 1209 cp += length - 1; 1210 } 1211 } 1212 1213 /* 1214 * If the word is followed by a left parenthesis, it's the 1215 * name of an object file inside an archive (ar file). 1216 */ 1217 if (!ParseIsEscaped(lstart, cp) && *cp == LPAREN) { 1218 /* 1219 * Archives must be handled specially to make sure the OP_ARCHV 1220 * flag is set in their 'type' field, for one thing, and because 1221 * things like "archive(file1.o file2.o file3.o)" are permissible. 1222 * Arch_ParseArchive will set 'line' to be the first non-blank 1223 * after the archive-spec. It creates/finds nodes for the members 1224 * and places them on the given list, returning TRUE if all 1225 * went well and FALSE if there was an error in the 1226 * specification. On error, line should remain untouched. 1227 */ 1228 if (!Arch_ParseArchive(&line, targets, VAR_CMD)) { 1229 Parse_Error(PARSE_FATAL, 1230 "Error in archive specification: \"%s\"", line); 1231 goto out; 1232 } else { 1233 /* Done with this word; on to the next. */ 1234 cp = line; 1235 continue; 1236 } 1237 } 1238 1239 if (!*cp) { 1240 /* 1241 * We got to the end of the line while we were still 1242 * looking at targets. 1243 * 1244 * Ending a dependency line without an operator is a Bozo 1245 * no-no. As a heuristic, this is also often triggered by 1246 * undetected conflicts from cvs/rcs merges. 1247 */ 1248 if ((strncmp(line, "<<<<<<", 6) == 0) || 1249 (strncmp(line, "======", 6) == 0) || 1250 (strncmp(line, ">>>>>>", 6) == 0)) 1251 Parse_Error(PARSE_FATAL, 1252 "Makefile appears to contain unresolved cvs/rcs/??? merge conflicts"); 1253 else if (lstart[0] == '.') { 1254 const char *dirstart = lstart + 1; 1255 const char *dirend; 1256 while (isspace((unsigned char)*dirstart)) 1257 dirstart++; 1258 dirend = dirstart; 1259 while (isalnum((unsigned char)*dirend) || *dirend == '-') 1260 dirend++; 1261 Parse_Error(PARSE_FATAL, "Unknown directive \"%.*s\"", 1262 (int)(dirend - dirstart), dirstart); 1263 } else 1264 Parse_Error(PARSE_FATAL, "Need an operator"); 1265 goto out; 1266 } 1267 1268 /* Insert a null terminator. */ 1269 savec = *cp; 1270 *cp = '\0'; 1271 1272 /* 1273 * Got the word. See if it's a special target and if so set 1274 * specType to match it. 1275 */ 1276 if (*line == '.' && isupper ((unsigned char)line[1])) { 1277 /* 1278 * See if the target is a special target that must have it 1279 * or its sources handled specially. 1280 */ 1281 int keywd = ParseFindKeyword(line); 1282 if (keywd != -1) { 1283 if (specType == ExPath && parseKeywords[keywd].spec != ExPath) { 1284 Parse_Error(PARSE_FATAL, "Mismatched special targets"); 1285 goto out; 1286 } 1287 1288 specType = parseKeywords[keywd].spec; 1289 tOp = parseKeywords[keywd].op; 1290 1291 /* 1292 * Certain special targets have special semantics: 1293 * .PATH Have to set the dirSearchPath 1294 * variable too 1295 * .MAIN Its sources are only used if 1296 * nothing has been specified to 1297 * create. 1298 * .DEFAULT Need to create a node to hang 1299 * commands on, but we don't want 1300 * it in the graph, nor do we want 1301 * it to be the Main Target, so we 1302 * create it, set OP_NOTMAIN and 1303 * add it to the list, setting 1304 * DEFAULT to the new node for 1305 * later use. We claim the node is 1306 * A transformation rule to make 1307 * life easier later, when we'll 1308 * use Make_HandleUse to actually 1309 * apply the .DEFAULT commands. 1310 * .PHONY The list of targets 1311 * .NOPATH Don't search for file in the path 1312 * .STALE 1313 * .BEGIN 1314 * .END 1315 * .ERROR 1316 * .DELETE_ON_ERROR 1317 * .INTERRUPT Are not to be considered the 1318 * main target. 1319 * .NOTPARALLEL Make only one target at a time. 1320 * .SINGLESHELL Create a shell for each command. 1321 * .ORDER Must set initial predecessor to NULL 1322 */ 1323 switch (specType) { 1324 case ExPath: 1325 if (paths == NULL) { 1326 paths = Lst_Init(); 1327 } 1328 Lst_Append(paths, dirSearchPath); 1329 break; 1330 case Main: 1331 if (!Lst_IsEmpty(create)) { 1332 specType = Not; 1333 } 1334 break; 1335 case Begin: 1336 case End: 1337 case Stale: 1338 case dotError: 1339 case Interrupt: 1340 gn = Targ_FindNode(line, TARG_CREATE); 1341 if (doing_depend) 1342 ParseMark(gn); 1343 gn->type |= OP_NOTMAIN|OP_SPECIAL; 1344 Lst_Append(targets, gn); 1345 break; 1346 case Default: 1347 gn = Targ_NewGN(".DEFAULT"); 1348 gn->type |= (OP_NOTMAIN|OP_TRANSFORM); 1349 Lst_Append(targets, gn); 1350 DEFAULT = gn; 1351 break; 1352 case DeleteOnError: 1353 deleteOnError = TRUE; 1354 break; 1355 case NotParallel: 1356 maxJobs = 1; 1357 break; 1358 case SingleShell: 1359 compatMake = TRUE; 1360 break; 1361 case Order: 1362 predecessor = NULL; 1363 break; 1364 default: 1365 break; 1366 } 1367 } else if (strncmp(line, ".PATH", 5) == 0) { 1368 /* 1369 * .PATH<suffix> has to be handled specially. 1370 * Call on the suffix module to give us a path to 1371 * modify. 1372 */ 1373 Lst path; 1374 1375 specType = ExPath; 1376 path = Suff_GetPath(&line[5]); 1377 if (path == NULL) { 1378 Parse_Error(PARSE_FATAL, 1379 "Suffix '%s' not defined (yet)", 1380 &line[5]); 1381 goto out; 1382 } else { 1383 if (paths == NULL) { 1384 paths = Lst_Init(); 1385 } 1386 Lst_Append(paths, path); 1387 } 1388 } 1389 } 1390 1391 /* 1392 * Have word in line. Get or create its node and stick it at 1393 * the end of the targets list 1394 */ 1395 if (specType == Not && *line != '\0') { 1396 if (Dir_HasWildcards(line)) { 1397 /* 1398 * Targets are to be sought only in the current directory, 1399 * so create an empty path for the thing. Note we need to 1400 * use Dir_Destroy in the destruction of the path as the 1401 * Dir module could have added a directory to the path... 1402 */ 1403 Lst emptyPath = Lst_Init(); 1404 1405 Dir_Expand(line, emptyPath, curTargs); 1406 1407 Lst_Destroy(emptyPath, Dir_Destroy); 1408 } else { 1409 /* 1410 * No wildcards, but we want to avoid code duplication, 1411 * so create a list with the word on it. 1412 */ 1413 Lst_Append(curTargs, line); 1414 } 1415 1416 /* Apply the targets. */ 1417 1418 while(!Lst_IsEmpty(curTargs)) { 1419 char *targName = Lst_Dequeue(curTargs); 1420 1421 if (!Suff_IsTransform (targName)) { 1422 gn = Targ_FindNode(targName, TARG_CREATE); 1423 } else { 1424 gn = Suff_AddTransform(targName); 1425 } 1426 if (doing_depend) 1427 ParseMark(gn); 1428 1429 Lst_Append(targets, gn); 1430 } 1431 } else if (specType == ExPath && *line != '.' && *line != '\0') { 1432 Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line); 1433 } 1434 1435 /* Don't need the inserted null terminator any more. */ 1436 *cp = savec; 1437 1438 /* 1439 * If it is a special type and not .PATH, it's the only target we 1440 * allow on this line... 1441 */ 1442 if (specType != Not && specType != ExPath) { 1443 Boolean warning = FALSE; 1444 1445 while (*cp && (ParseIsEscaped(lstart, cp) || 1446 (*cp != '!' && *cp != ':'))) { 1447 if (ParseIsEscaped(lstart, cp) || 1448 (*cp != ' ' && *cp != '\t')) { 1449 warning = TRUE; 1450 } 1451 cp++; 1452 } 1453 if (warning) { 1454 Parse_Error(PARSE_WARNING, "Extra target ignored"); 1455 } 1456 } else { 1457 while (*cp && isspace ((unsigned char)*cp)) { 1458 cp++; 1459 } 1460 } 1461 line = cp; 1462 } while (*line && (ParseIsEscaped(lstart, line) || 1463 (*line != '!' && *line != ':'))); 1464 1465 /* 1466 * Don't need the list of target names anymore... 1467 */ 1468 Lst_Free(curTargs); 1469 curTargs = NULL; 1470 1471 if (targets != NULL && !Lst_IsEmpty(targets)) { 1472 switch(specType) { 1473 default: 1474 Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored"); 1475 break; 1476 case Default: 1477 case Stale: 1478 case Begin: 1479 case End: 1480 case dotError: 1481 case Interrupt: 1482 /* 1483 * These four create nodes on which to hang commands, so 1484 * targets shouldn't be empty... 1485 */ 1486 case Not: 1487 /* 1488 * Nothing special here -- targets can be empty if it wants. 1489 */ 1490 break; 1491 } 1492 } 1493 1494 /* 1495 * Have now parsed all the target names. Must parse the operator next. The 1496 * result is left in op . 1497 */ 1498 if (*cp == '!') { 1499 op = OP_FORCE; 1500 } else if (*cp == ':') { 1501 if (cp[1] == ':') { 1502 op = OP_DOUBLEDEP; 1503 cp++; 1504 } else { 1505 op = OP_DEPENDS; 1506 } 1507 } else { 1508 Parse_Error(PARSE_FATAL, lstart[0] == '.' ? "Unknown directive" 1509 : "Missing dependency operator"); 1510 goto out; 1511 } 1512 1513 /* Advance beyond the operator */ 1514 cp++; 1515 1516 /* 1517 * Apply the operator to the target. This is how we remember which 1518 * operator a target was defined with. It fails if the operator 1519 * used isn't consistent across all references. 1520 */ 1521 if (targets != NULL) 1522 Lst_ForEach(targets, ParseDoOp, &op); 1523 1524 /* 1525 * Onward to the sources. 1526 * 1527 * LINE will now point to the first source word, if any, or the 1528 * end of the string if not. 1529 */ 1530 while (*cp && isspace ((unsigned char)*cp)) { 1531 cp++; 1532 } 1533 line = cp; 1534 1535 /* 1536 * Several special targets take different actions if present with no 1537 * sources: 1538 * a .SUFFIXES line with no sources clears out all old suffixes 1539 * a .PRECIOUS line makes all targets precious 1540 * a .IGNORE line ignores errors for all targets 1541 * a .SILENT line creates silence when making all targets 1542 * a .PATH removes all directories from the search path(s). 1543 */ 1544 if (!*line) { 1545 switch (specType) { 1546 case Suffixes: 1547 Suff_ClearSuffixes(); 1548 break; 1549 case Precious: 1550 allPrecious = TRUE; 1551 break; 1552 case Ignore: 1553 ignoreErrors = TRUE; 1554 break; 1555 case Silent: 1556 beSilent = TRUE; 1557 break; 1558 case ExPath: 1559 if (paths != NULL) 1560 Lst_ForEach(paths, ParseClearPath, NULL); 1561 Dir_SetPATH(); 1562 break; 1563 #ifdef POSIX 1564 case Posix: 1565 Var_Set("%POSIX", "1003.2", VAR_GLOBAL); 1566 break; 1567 #endif 1568 default: 1569 break; 1570 } 1571 } else if (specType == MFlags) { 1572 /* 1573 * Call on functions in main.c to deal with these arguments and 1574 * set the initial character to a null-character so the loop to 1575 * get sources won't get anything 1576 */ 1577 Main_ParseArgLine(line); 1578 *line = '\0'; 1579 } else if (specType == ExShell) { 1580 if (!Job_ParseShell(line)) { 1581 Parse_Error(PARSE_FATAL, "improper shell specification"); 1582 goto out; 1583 } 1584 *line = '\0'; 1585 } else if (specType == NotParallel || specType == SingleShell || 1586 specType == DeleteOnError) { 1587 *line = '\0'; 1588 } 1589 1590 /* 1591 * NOW GO FOR THE SOURCES 1592 */ 1593 if (specType == Suffixes || specType == ExPath || 1594 specType == Includes || specType == Libs || 1595 specType == Null || specType == ExObjdir) 1596 { 1597 while (*line) { 1598 /* 1599 * If the target was one that doesn't take files as its sources 1600 * but takes something like suffixes, we take each 1601 * space-separated word on the line as a something and deal 1602 * with it accordingly. 1603 * 1604 * If the target was .SUFFIXES, we take each source as a 1605 * suffix and add it to the list of suffixes maintained by the 1606 * Suff module. 1607 * 1608 * If the target was a .PATH, we add the source as a directory 1609 * to search on the search path. 1610 * 1611 * If it was .INCLUDES, the source is taken to be the suffix of 1612 * files which will be #included and whose search path should 1613 * be present in the .INCLUDES variable. 1614 * 1615 * If it was .LIBS, the source is taken to be the suffix of 1616 * files which are considered libraries and whose search path 1617 * should be present in the .LIBS variable. 1618 * 1619 * If it was .NULL, the source is the suffix to use when a file 1620 * has no valid suffix. 1621 * 1622 * If it was .OBJDIR, the source is a new definition for .OBJDIR, 1623 * and will cause make to do a new chdir to that path. 1624 */ 1625 while (*cp && !isspace ((unsigned char)*cp)) { 1626 cp++; 1627 } 1628 savec = *cp; 1629 *cp = '\0'; 1630 switch (specType) { 1631 case Suffixes: 1632 Suff_AddSuffix(line, &mainNode); 1633 break; 1634 case ExPath: 1635 if (paths != NULL) 1636 Lst_ForEach(paths, ParseAddDir, line); 1637 break; 1638 case Includes: 1639 Suff_AddInclude(line); 1640 break; 1641 case Libs: 1642 Suff_AddLib(line); 1643 break; 1644 case Null: 1645 Suff_SetNull(line); 1646 break; 1647 case ExObjdir: 1648 Main_SetObjdir("%s", line); 1649 break; 1650 default: 1651 break; 1652 } 1653 *cp = savec; 1654 if (savec != '\0') { 1655 cp++; 1656 } 1657 while (*cp && isspace ((unsigned char)*cp)) { 1658 cp++; 1659 } 1660 line = cp; 1661 } 1662 if (paths) { 1663 Lst_Free(paths); 1664 paths = NULL; 1665 } 1666 if (specType == ExPath) 1667 Dir_SetPATH(); 1668 } else { 1669 assert(paths == NULL); 1670 while (*line) { 1671 /* 1672 * The targets take real sources, so we must beware of archive 1673 * specifications (i.e. things with left parentheses in them) 1674 * and handle them accordingly. 1675 */ 1676 for (; *cp && !isspace ((unsigned char)*cp); cp++) { 1677 if (*cp == LPAREN && cp > line && cp[-1] != '$') { 1678 /* 1679 * Only stop for a left parenthesis if it isn't at the 1680 * start of a word (that'll be for variable changes 1681 * later) and isn't preceded by a dollar sign (a dynamic 1682 * source). 1683 */ 1684 break; 1685 } 1686 } 1687 1688 if (*cp == LPAREN) { 1689 sources = Lst_Init(); 1690 if (!Arch_ParseArchive(&line, sources, VAR_CMD)) { 1691 Parse_Error(PARSE_FATAL, 1692 "Error in source archive spec \"%s\"", line); 1693 goto out; 1694 } 1695 1696 while (!Lst_IsEmpty(sources)) { 1697 gn = Lst_Dequeue(sources); 1698 ParseDoSrc(tOp, gn->name); 1699 } 1700 Lst_Free(sources); 1701 cp = line; 1702 } else { 1703 if (*cp) { 1704 *cp = '\0'; 1705 cp += 1; 1706 } 1707 1708 ParseDoSrc(tOp, line); 1709 } 1710 while (*cp && isspace ((unsigned char)*cp)) { 1711 cp++; 1712 } 1713 line = cp; 1714 } 1715 } 1716 1717 if (mainNode == NULL && targets != NULL) { 1718 /* 1719 * If we have yet to decide on a main target to make, in the 1720 * absence of any user input, we want the first target on 1721 * the first dependency line that is actually a real target 1722 * (i.e. isn't a .USE or .EXEC rule) to be made. 1723 */ 1724 Lst_ForEach(targets, ParseFindMain, NULL); 1725 } 1726 1727 out: 1728 if (paths != NULL) 1729 Lst_Free(paths); 1730 if (curTargs != NULL) 1731 Lst_Free(curTargs); 1732 } 1733 1734 /*- 1735 *--------------------------------------------------------------------- 1736 * Parse_IsVar -- 1737 * Return TRUE if the passed line is a variable assignment. A variable 1738 * assignment consists of a single word followed by optional whitespace 1739 * followed by either a += or an = operator. 1740 * This function is used both by the Parse_File function and main when 1741 * parsing the command-line arguments. 1742 * 1743 * Input: 1744 * line the line to check 1745 * 1746 * Results: 1747 * TRUE if it is. FALSE if it ain't 1748 * 1749 * Side Effects: 1750 * none 1751 *--------------------------------------------------------------------- 1752 */ 1753 Boolean 1754 Parse_IsVar(const char *line) 1755 { 1756 Boolean wasSpace = FALSE; /* set TRUE if found a space */ 1757 char ch; 1758 int level = 0; 1759 #define ISEQOPERATOR(c) \ 1760 (((c) == '+') || ((c) == ':') || ((c) == '?') || ((c) == '!')) 1761 1762 /* 1763 * Skip to variable name 1764 */ 1765 while (*line == ' ' || *line == '\t') 1766 line++; 1767 1768 /* Scan for one of the assignment operators outside a variable expansion */ 1769 while ((ch = *line++) != 0) { 1770 if (ch == '(' || ch == '{') { 1771 level++; 1772 continue; 1773 } 1774 if (ch == ')' || ch == '}') { 1775 level--; 1776 continue; 1777 } 1778 if (level != 0) 1779 continue; 1780 while (ch == ' ' || ch == '\t') { 1781 ch = *line++; 1782 wasSpace = TRUE; 1783 } 1784 #ifdef SUNSHCMD 1785 if (ch == ':' && strncmp(line, "sh", 2) == 0) { 1786 line += 2; 1787 continue; 1788 } 1789 #endif 1790 if (ch == '=') 1791 return TRUE; 1792 if (*line == '=' && ISEQOPERATOR(ch)) 1793 return TRUE; 1794 if (wasSpace) 1795 return FALSE; 1796 } 1797 1798 return FALSE; 1799 } 1800 1801 /*- 1802 *--------------------------------------------------------------------- 1803 * Parse_DoVar -- 1804 * Take the variable assignment in the passed line and do it in the 1805 * global context. 1806 * 1807 * Note: There is a lexical ambiguity with assignment modifier characters 1808 * in variable names. This routine interprets the character before the = 1809 * as a modifier. Therefore, an assignment like 1810 * C++=/usr/bin/CC 1811 * is interpreted as "C+ +=" instead of "C++ =". 1812 * 1813 * Input: 1814 * line a line guaranteed to be a variable assignment. 1815 * This reduces error checks 1816 * ctxt Context in which to do the assignment 1817 * 1818 * Results: 1819 * none 1820 * 1821 * Side Effects: 1822 * the variable structure of the given variable name is altered in the 1823 * global context. 1824 *--------------------------------------------------------------------- 1825 */ 1826 void 1827 Parse_DoVar(char *line, GNode *ctxt) 1828 { 1829 char *cp; /* pointer into line */ 1830 enum { 1831 VAR_SUBST, VAR_APPEND, VAR_SHELL, VAR_NORMAL 1832 } type; /* Type of assignment */ 1833 char *opc; /* ptr to operator character to 1834 * null-terminate the variable name */ 1835 Boolean freeCp = FALSE; /* TRUE if cp needs to be freed, 1836 * i.e. if any variable expansion was 1837 * performed */ 1838 int depth; 1839 1840 /* 1841 * Skip to variable name 1842 */ 1843 while (*line == ' ' || *line == '\t') 1844 line++; 1845 1846 /* 1847 * Skip to operator character, nulling out whitespace as we go 1848 * XXX Rather than counting () and {} we should look for $ and 1849 * then expand the variable. 1850 */ 1851 for (depth = 0, cp = line; depth > 0 || *cp != '='; cp++) { 1852 if (*cp == '(' || *cp == '{') { 1853 depth++; 1854 continue; 1855 } 1856 if (*cp == ')' || *cp == '}') { 1857 depth--; 1858 continue; 1859 } 1860 if (depth == 0 && isspace ((unsigned char)*cp)) { 1861 *cp = '\0'; 1862 } 1863 } 1864 opc = cp-1; /* operator is the previous character */ 1865 *cp++ = '\0'; /* nuke the = */ 1866 1867 /* 1868 * Check operator type 1869 */ 1870 switch (*opc) { 1871 case '+': 1872 type = VAR_APPEND; 1873 *opc = '\0'; 1874 break; 1875 1876 case '?': 1877 /* 1878 * If the variable already has a value, we don't do anything. 1879 */ 1880 *opc = '\0'; 1881 if (Var_Exists(line, ctxt)) { 1882 return; 1883 } else { 1884 type = VAR_NORMAL; 1885 } 1886 break; 1887 1888 case ':': 1889 type = VAR_SUBST; 1890 *opc = '\0'; 1891 break; 1892 1893 case '!': 1894 type = VAR_SHELL; 1895 *opc = '\0'; 1896 break; 1897 1898 default: 1899 #ifdef SUNSHCMD 1900 while (opc > line && *opc != ':') 1901 opc--; 1902 1903 if (strncmp(opc, ":sh", 3) == 0) { 1904 type = VAR_SHELL; 1905 *opc = '\0'; 1906 break; 1907 } 1908 #endif 1909 type = VAR_NORMAL; 1910 break; 1911 } 1912 1913 while (isspace((unsigned char)*cp)) 1914 cp++; 1915 1916 if (DEBUG(LINT)) { 1917 if (type != VAR_SUBST && strchr(cp, '$') != NULL) { 1918 /* sanity check now */ 1919 char *cp2; 1920 1921 cp2 = Var_Subst(cp, ctxt, VARE_ASSIGN); 1922 free(cp2); 1923 } 1924 } 1925 1926 if (type == VAR_APPEND) { 1927 Var_Append(line, cp, ctxt); 1928 } else if (type == VAR_SUBST) { 1929 /* 1930 * Allow variables in the old value to be undefined, but leave their 1931 * invocation alone -- this is done by forcing oldVars to be false. 1932 * XXX: This can cause recursive variables, but that's not hard to do, 1933 * and this allows someone to do something like 1934 * 1935 * CFLAGS = $(.INCLUDES) 1936 * CFLAGS := -I.. $(CFLAGS) 1937 * 1938 * And not get an error. 1939 */ 1940 Boolean oldOldVars = oldVars; 1941 1942 oldVars = FALSE; 1943 1944 /* 1945 * make sure that we set the variable the first time to nothing 1946 * so that it gets substituted! 1947 */ 1948 if (!Var_Exists(line, ctxt)) 1949 Var_Set(line, "", ctxt); 1950 1951 cp = Var_Subst(cp, ctxt, VARE_WANTRES|VARE_ASSIGN); 1952 oldVars = oldOldVars; 1953 freeCp = TRUE; 1954 1955 Var_Set(line, cp, ctxt); 1956 } else if (type == VAR_SHELL) { 1957 char *res; 1958 const char *error; 1959 1960 if (strchr(cp, '$') != NULL) { 1961 /* 1962 * There's a dollar sign in the command, so perform variable 1963 * expansion on the whole thing. The resulting string will need 1964 * freeing when we're done. 1965 */ 1966 cp = Var_Subst(cp, VAR_CMD, VARE_UNDEFERR|VARE_WANTRES); 1967 freeCp = TRUE; 1968 } 1969 1970 res = Cmd_Exec(cp, &error); 1971 Var_Set(line, res, ctxt); 1972 free(res); 1973 1974 if (error) 1975 Parse_Error(PARSE_WARNING, error, cp); 1976 } else { 1977 /* 1978 * Normal assignment -- just do it. 1979 */ 1980 Var_Set(line, cp, ctxt); 1981 } 1982 if (strcmp(line, MAKEOVERRIDES) == 0) 1983 Main_ExportMAKEFLAGS(FALSE); /* re-export MAKEFLAGS */ 1984 else if (strcmp(line, ".CURDIR") == 0) { 1985 /* 1986 * Somone is being (too?) clever... 1987 * Let's pretend they know what they are doing and 1988 * re-initialize the 'cur' Path. 1989 */ 1990 Dir_InitCur(cp); 1991 Dir_SetPATH(); 1992 } else if (strcmp(line, MAKE_JOB_PREFIX) == 0) { 1993 Job_SetPrefix(); 1994 } else if (strcmp(line, MAKE_EXPORTED) == 0) { 1995 Var_Export(cp, FALSE); 1996 } 1997 if (freeCp) 1998 free(cp); 1999 } 2000 2001 2002 /* 2003 * ParseMaybeSubMake -- 2004 * Scan the command string to see if it a possible submake node 2005 * Input: 2006 * cmd the command to scan 2007 * Results: 2008 * TRUE if the command is possibly a submake, FALSE if not. 2009 */ 2010 static Boolean 2011 ParseMaybeSubMake(const char *cmd) 2012 { 2013 size_t i; 2014 static struct { 2015 const char *name; 2016 size_t len; 2017 } vals[] = { 2018 #define MKV(A) { A, sizeof(A) - 1 } 2019 MKV("${MAKE}"), 2020 MKV("${.MAKE}"), 2021 MKV("$(MAKE)"), 2022 MKV("$(.MAKE)"), 2023 MKV("make"), 2024 }; 2025 for (i = 0; i < sizeof(vals)/sizeof(vals[0]); i++) { 2026 char *ptr; 2027 if ((ptr = strstr(cmd, vals[i].name)) == NULL) 2028 continue; 2029 if ((ptr == cmd || !isalnum((unsigned char)ptr[-1])) 2030 && !isalnum((unsigned char)ptr[vals[i].len])) 2031 return TRUE; 2032 } 2033 return FALSE; 2034 } 2035 2036 /*- 2037 * ParseAddCmd -- 2038 * Lst_ForEach function to add a command line to all targets 2039 * 2040 * Input: 2041 * gnp the node to which the command is to be added 2042 * cmd the command to add 2043 * 2044 * Results: 2045 * Always 0 2046 * 2047 * Side Effects: 2048 * A new element is added to the commands list of the node, 2049 * and the node can be marked as a submake node if the command is 2050 * determined to be that. 2051 */ 2052 static int 2053 ParseAddCmd(void *gnp, void *cmd) 2054 { 2055 GNode *gn = (GNode *)gnp; 2056 2057 /* Add to last (ie current) cohort for :: targets */ 2058 if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty(gn->cohorts)) 2059 gn = LstNode_Datum(Lst_Last(gn->cohorts)); 2060 2061 /* if target already supplied, ignore commands */ 2062 if (!(gn->type & OP_HAS_COMMANDS)) { 2063 Lst_Append(gn->commands, cmd); 2064 if (ParseMaybeSubMake(cmd)) 2065 gn->type |= OP_SUBMAKE; 2066 ParseMark(gn); 2067 } else { 2068 #ifdef notyet 2069 /* XXX: We cannot do this until we fix the tree */ 2070 Lst_Append(gn->commands, cmd); 2071 Parse_Error(PARSE_WARNING, 2072 "overriding commands for target \"%s\"; " 2073 "previous commands defined at %s: %d ignored", 2074 gn->name, gn->fname, gn->lineno); 2075 #else 2076 Parse_Error(PARSE_WARNING, 2077 "duplicate script for target \"%s\" ignored", 2078 gn->name); 2079 ParseErrorInternal(gn->fname, gn->lineno, PARSE_WARNING, 2080 "using previous script for \"%s\" defined here", 2081 gn->name); 2082 #endif 2083 } 2084 return 0; 2085 } 2086 2087 /* Callback procedure for Parse_File when destroying the list of targets on 2088 * the last dependency line. Marks a target as already having commands if it 2089 * does, to keep from having shell commands on multiple dependency lines. */ 2090 static void 2091 ParseHasCommands(void *gnp) 2092 { 2093 GNode *gn = (GNode *)gnp; 2094 if (!Lst_IsEmpty(gn->commands)) { 2095 gn->type |= OP_HAS_COMMANDS; 2096 } 2097 } 2098 2099 /* Add a directory to the path searched for included makefiles bracketed 2100 * by double-quotes. */ 2101 void 2102 Parse_AddIncludeDir(char *dir) 2103 { 2104 (void)Dir_AddDir(parseIncPath, dir); 2105 } 2106 2107 /* Push to another file. 2108 * 2109 * The input is the line minus the '.'. A file spec is a string enclosed in 2110 * <> or "". The <> file is looked for only in sysIncPath. The "" file is 2111 * first searched in the parsedir and then in the directories specified by 2112 * the -I command line options. 2113 */ 2114 static void 2115 Parse_include_file(char *file, Boolean isSystem, Boolean depinc, int silent) 2116 { 2117 struct loadedfile *lf; 2118 char *fullname; /* full pathname of file */ 2119 char *newName; 2120 char *prefEnd, *incdir; 2121 int fd; 2122 int i; 2123 2124 /* 2125 * Now we know the file's name and its search path, we attempt to 2126 * find the durn thing. A return of NULL indicates the file don't 2127 * exist. 2128 */ 2129 fullname = file[0] == '/' ? bmake_strdup(file) : NULL; 2130 2131 if (fullname == NULL && !isSystem) { 2132 /* 2133 * Include files contained in double-quotes are first searched for 2134 * relative to the including file's location. We don't want to 2135 * cd there, of course, so we just tack on the old file's 2136 * leading path components and call Dir_FindFile to see if 2137 * we can locate the beast. 2138 */ 2139 2140 incdir = bmake_strdup(curFile->fname); 2141 prefEnd = strrchr(incdir, '/'); 2142 if (prefEnd != NULL) { 2143 *prefEnd = '\0'; 2144 /* Now do lexical processing of leading "../" on the filename */ 2145 for (i = 0; strncmp(file + i, "../", 3) == 0; i += 3) { 2146 prefEnd = strrchr(incdir + 1, '/'); 2147 if (prefEnd == NULL || strcmp(prefEnd, "/..") == 0) 2148 break; 2149 *prefEnd = '\0'; 2150 } 2151 newName = str_concat3(incdir, "/", file + i); 2152 fullname = Dir_FindFile(newName, parseIncPath); 2153 if (fullname == NULL) 2154 fullname = Dir_FindFile(newName, dirSearchPath); 2155 free(newName); 2156 } 2157 free(incdir); 2158 2159 if (fullname == NULL) { 2160 /* 2161 * Makefile wasn't found in same directory as included makefile. 2162 * Search for it first on the -I search path, 2163 * then on the .PATH search path, if not found in a -I directory. 2164 * If we have a suffix specific path we should use that. 2165 */ 2166 char *suff; 2167 Lst suffPath = NULL; 2168 2169 if ((suff = strrchr(file, '.'))) { 2170 suffPath = Suff_GetPath(suff); 2171 if (suffPath != NULL) { 2172 fullname = Dir_FindFile(file, suffPath); 2173 } 2174 } 2175 if (fullname == NULL) { 2176 fullname = Dir_FindFile(file, parseIncPath); 2177 if (fullname == NULL) { 2178 fullname = Dir_FindFile(file, dirSearchPath); 2179 } 2180 } 2181 } 2182 } 2183 2184 /* Looking for a system file or file still not found */ 2185 if (fullname == NULL) { 2186 /* 2187 * Look for it on the system path 2188 */ 2189 fullname = Dir_FindFile(file, 2190 Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath); 2191 } 2192 2193 if (fullname == NULL) { 2194 if (!silent) 2195 Parse_Error(PARSE_FATAL, "Could not find %s", file); 2196 return; 2197 } 2198 2199 /* Actually open the file... */ 2200 fd = open(fullname, O_RDONLY); 2201 if (fd == -1) { 2202 if (!silent) 2203 Parse_Error(PARSE_FATAL, "Cannot open %s", fullname); 2204 free(fullname); 2205 return; 2206 } 2207 2208 /* load it */ 2209 lf = loadfile(fullname, fd); 2210 2211 /* Start reading from this file next */ 2212 Parse_SetInput(fullname, 0, -1, loadedfile_nextbuf, lf); 2213 curFile->lf = lf; 2214 if (depinc) 2215 doing_depend = depinc; /* only turn it on */ 2216 } 2217 2218 static void 2219 ParseDoInclude(char *line) 2220 { 2221 char endc; /* the character which ends the file spec */ 2222 char *cp; /* current position in file spec */ 2223 int silent = *line != 'i'; 2224 char *file = &line[7 + silent]; 2225 2226 /* Skip to delimiter character so we know where to look */ 2227 while (*file == ' ' || *file == '\t') 2228 file++; 2229 2230 if (*file != '"' && *file != '<') { 2231 Parse_Error(PARSE_FATAL, 2232 ".include filename must be delimited by '\"' or '<'"); 2233 return; 2234 } 2235 2236 /* 2237 * Set the search path on which to find the include file based on the 2238 * characters which bracket its name. Angle-brackets imply it's 2239 * a system Makefile while double-quotes imply it's a user makefile 2240 */ 2241 if (*file == '<') { 2242 endc = '>'; 2243 } else { 2244 endc = '"'; 2245 } 2246 2247 /* Skip to matching delimiter */ 2248 for (cp = ++file; *cp && *cp != endc; cp++) 2249 continue; 2250 2251 if (*cp != endc) { 2252 Parse_Error(PARSE_FATAL, 2253 "Unclosed %cinclude filename. '%c' expected", 2254 '.', endc); 2255 return; 2256 } 2257 *cp = '\0'; 2258 2259 /* 2260 * Substitute for any variables in the file name before trying to 2261 * find the thing. 2262 */ 2263 file = Var_Subst(file, VAR_CMD, VARE_WANTRES); 2264 2265 Parse_include_file(file, endc == '>', *line == 'd', silent); 2266 free(file); 2267 } 2268 2269 /* Split filename into dirname + basename, then assign these to the 2270 * given variables. */ 2271 static void 2272 SetFilenameVars(const char *filename, const char *dirvar, const char *filevar) 2273 { 2274 const char *slash, *dirname, *basename; 2275 void *freeIt; 2276 2277 slash = strrchr(filename, '/'); 2278 if (slash == NULL) { 2279 dirname = curdir; 2280 basename = filename; 2281 freeIt = NULL; 2282 } else { 2283 dirname = freeIt = bmake_strsedup(filename, slash); 2284 basename = slash + 1; 2285 } 2286 2287 Var_Set(dirvar, dirname, VAR_GLOBAL); 2288 Var_Set(filevar, basename, VAR_GLOBAL); 2289 2290 if (DEBUG(PARSE)) 2291 fprintf(debug_file, "%s: ${%s} = `%s' ${%s} = `%s'\n", 2292 __func__, dirvar, dirname, filevar, basename); 2293 free(freeIt); 2294 } 2295 2296 /* Return the immediately including file. 2297 * 2298 * This is made complicated since the .for loop is implemented as a special 2299 * kind of .include; see For_Run. */ 2300 static const char * 2301 GetActuallyIncludingFile(void) 2302 { 2303 size_t i; 2304 2305 /* XXX: Stack was supposed to be an opaque data structure. */ 2306 for (i = includes.len; i > 0; i--) { 2307 IFile *parent = includes.items[i - 1]; 2308 IFile *child = i < includes.len ? includes.items[i] : curFile; 2309 if (!child->fromForLoop) 2310 return parent->fname; 2311 } 2312 return NULL; 2313 } 2314 2315 /* Set .PARSEDIR, .PARSEFILE, .INCLUDEDFROMDIR and .INCLUDEDFROMFILE. */ 2316 static void 2317 ParseSetParseFile(const char *filename) 2318 { 2319 const char *including; 2320 2321 SetFilenameVars(filename, ".PARSEDIR", ".PARSEFILE"); 2322 2323 including = GetActuallyIncludingFile(); 2324 if (including != NULL) { 2325 SetFilenameVars(including, 2326 ".INCLUDEDFROMDIR", ".INCLUDEDFROMFILE"); 2327 } else { 2328 Var_Delete(".INCLUDEDFROMDIR", VAR_GLOBAL); 2329 Var_Delete(".INCLUDEDFROMFILE", VAR_GLOBAL); 2330 } 2331 } 2332 2333 /* Track the makefiles we read - so makefiles can set dependencies on them. 2334 * Avoid adding anything more than once. */ 2335 static void 2336 ParseTrackInput(const char *name) 2337 { 2338 char *fp = NULL; 2339 2340 const char *old = Var_Value(MAKE_MAKEFILES, VAR_GLOBAL, &fp); 2341 if (old) { 2342 size_t name_len = strlen(name); 2343 const char *ep = old + strlen(old) - name_len; 2344 /* does it contain name? */ 2345 for (; old != NULL; old = strchr(old, ' ')) { 2346 if (*old == ' ') 2347 old++; 2348 if (old >= ep) 2349 break; /* cannot contain name */ 2350 if (memcmp(old, name, name_len) == 0 2351 && (old[name_len] == 0 || old[name_len] == ' ')) 2352 goto cleanup; 2353 } 2354 } 2355 Var_Append (MAKE_MAKEFILES, name, VAR_GLOBAL); 2356 cleanup: 2357 bmake_free(fp); 2358 } 2359 2360 2361 /* Start Parsing from the given source. 2362 * 2363 * The given file is added to the includes stack. */ 2364 void 2365 Parse_SetInput(const char *name, int line, int fd, 2366 char *(*nextbuf)(void *, size_t *), void *arg) 2367 { 2368 char *buf; 2369 size_t len; 2370 Boolean fromForLoop = name == NULL; 2371 2372 if (fromForLoop) 2373 name = curFile->fname; 2374 else 2375 ParseTrackInput(name); 2376 2377 if (DEBUG(PARSE)) 2378 fprintf(debug_file, "%s: file %s, line %d, fd %d, nextbuf %p, arg %p\n", 2379 __func__, name, line, fd, nextbuf, arg); 2380 2381 if (fd == -1 && nextbuf == NULL) 2382 /* sanity */ 2383 return; 2384 2385 if (curFile != NULL) 2386 /* Save existing file info */ 2387 Stack_Push(&includes, curFile); 2388 2389 /* Allocate and fill in new structure */ 2390 curFile = bmake_malloc(sizeof *curFile); 2391 2392 /* 2393 * Once the previous state has been saved, we can get down to reading 2394 * the new file. We set up the name of the file to be the absolute 2395 * name of the include file so error messages refer to the right 2396 * place. 2397 */ 2398 curFile->fname = bmake_strdup(name); 2399 curFile->fromForLoop = fromForLoop; 2400 curFile->lineno = line; 2401 curFile->first_lineno = line; 2402 curFile->nextbuf = nextbuf; 2403 curFile->nextbuf_arg = arg; 2404 curFile->lf = NULL; 2405 curFile->depending = doing_depend; /* restore this on EOF */ 2406 2407 assert(nextbuf != NULL); 2408 2409 /* Get first block of input data */ 2410 buf = curFile->nextbuf(curFile->nextbuf_arg, &len); 2411 if (buf == NULL) { 2412 /* Was all a waste of time ... */ 2413 if (curFile->fname) 2414 free(curFile->fname); 2415 free(curFile); 2416 return; 2417 } 2418 curFile->P_str = buf; 2419 curFile->P_ptr = buf; 2420 curFile->P_end = buf+len; 2421 2422 curFile->cond_depth = Cond_save_depth(); 2423 ParseSetParseFile(name); 2424 } 2425 2426 /* Check if the line is an include directive. */ 2427 static Boolean 2428 IsInclude(const char *line, Boolean sysv) 2429 { 2430 static const char inc[] = "include"; 2431 static const size_t inclen = sizeof(inc) - 1; 2432 2433 /* 'd' is not valid for sysv */ 2434 int o = strchr(sysv ? "s-" : "ds-", *line) != NULL; 2435 2436 if (strncmp(line + o, inc, inclen) != 0) 2437 return FALSE; 2438 2439 /* Space is not mandatory for BSD .include */ 2440 return !sysv || isspace((unsigned char)line[inclen + o]); 2441 } 2442 2443 2444 #ifdef SYSVINCLUDE 2445 /* Check if the line is a SYSV include directive. */ 2446 static Boolean 2447 IsSysVInclude(const char *line) 2448 { 2449 const char *p; 2450 2451 if (!IsInclude(line, TRUE)) 2452 return FALSE; 2453 2454 /* Avoid interpeting a dependency line as an include */ 2455 for (p = line; (p = strchr(p, ':')) != NULL;) { 2456 if (*++p == '\0') { 2457 /* end of line -> dependency */ 2458 return FALSE; 2459 } 2460 if (*p == ':' || isspace((unsigned char)*p)) { 2461 /* :: operator or ': ' -> dependency */ 2462 return FALSE; 2463 } 2464 } 2465 return TRUE; 2466 } 2467 2468 /* Push to another file. The line points to the word "include". */ 2469 static void 2470 ParseTraditionalInclude(char *line) 2471 { 2472 char *cp; /* current position in file spec */ 2473 int done = 0; 2474 int silent = line[0] != 'i'; 2475 char *file = &line[silent + 7]; 2476 char *all_files; 2477 2478 if (DEBUG(PARSE)) 2479 fprintf(debug_file, "%s: %s\n", __func__, file); 2480 2481 /* 2482 * Skip over whitespace 2483 */ 2484 while (isspace((unsigned char)*file)) 2485 file++; 2486 2487 /* 2488 * Substitute for any variables in the file name before trying to 2489 * find the thing. 2490 */ 2491 all_files = Var_Subst(file, VAR_CMD, VARE_WANTRES); 2492 2493 if (*file == '\0') { 2494 Parse_Error(PARSE_FATAL, 2495 "Filename missing from \"include\""); 2496 goto out; 2497 } 2498 2499 for (file = all_files; !done; file = cp + 1) { 2500 /* Skip to end of line or next whitespace */ 2501 for (cp = file; *cp && !isspace((unsigned char) *cp); cp++) 2502 continue; 2503 2504 if (*cp) 2505 *cp = '\0'; 2506 else 2507 done = 1; 2508 2509 Parse_include_file(file, FALSE, FALSE, silent); 2510 } 2511 out: 2512 free(all_files); 2513 } 2514 #endif 2515 2516 #ifdef GMAKEEXPORT 2517 /* Parse export <variable>=<value>, and actually export it. */ 2518 static void 2519 ParseGmakeExport(char *line) 2520 { 2521 char *variable = &line[6]; 2522 char *value; 2523 2524 if (DEBUG(PARSE)) 2525 fprintf(debug_file, "%s: %s\n", __func__, variable); 2526 2527 /* 2528 * Skip over whitespace 2529 */ 2530 while (isspace((unsigned char)*variable)) 2531 variable++; 2532 2533 for (value = variable; *value && *value != '='; value++) 2534 continue; 2535 2536 if (*value != '=') { 2537 Parse_Error(PARSE_FATAL, 2538 "Variable/Value missing from \"export\""); 2539 return; 2540 } 2541 *value++ = '\0'; /* terminate variable */ 2542 2543 /* 2544 * Expand the value before putting it in the environment. 2545 */ 2546 value = Var_Subst(value, VAR_CMD, VARE_WANTRES); 2547 setenv(variable, value, 1); 2548 free(value); 2549 } 2550 #endif 2551 2552 /* Called when EOF is reached in the current file. If we were reading an 2553 * include file, the includes stack is popped and things set up to go back 2554 * to reading the previous file at the previous location. 2555 * 2556 * Results: 2557 * CONTINUE if there's more to do. DONE if not. 2558 */ 2559 static int 2560 ParseEOF(void) 2561 { 2562 char *ptr; 2563 size_t len; 2564 2565 assert(curFile->nextbuf != NULL); 2566 2567 doing_depend = curFile->depending; /* restore this */ 2568 /* get next input buffer, if any */ 2569 ptr = curFile->nextbuf(curFile->nextbuf_arg, &len); 2570 curFile->P_ptr = ptr; 2571 curFile->P_str = ptr; 2572 curFile->P_end = ptr + len; 2573 curFile->lineno = curFile->first_lineno; 2574 if (ptr != NULL) { 2575 /* Iterate again */ 2576 return CONTINUE; 2577 } 2578 2579 /* Ensure the makefile (or loop) didn't have mismatched conditionals */ 2580 Cond_restore_depth(curFile->cond_depth); 2581 2582 if (curFile->lf != NULL) { 2583 loadedfile_destroy(curFile->lf); 2584 curFile->lf = NULL; 2585 } 2586 2587 /* Dispose of curFile info */ 2588 /* Leak curFile->fname because all the gnodes have pointers to it */ 2589 free(curFile->P_str); 2590 free(curFile); 2591 2592 if (Stack_IsEmpty(&includes)) { 2593 curFile = NULL; 2594 /* We've run out of input */ 2595 Var_Delete(".PARSEDIR", VAR_GLOBAL); 2596 Var_Delete(".PARSEFILE", VAR_GLOBAL); 2597 Var_Delete(".INCLUDEDFROMDIR", VAR_GLOBAL); 2598 Var_Delete(".INCLUDEDFROMFILE", VAR_GLOBAL); 2599 return DONE; 2600 } 2601 2602 curFile = Stack_Pop(&includes); 2603 if (DEBUG(PARSE)) 2604 fprintf(debug_file, "ParseEOF: returning to file %s, line %d\n", 2605 curFile->fname, curFile->lineno); 2606 2607 ParseSetParseFile(curFile->fname); 2608 return CONTINUE; 2609 } 2610 2611 #define PARSE_RAW 1 2612 #define PARSE_SKIP 2 2613 2614 static char * 2615 ParseGetLine(int flags, int *length) 2616 { 2617 IFile *cf = curFile; 2618 char *ptr; 2619 char ch; 2620 char *line; 2621 char *line_end; 2622 char *escaped; 2623 char *comment; 2624 char *tp; 2625 2626 /* Loop through blank lines and comment lines */ 2627 for (;;) { 2628 cf->lineno++; 2629 line = cf->P_ptr; 2630 ptr = line; 2631 line_end = line; 2632 escaped = NULL; 2633 comment = NULL; 2634 for (;;) { 2635 if (cf->P_end != NULL && ptr == cf->P_end) { 2636 /* end of buffer */ 2637 ch = 0; 2638 break; 2639 } 2640 ch = *ptr; 2641 if (ch == 0 || (ch == '\\' && ptr[1] == 0)) { 2642 if (cf->P_end == NULL) 2643 /* End of string (aka for loop) data */ 2644 break; 2645 /* see if there is more we can parse */ 2646 while (ptr++ < cf->P_end) { 2647 if ((ch = *ptr) == '\n') { 2648 if (ptr > line && ptr[-1] == '\\') 2649 continue; 2650 Parse_Error(PARSE_WARNING, 2651 "Zero byte read from file, skipping rest of line."); 2652 break; 2653 } 2654 } 2655 if (cf->nextbuf != NULL) { 2656 /* 2657 * End of this buffer; return EOF and outer logic 2658 * will get the next one. (eww) 2659 */ 2660 break; 2661 } 2662 Parse_Error(PARSE_FATAL, "Zero byte read from file"); 2663 return NULL; 2664 } 2665 2666 if (ch == '\\') { 2667 /* Don't treat next character as special, remember first one */ 2668 if (escaped == NULL) 2669 escaped = ptr; 2670 if (ptr[1] == '\n') 2671 cf->lineno++; 2672 ptr += 2; 2673 line_end = ptr; 2674 continue; 2675 } 2676 if (ch == '#' && comment == NULL) { 2677 /* Remember first '#' for comment stripping */ 2678 /* Unless previous char was '[', as in modifier :[#] */ 2679 if (!(ptr > line && ptr[-1] == '[')) 2680 comment = line_end; 2681 } 2682 ptr++; 2683 if (ch == '\n') 2684 break; 2685 if (!isspace((unsigned char)ch)) 2686 /* We are not interested in trailing whitespace */ 2687 line_end = ptr; 2688 } 2689 2690 /* Save next 'to be processed' location */ 2691 cf->P_ptr = ptr; 2692 2693 /* Check we have a non-comment, non-blank line */ 2694 if (line_end == line || comment == line) { 2695 if (ch == 0) 2696 /* At end of file */ 2697 return NULL; 2698 /* Parse another line */ 2699 continue; 2700 } 2701 2702 /* We now have a line of data */ 2703 *line_end = 0; 2704 2705 if (flags & PARSE_RAW) { 2706 /* Leave '\' (etc) in line buffer (eg 'for' lines) */ 2707 *length = line_end - line; 2708 return line; 2709 } 2710 2711 if (flags & PARSE_SKIP) { 2712 /* Completely ignore non-directives */ 2713 if (line[0] != '.') 2714 continue; 2715 /* We could do more of the .else/.elif/.endif checks here */ 2716 } 2717 break; 2718 } 2719 2720 /* Brutally ignore anything after a non-escaped '#' in non-commands */ 2721 if (comment != NULL && line[0] != '\t') { 2722 line_end = comment; 2723 *line_end = 0; 2724 } 2725 2726 /* If we didn't see a '\\' then the in-situ data is fine */ 2727 if (escaped == NULL) { 2728 *length = line_end - line; 2729 return line; 2730 } 2731 2732 /* Remove escapes from '\n' and '#' */ 2733 tp = ptr = escaped; 2734 escaped = line; 2735 for (; ; *tp++ = ch) { 2736 ch = *ptr++; 2737 if (ch != '\\') { 2738 if (ch == 0) 2739 break; 2740 continue; 2741 } 2742 2743 ch = *ptr++; 2744 if (ch == 0) { 2745 /* Delete '\\' at end of buffer */ 2746 tp--; 2747 break; 2748 } 2749 2750 if (ch == '#' && line[0] != '\t') 2751 /* Delete '\\' from before '#' on non-command lines */ 2752 continue; 2753 2754 if (ch != '\n') { 2755 /* Leave '\\' in buffer for later */ 2756 *tp++ = '\\'; 2757 /* Make sure we don't delete an escaped ' ' from the line end */ 2758 escaped = tp + 1; 2759 continue; 2760 } 2761 2762 /* Escaped '\n' replace following whitespace with a single ' ' */ 2763 while (ptr[0] == ' ' || ptr[0] == '\t') 2764 ptr++; 2765 ch = ' '; 2766 } 2767 2768 /* Delete any trailing spaces - eg from empty continuations */ 2769 while (tp > escaped && isspace((unsigned char)tp[-1])) 2770 tp--; 2771 2772 *tp = 0; 2773 *length = tp - line; 2774 return line; 2775 } 2776 2777 /* Read an entire line from the input file. Called only by Parse_File. 2778 * 2779 * Results: 2780 * A line without its newline. 2781 * 2782 * Side Effects: 2783 * Only those associated with reading a character 2784 */ 2785 static char * 2786 ParseReadLine(void) 2787 { 2788 char *line; /* Result */ 2789 int lineLength; /* Length of result */ 2790 int lineno; /* Saved line # */ 2791 int rval; 2792 2793 for (;;) { 2794 line = ParseGetLine(0, &lineLength); 2795 if (line == NULL) 2796 return NULL; 2797 2798 if (line[0] != '.') 2799 return line; 2800 2801 /* 2802 * The line might be a conditional. Ask the conditional module 2803 * about it and act accordingly 2804 */ 2805 switch (Cond_Eval(line)) { 2806 case COND_SKIP: 2807 /* Skip to next conditional that evaluates to COND_PARSE. */ 2808 do { 2809 line = ParseGetLine(PARSE_SKIP, &lineLength); 2810 } while (line && Cond_Eval(line) != COND_PARSE); 2811 if (line == NULL) 2812 break; 2813 continue; 2814 case COND_PARSE: 2815 continue; 2816 case COND_INVALID: /* Not a conditional line */ 2817 /* Check for .for loops */ 2818 rval = For_Eval(line); 2819 if (rval == 0) 2820 /* Not a .for line */ 2821 break; 2822 if (rval < 0) 2823 /* Syntax error - error printed, ignore line */ 2824 continue; 2825 /* Start of a .for loop */ 2826 lineno = curFile->lineno; 2827 /* Accumulate loop lines until matching .endfor */ 2828 do { 2829 line = ParseGetLine(PARSE_RAW, &lineLength); 2830 if (line == NULL) { 2831 Parse_Error(PARSE_FATAL, 2832 "Unexpected end of file in for loop."); 2833 break; 2834 } 2835 } while (For_Accum(line)); 2836 /* Stash each iteration as a new 'input file' */ 2837 For_Run(lineno); 2838 /* Read next line from for-loop buffer */ 2839 continue; 2840 } 2841 return line; 2842 } 2843 } 2844 2845 /*- 2846 *----------------------------------------------------------------------- 2847 * ParseFinishLine -- 2848 * Handle the end of a dependency group. 2849 * 2850 * Results: 2851 * Nothing. 2852 * 2853 * Side Effects: 2854 * inLine set FALSE. 'targets' list destroyed. 2855 * 2856 *----------------------------------------------------------------------- 2857 */ 2858 static void 2859 ParseFinishLine(void) 2860 { 2861 if (inLine) { 2862 if (targets != NULL) { 2863 Lst_ForEach(targets, Suff_EndTransform, NULL); 2864 Lst_Destroy(targets, ParseHasCommands); 2865 } 2866 targets = NULL; 2867 inLine = FALSE; 2868 } 2869 } 2870 2871 2872 /*- 2873 *--------------------------------------------------------------------- 2874 * Parse_File -- 2875 * Parse a file into its component parts, incorporating it into the 2876 * current dependency graph. This is the main function and controls 2877 * almost every other function in this module 2878 * 2879 * Input: 2880 * name the name of the file being read 2881 * fd Open file to makefile to parse 2882 * 2883 * Results: 2884 * None 2885 * 2886 * Side Effects: 2887 * closes fd. 2888 * Loads. Nodes are added to the list of all targets, nodes and links 2889 * are added to the dependency graph. etc. etc. etc. 2890 *--------------------------------------------------------------------- 2891 */ 2892 void 2893 Parse_File(const char *name, int fd) 2894 { 2895 char *cp; /* pointer into the line */ 2896 char *line; /* the line we're working on */ 2897 struct loadedfile *lf; 2898 2899 lf = loadfile(name, fd); 2900 2901 inLine = FALSE; 2902 fatals = 0; 2903 2904 if (name == NULL) 2905 name = "(stdin)"; 2906 2907 Parse_SetInput(name, 0, -1, loadedfile_nextbuf, lf); 2908 curFile->lf = lf; 2909 2910 do { 2911 for (; (line = ParseReadLine()) != NULL; ) { 2912 if (DEBUG(PARSE)) 2913 fprintf(debug_file, "ParseReadLine (%d): '%s'\n", 2914 curFile->lineno, line); 2915 if (*line == '.') { 2916 /* 2917 * Lines that begin with the special character may be 2918 * include or undef directives. 2919 * On the other hand they can be suffix rules (.c.o: ...) 2920 * or just dependencies for filenames that start '.'. 2921 */ 2922 for (cp = line + 1; isspace((unsigned char)*cp); cp++) { 2923 continue; 2924 } 2925 if (IsInclude(cp, FALSE)) { 2926 ParseDoInclude(cp); 2927 continue; 2928 } 2929 if (strncmp(cp, "undef", 5) == 0) { 2930 char *cp2; 2931 for (cp += 5; isspace((unsigned char) *cp); cp++) 2932 continue; 2933 for (cp2 = cp; !isspace((unsigned char) *cp2) && 2934 *cp2 != '\0'; cp2++) 2935 continue; 2936 *cp2 = '\0'; 2937 Var_Delete(cp, VAR_GLOBAL); 2938 continue; 2939 } else if (strncmp(cp, "export", 6) == 0) { 2940 for (cp += 6; isspace((unsigned char) *cp); cp++) 2941 continue; 2942 Var_Export(cp, TRUE); 2943 continue; 2944 } else if (strncmp(cp, "unexport", 8) == 0) { 2945 Var_UnExport(cp); 2946 continue; 2947 } else if (strncmp(cp, "info", 4) == 0 || 2948 strncmp(cp, "error", 5) == 0 || 2949 strncmp(cp, "warning", 7) == 0) { 2950 if (ParseMessage(cp)) 2951 continue; 2952 } 2953 } 2954 2955 if (*line == '\t') { 2956 /* 2957 * If a line starts with a tab, it can only hope to be 2958 * a creation command. 2959 */ 2960 cp = line + 1; 2961 shellCommand: 2962 for (; isspace ((unsigned char)*cp); cp++) { 2963 continue; 2964 } 2965 if (*cp) { 2966 if (!inLine) 2967 Parse_Error(PARSE_FATAL, 2968 "Unassociated shell command \"%s\"", 2969 cp); 2970 /* 2971 * So long as it's not a blank line and we're actually 2972 * in a dependency spec, add the command to the list of 2973 * commands of all targets in the dependency spec 2974 */ 2975 if (targets) { 2976 cp = bmake_strdup(cp); 2977 Lst_ForEach(targets, ParseAddCmd, cp); 2978 #ifdef CLEANUP 2979 Lst_Append(targCmds, cp); 2980 #endif 2981 } 2982 } 2983 continue; 2984 } 2985 2986 #ifdef SYSVINCLUDE 2987 if (IsSysVInclude(line)) { 2988 /* 2989 * It's an S3/S5-style "include". 2990 */ 2991 ParseTraditionalInclude(line); 2992 continue; 2993 } 2994 #endif 2995 #ifdef GMAKEEXPORT 2996 if (strncmp(line, "export", 6) == 0 && 2997 isspace((unsigned char) line[6]) && 2998 strchr(line, ':') == NULL) { 2999 /* 3000 * It's a Gmake "export". 3001 */ 3002 ParseGmakeExport(line); 3003 continue; 3004 } 3005 #endif 3006 if (Parse_IsVar(line)) { 3007 ParseFinishLine(); 3008 Parse_DoVar(line, VAR_GLOBAL); 3009 continue; 3010 } 3011 3012 #ifndef POSIX 3013 /* 3014 * To make life easier on novices, if the line is indented we 3015 * first make sure the line has a dependency operator in it. 3016 * If it doesn't have an operator and we're in a dependency 3017 * line's script, we assume it's actually a shell command 3018 * and add it to the current list of targets. 3019 */ 3020 cp = line; 3021 if (isspace((unsigned char) line[0])) { 3022 while (isspace((unsigned char) *cp)) 3023 cp++; 3024 while (*cp && (ParseIsEscaped(line, cp) || 3025 *cp != ':' && *cp != '!')) { 3026 cp++; 3027 } 3028 if (*cp == '\0') { 3029 if (inLine) { 3030 Parse_Error(PARSE_WARNING, 3031 "Shell command needs a leading tab"); 3032 goto shellCommand; 3033 } 3034 } 3035 } 3036 #endif 3037 ParseFinishLine(); 3038 3039 /* 3040 * For some reason - probably to make the parser impossible - 3041 * a ';' can be used to separate commands from dependencies. 3042 * Attempt to avoid ';' inside substitution patterns. 3043 */ 3044 { 3045 int level = 0; 3046 3047 for (cp = line; *cp != 0; cp++) { 3048 if (*cp == '\\' && cp[1] != 0) { 3049 cp++; 3050 continue; 3051 } 3052 if (*cp == '$' && 3053 (cp[1] == '(' || cp[1] == '{')) { 3054 level++; 3055 continue; 3056 } 3057 if (level > 0) { 3058 if (*cp == ')' || *cp == '}') { 3059 level--; 3060 continue; 3061 } 3062 } else if (*cp == ';') { 3063 break; 3064 } 3065 } 3066 } 3067 if (*cp != 0) 3068 /* Terminate the dependency list at the ';' */ 3069 *cp++ = 0; 3070 else 3071 cp = NULL; 3072 3073 /* 3074 * We now know it's a dependency line so it needs to have all 3075 * variables expanded before being parsed. Tell the variable 3076 * module to complain if some variable is undefined... 3077 */ 3078 line = Var_Subst(line, VAR_CMD, VARE_UNDEFERR|VARE_WANTRES); 3079 3080 /* 3081 * Need a non-circular list for the target nodes 3082 */ 3083 if (targets != NULL) 3084 Lst_Free(targets); 3085 3086 targets = Lst_Init(); 3087 inLine = TRUE; 3088 3089 ParseDoDependency(line); 3090 free(line); 3091 3092 /* If there were commands after a ';', add them now */ 3093 if (cp != NULL) { 3094 goto shellCommand; 3095 } 3096 } 3097 /* 3098 * Reached EOF, but it may be just EOF of an include file... 3099 */ 3100 } while (ParseEOF() == CONTINUE); 3101 3102 if (fatals) { 3103 (void)fflush(stdout); 3104 (void)fprintf(stderr, 3105 "%s: Fatal errors encountered -- cannot continue", 3106 progname); 3107 PrintOnError(NULL, NULL); 3108 exit(1); 3109 } 3110 } 3111 3112 /*- 3113 *--------------------------------------------------------------------- 3114 * Parse_Init -- 3115 * initialize the parsing module 3116 * 3117 * Results: 3118 * none 3119 * 3120 * Side Effects: 3121 * the parseIncPath list is initialized... 3122 *--------------------------------------------------------------------- 3123 */ 3124 void 3125 Parse_Init(void) 3126 { 3127 mainNode = NULL; 3128 parseIncPath = Lst_Init(); 3129 sysIncPath = Lst_Init(); 3130 defIncPath = Lst_Init(); 3131 Stack_Init(&includes); 3132 #ifdef CLEANUP 3133 targCmds = Lst_Init(); 3134 #endif 3135 } 3136 3137 void 3138 Parse_End(void) 3139 { 3140 #ifdef CLEANUP 3141 Lst_Destroy(targCmds, free); 3142 if (targets) 3143 Lst_Free(targets); 3144 Lst_Destroy(defIncPath, Dir_Destroy); 3145 Lst_Destroy(sysIncPath, Dir_Destroy); 3146 Lst_Destroy(parseIncPath, Dir_Destroy); 3147 assert(Stack_IsEmpty(&includes)); 3148 Stack_Done(&includes); 3149 #endif 3150 } 3151 3152 3153 /*- 3154 *----------------------------------------------------------------------- 3155 * Parse_MainName -- 3156 * Return a Lst of the main target to create for main()'s sake. If 3157 * no such target exists, we Punt with an obnoxious error message. 3158 * 3159 * Results: 3160 * A Lst of the single node to create. 3161 * 3162 * Side Effects: 3163 * None. 3164 * 3165 *----------------------------------------------------------------------- 3166 */ 3167 Lst 3168 Parse_MainName(void) 3169 { 3170 Lst mainList; /* result list */ 3171 3172 mainList = Lst_Init(); 3173 3174 if (mainNode == NULL) { 3175 Punt("no target to make."); 3176 /*NOTREACHED*/ 3177 } else if (mainNode->type & OP_DOUBLEDEP) { 3178 Lst_Append(mainList, mainNode); 3179 Lst_AppendAll(mainList, mainNode->cohorts); 3180 } 3181 else 3182 Lst_Append(mainList, mainNode); 3183 Var_Append(".TARGETS", mainNode->name, VAR_GLOBAL); 3184 return mainList; 3185 } 3186