1 /* $NetBSD: parse.c,v 1.595 2021/12/28 16:59:09 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 /* 72 * Parsing of makefiles. 73 * 74 * Parse_File is the main entry point and controls most of the other 75 * functions in this module. 76 * 77 * The directories for the .include "..." directive are kept in 78 * 'parseIncPath', while those for .include <...> are kept in 'sysIncPath'. 79 * The targets currently being defined are kept in 'targets'. 80 * 81 * Interface: 82 * Parse_Init Initialize the module 83 * 84 * Parse_End Clean up the module 85 * 86 * Parse_File Parse a top-level makefile. Included files are 87 * handled by IncludeFile instead. 88 * 89 * Parse_IsVar Return true if the given line is a variable 90 * assignment. Used by MainParseArgs to determine if 91 * an argument is a target or a variable assignment. 92 * Used internally for pretty much the same thing. 93 * 94 * Parse_Error Report a parse error, a warning or an informational 95 * message. 96 * 97 * Parse_MainName Returns a list of the main target to create. 98 */ 99 100 #include <sys/types.h> 101 #include <sys/stat.h> 102 #include <errno.h> 103 #include <stdarg.h> 104 #include <stdint.h> 105 106 #include "make.h" 107 #include "dir.h" 108 #include "job.h" 109 #include "pathnames.h" 110 111 /* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */ 112 MAKE_RCSID("$NetBSD: parse.c,v 1.595 2021/12/28 16:59:09 rillig Exp $"); 113 114 /* types and constants */ 115 116 /* 117 * Structure for a file being read ("included file") 118 */ 119 typedef struct IFile { 120 FStr name; /* absolute or relative to the cwd */ 121 bool fromForLoop; /* simulated .include by the .for loop */ 122 int lineno; /* current line number in file */ 123 int first_lineno; /* line number of start of text */ 124 unsigned int cond_depth; /* 'if' nesting when file opened */ 125 bool depending; /* state of doing_depend on EOF */ 126 127 /* 128 * The buffer from which the file's content is read. The buffer 129 * always ends with '\n', the buffer is not null-terminated, that is, 130 * buf_end[0] is already out of bounds. 131 */ 132 char *buf_freeIt; 133 char *buf_ptr; /* next char to be read */ 134 char *buf_end; /* buf_end[-1] == '\n' */ 135 136 /* Function to read more data, with a single opaque argument. */ 137 ReadMoreProc readMore; 138 void *readMoreArg; 139 140 struct loadedfile *lf; /* loadedfile object, if any */ 141 } IFile; 142 143 /* 144 * Tokens for target attributes 145 */ 146 typedef enum ParseSpecial { 147 SP_ATTRIBUTE, /* Generic attribute */ 148 SP_BEGIN, /* .BEGIN */ 149 SP_DEFAULT, /* .DEFAULT */ 150 SP_DELETE_ON_ERROR, /* .DELETE_ON_ERROR */ 151 SP_END, /* .END */ 152 SP_ERROR, /* .ERROR */ 153 SP_IGNORE, /* .IGNORE */ 154 SP_INCLUDES, /* .INCLUDES; not mentioned in the manual page */ 155 SP_INTERRUPT, /* .INTERRUPT */ 156 SP_LIBS, /* .LIBS; not mentioned in the manual page */ 157 SP_MAIN, /* .MAIN and no user-specified targets to make */ 158 SP_META, /* .META */ 159 SP_MFLAGS, /* .MFLAGS or .MAKEFLAGS */ 160 SP_NOMETA, /* .NOMETA */ 161 SP_NOMETA_CMP, /* .NOMETA_CMP */ 162 SP_NOPATH, /* .NOPATH */ 163 SP_NOT, /* Not special */ 164 SP_NOTPARALLEL, /* .NOTPARALLEL or .NO_PARALLEL */ 165 SP_NULL, /* .NULL; not mentioned in the manual page */ 166 SP_OBJDIR, /* .OBJDIR */ 167 SP_ORDER, /* .ORDER */ 168 SP_PARALLEL, /* .PARALLEL; not mentioned in the manual page */ 169 SP_PATH, /* .PATH or .PATH.suffix */ 170 SP_PHONY, /* .PHONY */ 171 #ifdef POSIX 172 SP_POSIX, /* .POSIX; not mentioned in the manual page */ 173 #endif 174 SP_PRECIOUS, /* .PRECIOUS */ 175 SP_SHELL, /* .SHELL */ 176 SP_SILENT, /* .SILENT */ 177 SP_SINGLESHELL, /* .SINGLESHELL; not mentioned in the manual page */ 178 SP_STALE, /* .STALE */ 179 SP_SUFFIXES, /* .SUFFIXES */ 180 SP_WAIT /* .WAIT */ 181 } ParseSpecial; 182 183 typedef List SearchPathList; 184 typedef ListNode SearchPathListNode; 185 186 /* result data */ 187 188 /* 189 * The main target to create. This is the first target defined in any of the 190 * makefiles. 191 */ 192 static GNode *mainNode; 193 194 /* eval state */ 195 196 /* 197 * During parsing, the targets from the left-hand side of the currently 198 * active dependency line, or NULL if the current line does not belong to a 199 * dependency line, for example because it is a variable assignment. 200 * 201 * See unit-tests/deptgt.mk, keyword "parse.c:targets". 202 */ 203 static GNodeList *targets; 204 205 #ifdef CLEANUP 206 /* 207 * All shell commands for all targets, in no particular order and possibly 208 * with duplicates. Kept in a separate list since the commands from .USE or 209 * .USEBEFORE nodes are shared with other GNodes, thereby giving up the 210 * easily understandable ownership over the allocated strings. 211 */ 212 static StringList targCmds = LST_INIT; 213 #endif 214 215 /* 216 * Predecessor node for handling .ORDER. Initialized to NULL when .ORDER 217 * seen, then set to each successive source on the line. 218 */ 219 static GNode *order_pred; 220 221 /* parser state */ 222 223 /* number of fatal errors */ 224 static int parseErrors = 0; 225 226 /* 227 * Variables for doing includes 228 */ 229 230 /* 231 * The include chain of makefiles. At index 0 is the top-level makefile from 232 * the command line, followed by the included files or .for loops, up to and 233 * including the current file. 234 * 235 * See PrintStackTrace for how to interpret the data. 236 */ 237 static Vector /* of IFile */ includes; 238 239 static IFile * 240 GetInclude(size_t i) 241 { 242 return Vector_Get(&includes, i); 243 } 244 245 /* The file that is currently being read. */ 246 static IFile * 247 CurFile(void) 248 { 249 return GetInclude(includes.len - 1); 250 } 251 252 /* include paths */ 253 SearchPath *parseIncPath; /* directories for "..." includes */ 254 SearchPath *sysIncPath; /* directories for <...> includes */ 255 SearchPath *defSysIncPath; /* default for sysIncPath */ 256 257 /* parser tables */ 258 259 /* 260 * The parseKeywords table is searched using binary search when deciding 261 * if a target or source is special. The 'spec' field is the ParseSpecial 262 * type of the keyword (SP_NOT if the keyword isn't special as a target) while 263 * the 'op' field is the operator to apply to the list of targets if the 264 * keyword is used as a source ("0" if the keyword isn't special as a source) 265 */ 266 static const struct { 267 const char name[17]; 268 ParseSpecial special; /* when used as a target */ 269 GNodeType targetAttr; /* when used as a source */ 270 } parseKeywords[] = { 271 { ".BEGIN", SP_BEGIN, OP_NONE }, 272 { ".DEFAULT", SP_DEFAULT, OP_NONE }, 273 { ".DELETE_ON_ERROR", SP_DELETE_ON_ERROR, OP_NONE }, 274 { ".END", SP_END, OP_NONE }, 275 { ".ERROR", SP_ERROR, OP_NONE }, 276 { ".EXEC", SP_ATTRIBUTE, OP_EXEC }, 277 { ".IGNORE", SP_IGNORE, OP_IGNORE }, 278 { ".INCLUDES", SP_INCLUDES, OP_NONE }, 279 { ".INTERRUPT", SP_INTERRUPT, OP_NONE }, 280 { ".INVISIBLE", SP_ATTRIBUTE, OP_INVISIBLE }, 281 { ".JOIN", SP_ATTRIBUTE, OP_JOIN }, 282 { ".LIBS", SP_LIBS, OP_NONE }, 283 { ".MADE", SP_ATTRIBUTE, OP_MADE }, 284 { ".MAIN", SP_MAIN, OP_NONE }, 285 { ".MAKE", SP_ATTRIBUTE, OP_MAKE }, 286 { ".MAKEFLAGS", SP_MFLAGS, OP_NONE }, 287 { ".META", SP_META, OP_META }, 288 { ".MFLAGS", SP_MFLAGS, OP_NONE }, 289 { ".NOMETA", SP_NOMETA, OP_NOMETA }, 290 { ".NOMETA_CMP", SP_NOMETA_CMP, OP_NOMETA_CMP }, 291 { ".NOPATH", SP_NOPATH, OP_NOPATH }, 292 { ".NOTMAIN", SP_ATTRIBUTE, OP_NOTMAIN }, 293 { ".NOTPARALLEL", SP_NOTPARALLEL, OP_NONE }, 294 { ".NO_PARALLEL", SP_NOTPARALLEL, OP_NONE }, 295 { ".NULL", SP_NULL, OP_NONE }, 296 { ".OBJDIR", SP_OBJDIR, OP_NONE }, 297 { ".OPTIONAL", SP_ATTRIBUTE, OP_OPTIONAL }, 298 { ".ORDER", SP_ORDER, OP_NONE }, 299 { ".PARALLEL", SP_PARALLEL, OP_NONE }, 300 { ".PATH", SP_PATH, OP_NONE }, 301 { ".PHONY", SP_PHONY, OP_PHONY }, 302 #ifdef POSIX 303 { ".POSIX", SP_POSIX, OP_NONE }, 304 #endif 305 { ".PRECIOUS", SP_PRECIOUS, OP_PRECIOUS }, 306 { ".RECURSIVE", SP_ATTRIBUTE, OP_MAKE }, 307 { ".SHELL", SP_SHELL, OP_NONE }, 308 { ".SILENT", SP_SILENT, OP_SILENT }, 309 { ".SINGLESHELL", SP_SINGLESHELL, OP_NONE }, 310 { ".STALE", SP_STALE, OP_NONE }, 311 { ".SUFFIXES", SP_SUFFIXES, OP_NONE }, 312 { ".USE", SP_ATTRIBUTE, OP_USE }, 313 { ".USEBEFORE", SP_ATTRIBUTE, OP_USEBEFORE }, 314 { ".WAIT", SP_WAIT, OP_NONE }, 315 }; 316 317 /* file loader */ 318 319 struct loadedfile { 320 char *buf; /* contents buffer */ 321 size_t len; /* length of contents */ 322 bool used; /* XXX: have we used the data yet */ 323 }; 324 325 /* XXX: What is the lifetime of the path? Who manages the memory? */ 326 static struct loadedfile * 327 loadedfile_create(char *buf, size_t buflen) 328 { 329 struct loadedfile *lf; 330 331 lf = bmake_malloc(sizeof *lf); 332 lf->buf = buf; 333 lf->len = buflen; 334 lf->used = false; 335 return lf; 336 } 337 338 static void 339 loadedfile_destroy(struct loadedfile *lf) 340 { 341 free(lf->buf); 342 free(lf); 343 } 344 345 /* 346 * readMore() operation for loadedfile, as needed by the weird and twisted 347 * logic below. Once that's cleaned up, we can get rid of lf->used. 348 */ 349 static char * 350 loadedfile_readMore(void *x, size_t *len) 351 { 352 struct loadedfile *lf = x; 353 354 if (lf->used) 355 return NULL; 356 357 lf->used = true; 358 *len = lf->len; 359 return lf->buf; 360 } 361 362 /* 363 * Try to get the size of a file. 364 */ 365 static bool 366 load_getsize(int fd, size_t *ret) 367 { 368 struct stat st; 369 370 if (fstat(fd, &st) < 0) 371 return false; 372 373 if (!S_ISREG(st.st_mode)) 374 return false; 375 376 /* 377 * st_size is an off_t, which is 64 bits signed; *ret is 378 * size_t, which might be 32 bits unsigned or 64 bits 379 * unsigned. Rather than being elaborate, just punt on 380 * files that are more than 1 GiB. We should never 381 * see a makefile that size in practice. 382 * 383 * While we're at it reject negative sizes too, just in case. 384 */ 385 if (st.st_size < 0 || st.st_size > 0x3fffffff) 386 return false; 387 388 *ret = (size_t)st.st_size; 389 return true; 390 } 391 392 /* 393 * Read in a file. 394 * 395 * Until the path search logic can be moved under here instead of 396 * being in the caller in another source file, we need to have the fd 397 * passed in already open. Bleh. 398 * 399 * If the path is NULL, use stdin. 400 */ 401 static struct loadedfile * 402 loadfile(const char *path, int fd) 403 { 404 ssize_t n; 405 Buffer buf; 406 size_t filesize; 407 408 409 if (path == NULL) { 410 assert(fd == -1); 411 fd = STDIN_FILENO; 412 } 413 414 if (load_getsize(fd, &filesize)) { 415 /* 416 * Avoid resizing the buffer later for no reason. 417 * 418 * At the same time leave space for adding a final '\n', 419 * just in case it is missing in the file. 420 */ 421 filesize++; 422 } else 423 filesize = 1024; 424 Buf_InitSize(&buf, filesize); 425 426 for (;;) { 427 assert(buf.len <= buf.cap); 428 if (buf.len == buf.cap) { 429 if (buf.cap > 0x1fffffff) { 430 errno = EFBIG; 431 Error("%s: file too large", path); 432 exit(2); /* Not 1 so -q can distinguish error */ 433 } 434 Buf_Expand(&buf); 435 } 436 assert(buf.len < buf.cap); 437 n = read(fd, buf.data + buf.len, buf.cap - buf.len); 438 if (n < 0) { 439 Error("%s: read error: %s", path, strerror(errno)); 440 exit(2); /* Not 1 so -q can distinguish error */ 441 } 442 if (n == 0) 443 break; 444 445 buf.len += (size_t)n; 446 } 447 assert(buf.len <= buf.cap); 448 449 if (!Buf_EndsWith(&buf, '\n')) 450 Buf_AddByte(&buf, '\n'); 451 452 if (path != NULL) 453 close(fd); 454 455 return loadedfile_create(buf.data, buf.len); 456 } 457 458 static void 459 PrintStackTrace(void) 460 { 461 const IFile *entries; 462 size_t i, n; 463 464 if (!(DEBUG(PARSE))) 465 return; 466 467 entries = GetInclude(0); 468 n = includes.len; 469 if (n == 0) 470 return; 471 n--; /* This entry is already in the diagnostic. */ 472 473 /* 474 * For the IFiles with fromForLoop, lineno seems to be sorted 475 * backwards. This is because lineno is the number of completely 476 * parsed lines, which for a .for loop is right after the 477 * corresponding .endfor. The intuitive line number comes from 478 * first_lineno instead, which points at the start of the .for loop. 479 * 480 * To make the stack trace intuitive, the entry below each chain of 481 * .for loop entries must be ignored completely since neither its 482 * lineno nor its first_lineno is useful. Instead, the topmost of 483 * each chain of .for loop entries needs to be printed twice, once 484 * with its first_lineno and once with its lineno. 485 */ 486 487 for (i = n; i-- > 0;) { 488 const IFile *entry = entries + i; 489 const char *fname = entry->name.str; 490 bool printLineno; 491 char dirbuf[MAXPATHLEN + 1]; 492 493 if (fname[0] != '/' && strcmp(fname, "(stdin)") != 0) 494 fname = realpath(fname, dirbuf); 495 496 printLineno = !entry->fromForLoop; 497 if (i + 1 < n && entries[i + 1].fromForLoop == printLineno) 498 printLineno = entry->fromForLoop; 499 500 if (printLineno) 501 debug_printf("\tin .include from %s:%d\n", 502 fname, entry->lineno); 503 if (entry->fromForLoop) 504 debug_printf("\tin .for loop from %s:%d\n", 505 fname, entry->first_lineno); 506 } 507 } 508 509 /* Check if the current character is escaped on the current line. */ 510 static bool 511 ParseIsEscaped(const char *line, const char *p) 512 { 513 bool active = false; 514 while (p > line && *--p == '\\') 515 active = !active; 516 return active; 517 } 518 519 /* 520 * Add the filename and lineno to the GNode so that we remember where it 521 * was first defined. 522 */ 523 static void 524 RememberLocation(GNode *gn) 525 { 526 IFile *curFile = CurFile(); 527 gn->fname = Str_Intern(curFile->name.str); 528 gn->lineno = curFile->lineno; 529 } 530 531 /* 532 * Look in the table of keywords for one matching the given string. 533 * Return the index of the keyword, or -1 if it isn't there. 534 */ 535 static int 536 ParseFindKeyword(const char *str) 537 { 538 int start = 0; 539 int end = sizeof parseKeywords / sizeof parseKeywords[0] - 1; 540 541 do { 542 int curr = start + (end - start) / 2; 543 int diff = strcmp(str, parseKeywords[curr].name); 544 545 if (diff == 0) 546 return curr; 547 if (diff < 0) 548 end = curr - 1; 549 else 550 start = curr + 1; 551 } while (start <= end); 552 553 return -1; 554 } 555 556 static void 557 PrintLocation(FILE *f, const char *fname, size_t lineno) 558 { 559 char dirbuf[MAXPATHLEN + 1]; 560 FStr dir, base; 561 562 if (*fname == '/' || strcmp(fname, "(stdin)") == 0) { 563 (void)fprintf(f, "\"%s\" line %u: ", fname, (unsigned)lineno); 564 return; 565 } 566 567 /* 568 * Find out which makefile is the culprit. We try ${.PARSEDIR} and 569 * apply realpath(3) if not absolute. 570 */ 571 572 dir = Var_Value(SCOPE_GLOBAL, ".PARSEDIR"); 573 if (dir.str == NULL) 574 dir.str = "."; 575 if (dir.str[0] != '/') 576 dir.str = realpath(dir.str, dirbuf); 577 578 base = Var_Value(SCOPE_GLOBAL, ".PARSEFILE"); 579 if (base.str == NULL) 580 base.str = str_basename(fname); 581 582 (void)fprintf(f, "\"%s/%s\" line %u: ", 583 dir.str, base.str, (unsigned)lineno); 584 585 FStr_Done(&base); 586 FStr_Done(&dir); 587 } 588 589 static void 590 ParseVErrorInternal(FILE *f, const char *fname, size_t lineno, 591 ParseErrorLevel type, const char *fmt, va_list ap) 592 { 593 static bool fatal_warning_error_printed = false; 594 595 (void)fprintf(f, "%s: ", progname); 596 597 if (fname != NULL) 598 PrintLocation(f, fname, lineno); 599 if (type == PARSE_WARNING) 600 (void)fprintf(f, "warning: "); 601 (void)vfprintf(f, fmt, ap); 602 (void)fprintf(f, "\n"); 603 (void)fflush(f); 604 605 if (type == PARSE_INFO) 606 goto print_stack_trace; 607 if (type == PARSE_WARNING && !opts.parseWarnFatal) 608 goto print_stack_trace; 609 parseErrors++; 610 if (type == PARSE_WARNING && !fatal_warning_error_printed) { 611 Error("parsing warnings being treated as errors"); 612 fatal_warning_error_printed = true; 613 } 614 615 print_stack_trace: 616 PrintStackTrace(); 617 } 618 619 static void 620 ParseErrorInternal(const char *fname, size_t lineno, 621 ParseErrorLevel type, const char *fmt, ...) 622 { 623 va_list ap; 624 625 (void)fflush(stdout); 626 va_start(ap, fmt); 627 ParseVErrorInternal(stderr, fname, lineno, type, fmt, ap); 628 va_end(ap); 629 630 if (opts.debug_file != stderr && opts.debug_file != stdout) { 631 va_start(ap, fmt); 632 ParseVErrorInternal(opts.debug_file, fname, lineno, type, 633 fmt, ap); 634 va_end(ap); 635 } 636 } 637 638 /* 639 * Print a parse error message, including location information. 640 * 641 * If the level is PARSE_FATAL, continue parsing until the end of the 642 * current top-level makefile, then exit (see Parse_File). 643 * 644 * Fmt is given without a trailing newline. 645 */ 646 void 647 Parse_Error(ParseErrorLevel type, const char *fmt, ...) 648 { 649 va_list ap; 650 const char *fname; 651 size_t lineno; 652 653 if (includes.len == 0) { 654 fname = NULL; 655 lineno = 0; 656 } else { 657 IFile *curFile = CurFile(); 658 fname = curFile->name.str; 659 lineno = (size_t)curFile->lineno; 660 } 661 662 va_start(ap, fmt); 663 (void)fflush(stdout); 664 ParseVErrorInternal(stderr, fname, lineno, type, fmt, ap); 665 va_end(ap); 666 667 if (opts.debug_file != stderr && opts.debug_file != stdout) { 668 va_start(ap, fmt); 669 ParseVErrorInternal(opts.debug_file, fname, lineno, type, 670 fmt, ap); 671 va_end(ap); 672 } 673 } 674 675 676 /* 677 * Parse and handle an .info, .warning or .error directive. 678 * For an .error directive, immediately exit. 679 */ 680 static void 681 ParseMessage(ParseErrorLevel level, const char *levelName, const char *umsg) 682 { 683 char *xmsg; 684 685 if (umsg[0] == '\0') { 686 Parse_Error(PARSE_FATAL, "Missing argument for \".%s\"", 687 levelName); 688 return; 689 } 690 691 (void)Var_Subst(umsg, SCOPE_CMDLINE, VARE_WANTRES, &xmsg); 692 /* TODO: handle errors */ 693 694 Parse_Error(level, "%s", xmsg); 695 free(xmsg); 696 697 if (level == PARSE_FATAL) { 698 PrintOnError(NULL, NULL); 699 exit(1); 700 } 701 } 702 703 /* 704 * Add the child to the parent's children. 705 * 706 * Additionally, add the parent to the child's parents, but only if the 707 * target is not special. An example for such a special target is .END, 708 * which does not need to be informed once the child target has been made. 709 */ 710 static void 711 LinkSource(GNode *pgn, GNode *cgn, bool isSpecial) 712 { 713 if ((pgn->type & OP_DOUBLEDEP) && !Lst_IsEmpty(&pgn->cohorts)) 714 pgn = pgn->cohorts.last->datum; 715 716 Lst_Append(&pgn->children, cgn); 717 pgn->unmade++; 718 719 /* Special targets like .END don't need any children. */ 720 if (!isSpecial) 721 Lst_Append(&cgn->parents, pgn); 722 723 if (DEBUG(PARSE)) { 724 debug_printf("# LinkSource: added child %s - %s\n", 725 pgn->name, cgn->name); 726 Targ_PrintNode(pgn, 0); 727 Targ_PrintNode(cgn, 0); 728 } 729 } 730 731 /* Add the node to each target from the current dependency group. */ 732 static void 733 LinkToTargets(GNode *gn, bool isSpecial) 734 { 735 GNodeListNode *ln; 736 737 for (ln = targets->first; ln != NULL; ln = ln->next) 738 LinkSource(ln->datum, gn, isSpecial); 739 } 740 741 static bool 742 TryApplyDependencyOperator(GNode *gn, GNodeType op) 743 { 744 /* 745 * If the node occurred on the left-hand side of a dependency and the 746 * operator also defines a dependency, they must match. 747 */ 748 if ((op & OP_OPMASK) && (gn->type & OP_OPMASK) && 749 ((op & OP_OPMASK) != (gn->type & OP_OPMASK))) { 750 Parse_Error(PARSE_FATAL, "Inconsistent operator for %s", 751 gn->name); 752 return false; 753 } 754 755 if (op == OP_DOUBLEDEP && (gn->type & OP_OPMASK) == OP_DOUBLEDEP) { 756 /* 757 * If the node was of the left-hand side of a '::' operator, 758 * we need to create a new instance of it for the children 759 * and commands on this dependency line since each of these 760 * dependency groups has its own attributes and commands, 761 * separate from the others. 762 * 763 * The new instance is placed on the 'cohorts' list of the 764 * initial one (note the initial one is not on its own 765 * cohorts list) and the new instance is linked to all 766 * parents of the initial instance. 767 */ 768 GNode *cohort; 769 770 /* 771 * Propagate copied bits to the initial node. They'll be 772 * propagated back to the rest of the cohorts later. 773 */ 774 gn->type |= op & ~OP_OPMASK; 775 776 cohort = Targ_NewInternalNode(gn->name); 777 if (doing_depend) 778 RememberLocation(cohort); 779 /* 780 * Make the cohort invisible as well to avoid duplicating it 781 * into other variables. True, parents of this target won't 782 * tend to do anything with their local variables, but better 783 * safe than sorry. 784 * 785 * (I think this is pointless now, since the relevant list 786 * traversals will no longer see this node anyway. -mycroft) 787 */ 788 cohort->type = op | OP_INVISIBLE; 789 Lst_Append(&gn->cohorts, cohort); 790 cohort->centurion = gn; 791 gn->unmade_cohorts++; 792 snprintf(cohort->cohort_num, sizeof cohort->cohort_num, "#%d", 793 (unsigned int)gn->unmade_cohorts % 1000000); 794 } else { 795 /* 796 * We don't want to nuke any previous flags (whatever they 797 * were) so we just OR the new operator into the old. 798 */ 799 gn->type |= op; 800 } 801 802 return true; 803 } 804 805 static void 806 ApplyDependencyOperator(GNodeType op) 807 { 808 GNodeListNode *ln; 809 810 for (ln = targets->first; ln != NULL; ln = ln->next) 811 if (!TryApplyDependencyOperator(ln->datum, op)) 812 break; 813 } 814 815 /* 816 * We add a .WAIT node in the dependency list. After any dynamic dependencies 817 * (and filename globbing) have happened, it is given a dependency on each 818 * previous child, back until the previous .WAIT node. The next child won't 819 * be scheduled until the .WAIT node is built. 820 * 821 * We give each .WAIT node a unique name (mainly for diagnostics). 822 */ 823 static void 824 ApplyDependencySourceWait(bool isSpecial) 825 { 826 static int wait_number = 0; 827 char wait_src[16]; 828 GNode *gn; 829 830 snprintf(wait_src, sizeof wait_src, ".WAIT_%u", ++wait_number); 831 gn = Targ_NewInternalNode(wait_src); 832 if (doing_depend) 833 RememberLocation(gn); 834 gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN; 835 LinkToTargets(gn, isSpecial); 836 837 } 838 839 static bool 840 ApplyDependencySourceKeyword(const char *src, ParseSpecial special) 841 { 842 int keywd; 843 GNodeType targetAttr; 844 845 if (*src != '.' || !ch_isupper(src[1])) 846 return false; 847 848 keywd = ParseFindKeyword(src); 849 if (keywd == -1) 850 return false; 851 852 targetAttr = parseKeywords[keywd].targetAttr; 853 if (targetAttr != OP_NONE) { 854 ApplyDependencyOperator(targetAttr); 855 return true; 856 } 857 if (parseKeywords[keywd].special == SP_WAIT) { 858 ApplyDependencySourceWait(special != SP_NOT); 859 return true; 860 } 861 return false; 862 } 863 864 static void 865 ApplyDependencySourceMain(const char *src) 866 { 867 /* 868 * In a line like ".MAIN: source1 source2", add all sources to the 869 * list of things to create, but only if the user didn't specify a 870 * target on the command line and .MAIN occurs for the first time. 871 * 872 * See ParseDependencyTargetSpecial, branch SP_MAIN. 873 * See unit-tests/cond-func-make-main.mk. 874 */ 875 Lst_Append(&opts.create, bmake_strdup(src)); 876 /* 877 * Add the name to the .TARGETS variable as well, so the user can 878 * employ that, if desired. 879 */ 880 Global_Append(".TARGETS", src); 881 } 882 883 static void 884 ApplyDependencySourceOrder(const char *src) 885 { 886 GNode *gn; 887 /* 888 * Create proper predecessor/successor links between the previous 889 * source and the current one. 890 */ 891 gn = Targ_GetNode(src); 892 if (doing_depend) 893 RememberLocation(gn); 894 if (order_pred != NULL) { 895 Lst_Append(&order_pred->order_succ, gn); 896 Lst_Append(&gn->order_pred, order_pred); 897 if (DEBUG(PARSE)) { 898 debug_printf( 899 "# .ORDER forces '%s' to be made before '%s'\n", 900 order_pred->name, gn->name); 901 Targ_PrintNode(order_pred, 0); 902 Targ_PrintNode(gn, 0); 903 } 904 } 905 /* 906 * The current source now becomes the predecessor for the next one. 907 */ 908 order_pred = gn; 909 } 910 911 static void 912 ApplyDependencySourceOther(const char *src, GNodeType targetAttr, 913 ParseSpecial special) 914 { 915 GNode *gn; 916 917 /* 918 * The source is not an attribute, so find/create a node for it. 919 * After that, apply any operator to it from a special target or 920 * link it to its parents, as appropriate. 921 * 922 * In the case of a source that was the object of a '::' operator, 923 * the attribute is applied to all of its instances (as kept in 924 * the 'cohorts' list of the node) or all the cohorts are linked 925 * to all the targets. 926 */ 927 928 /* Find/create the 'src' node and attach to all targets */ 929 gn = Targ_GetNode(src); 930 if (doing_depend) 931 RememberLocation(gn); 932 if (targetAttr != OP_NONE) 933 gn->type |= targetAttr; 934 else 935 LinkToTargets(gn, special != SP_NOT); 936 } 937 938 /* 939 * Given the name of a source in a dependency line, figure out if it is an 940 * attribute (such as .SILENT) and if so, apply it to all targets. Otherwise 941 * decide if there is some attribute which should be applied *to* the source 942 * because of some special target (such as .PHONY) and apply it if so. 943 * Otherwise, make the source a child of the targets. 944 */ 945 static void 946 ApplyDependencySource(GNodeType targetAttr, const char *src, 947 ParseSpecial special) 948 { 949 if (ApplyDependencySourceKeyword(src, special)) 950 return; 951 952 if (special == SP_MAIN) 953 ApplyDependencySourceMain(src); 954 else if (special == SP_ORDER) 955 ApplyDependencySourceOrder(src); 956 else 957 ApplyDependencySourceOther(src, targetAttr, special); 958 } 959 960 /* 961 * If we have yet to decide on a main target to make, in the absence of any 962 * user input, we want the first target on the first dependency line that is 963 * actually a real target (i.e. isn't a .USE or .EXEC rule) to be made. 964 */ 965 static void 966 FindMainTarget(void) 967 { 968 GNodeListNode *ln; 969 970 if (mainNode != NULL) 971 return; 972 973 for (ln = targets->first; ln != NULL; ln = ln->next) { 974 GNode *gn = ln->datum; 975 if (GNode_IsMainCandidate(gn)) { 976 DEBUG1(MAKE, "Setting main node to \"%s\"\n", gn->name); 977 mainNode = gn; 978 Targ_SetMain(gn); 979 return; 980 } 981 } 982 } 983 984 /* 985 * We got to the end of the line while we were still looking at targets. 986 * 987 * Ending a dependency line without an operator is a Bozo no-no. As a 988 * heuristic, this is also often triggered by undetected conflicts from 989 * cvs/rcs merges. 990 */ 991 static void 992 ParseErrorNoDependency(const char *lstart) 993 { 994 if ((strncmp(lstart, "<<<<<<", 6) == 0) || 995 (strncmp(lstart, "======", 6) == 0) || 996 (strncmp(lstart, ">>>>>>", 6) == 0)) 997 Parse_Error(PARSE_FATAL, 998 "Makefile appears to contain unresolved CVS/RCS/??? merge conflicts"); 999 else if (lstart[0] == '.') { 1000 const char *dirstart = lstart + 1; 1001 const char *dirend; 1002 cpp_skip_whitespace(&dirstart); 1003 dirend = dirstart; 1004 while (ch_isalnum(*dirend) || *dirend == '-') 1005 dirend++; 1006 Parse_Error(PARSE_FATAL, "Unknown directive \"%.*s\"", 1007 (int)(dirend - dirstart), dirstart); 1008 } else 1009 Parse_Error(PARSE_FATAL, "Invalid line type"); 1010 } 1011 1012 static void 1013 ParseDependencyTargetWord(const char **pp, const char *lstart) 1014 { 1015 const char *cp = *pp; 1016 1017 while (*cp != '\0') { 1018 if ((ch_isspace(*cp) || *cp == '!' || *cp == ':' || 1019 *cp == '(') && 1020 !ParseIsEscaped(lstart, cp)) 1021 break; 1022 1023 if (*cp == '$') { 1024 /* 1025 * Must be a dynamic source (would have been expanded 1026 * otherwise), so call the Var module to parse the 1027 * puppy so we can safely advance beyond it. 1028 * 1029 * There should be no errors in this, as they would 1030 * have been discovered in the initial Var_Subst and 1031 * we wouldn't be here. 1032 */ 1033 const char *nested_p = cp; 1034 FStr nested_val; 1035 1036 (void)Var_Parse(&nested_p, SCOPE_CMDLINE, 1037 VARE_PARSE_ONLY, &nested_val); 1038 /* TODO: handle errors */ 1039 FStr_Done(&nested_val); 1040 cp += nested_p - cp; 1041 } else 1042 cp++; 1043 } 1044 1045 *pp = cp; 1046 } 1047 1048 /* 1049 * Handle special targets like .PATH, .DEFAULT, .BEGIN, .ORDER. 1050 * 1051 * See the tests deptgt-*.mk. 1052 */ 1053 static void 1054 ParseDependencyTargetSpecial(ParseSpecial *inout_special, 1055 const char *targetName, 1056 SearchPathList **inout_paths) 1057 { 1058 switch (*inout_special) { 1059 case SP_PATH: 1060 if (*inout_paths == NULL) 1061 *inout_paths = Lst_New(); 1062 Lst_Append(*inout_paths, &dirSearchPath); 1063 break; 1064 case SP_MAIN: 1065 /* 1066 * Allow targets from the command line to override the 1067 * .MAIN node. 1068 */ 1069 if (!Lst_IsEmpty(&opts.create)) 1070 *inout_special = SP_NOT; 1071 break; 1072 case SP_BEGIN: 1073 case SP_END: 1074 case SP_STALE: 1075 case SP_ERROR: 1076 case SP_INTERRUPT: { 1077 GNode *gn = Targ_GetNode(targetName); 1078 if (doing_depend) 1079 RememberLocation(gn); 1080 gn->type |= OP_NOTMAIN | OP_SPECIAL; 1081 Lst_Append(targets, gn); 1082 break; 1083 } 1084 case SP_DEFAULT: { 1085 /* 1086 * Need to create a node to hang commands on, but we don't 1087 * want it in the graph, nor do we want it to be the Main 1088 * Target. We claim the node is a transformation rule to make 1089 * life easier later, when we'll use Make_HandleUse to 1090 * actually apply the .DEFAULT commands. 1091 */ 1092 GNode *gn = GNode_New(".DEFAULT"); 1093 gn->type |= OP_NOTMAIN | OP_TRANSFORM; 1094 Lst_Append(targets, gn); 1095 defaultNode = gn; 1096 break; 1097 } 1098 case SP_DELETE_ON_ERROR: 1099 deleteOnError = true; 1100 break; 1101 case SP_NOTPARALLEL: 1102 opts.maxJobs = 1; 1103 break; 1104 case SP_SINGLESHELL: 1105 opts.compatMake = true; 1106 break; 1107 case SP_ORDER: 1108 order_pred = NULL; 1109 break; 1110 default: 1111 break; 1112 } 1113 } 1114 1115 /* 1116 * .PATH<suffix> has to be handled specially. 1117 * Call on the suffix module to give us a path to modify. 1118 */ 1119 static bool 1120 ParseDependencyTargetPath(const char *suffixName, 1121 SearchPathList **inout_paths) 1122 { 1123 SearchPath *path; 1124 1125 path = Suff_GetPath(suffixName); 1126 if (path == NULL) { 1127 Parse_Error(PARSE_FATAL, 1128 "Suffix '%s' not defined (yet)", suffixName); 1129 return false; 1130 } 1131 1132 if (*inout_paths == NULL) 1133 *inout_paths = Lst_New(); 1134 Lst_Append(*inout_paths, path); 1135 1136 return true; 1137 } 1138 1139 /* 1140 * See if it's a special target and if so set inout_special to match it. 1141 */ 1142 static bool 1143 ParseDependencyTarget(const char *targetName, 1144 ParseSpecial *inout_special, 1145 GNodeType *inout_targetAttr, 1146 SearchPathList **inout_paths) 1147 { 1148 int keywd; 1149 1150 if (!(targetName[0] == '.' && ch_isupper(targetName[1]))) 1151 return true; 1152 1153 /* 1154 * See if the target is a special target that must have it 1155 * or its sources handled specially. 1156 */ 1157 keywd = ParseFindKeyword(targetName); 1158 if (keywd != -1) { 1159 if (*inout_special == SP_PATH && 1160 parseKeywords[keywd].special != SP_PATH) { 1161 Parse_Error(PARSE_FATAL, "Mismatched special targets"); 1162 return false; 1163 } 1164 1165 *inout_special = parseKeywords[keywd].special; 1166 *inout_targetAttr = parseKeywords[keywd].targetAttr; 1167 1168 ParseDependencyTargetSpecial(inout_special, targetName, 1169 inout_paths); 1170 1171 } else if (strncmp(targetName, ".PATH", 5) == 0) { 1172 *inout_special = SP_PATH; 1173 if (!ParseDependencyTargetPath(targetName + 5, inout_paths)) 1174 return false; 1175 } 1176 return true; 1177 } 1178 1179 static void 1180 ParseDependencyTargetMundane(char *targetName) 1181 { 1182 StringList targetNames = LST_INIT; 1183 1184 if (Dir_HasWildcards(targetName)) { 1185 SearchPath *emptyPath = SearchPath_New(); 1186 SearchPath_Expand(emptyPath, targetName, &targetNames); 1187 SearchPath_Free(emptyPath); 1188 } else 1189 Lst_Append(&targetNames, targetName); 1190 1191 while (!Lst_IsEmpty(&targetNames)) { 1192 char *targName = Lst_Dequeue(&targetNames); 1193 GNode *gn = Suff_IsTransform(targName) 1194 ? Suff_AddTransform(targName) 1195 : Targ_GetNode(targName); 1196 if (doing_depend) 1197 RememberLocation(gn); 1198 1199 Lst_Append(targets, gn); 1200 } 1201 } 1202 1203 static void 1204 ParseDependencyTargetExtraWarn(char **pp, const char *lstart) 1205 { 1206 bool warning = false; 1207 char *cp = *pp; 1208 1209 while (*cp != '\0') { 1210 if (!ParseIsEscaped(lstart, cp) && (*cp == '!' || *cp == ':')) 1211 break; 1212 if (ParseIsEscaped(lstart, cp) || (*cp != ' ' && *cp != '\t')) 1213 warning = true; 1214 cp++; 1215 } 1216 if (warning) 1217 Parse_Error(PARSE_WARNING, "Extra target ignored"); 1218 1219 *pp = cp; 1220 } 1221 1222 static void 1223 ParseDependencyCheckSpecial(ParseSpecial special) 1224 { 1225 switch (special) { 1226 case SP_DEFAULT: 1227 case SP_STALE: 1228 case SP_BEGIN: 1229 case SP_END: 1230 case SP_ERROR: 1231 case SP_INTERRUPT: 1232 /* 1233 * These create nodes on which to hang commands, so targets 1234 * shouldn't be empty. 1235 */ 1236 case SP_NOT: 1237 /* 1238 * Nothing special here -- targets can be empty if it wants. 1239 */ 1240 break; 1241 default: 1242 Parse_Error(PARSE_WARNING, 1243 "Special and mundane targets don't mix. " 1244 "Mundane ones ignored"); 1245 break; 1246 } 1247 } 1248 1249 /* 1250 * In a dependency line like 'targets: sources' or 'targets! sources', parse 1251 * the operator ':', '::' or '!' from between the targets and the sources. 1252 */ 1253 static GNodeType 1254 ParseDependencyOp(char **pp) 1255 { 1256 if (**pp == '!') 1257 return (*pp)++, OP_FORCE; 1258 if ((*pp)[1] == ':') 1259 return (*pp) += 2, OP_DOUBLEDEP; 1260 else 1261 return (*pp)++, OP_DEPENDS; 1262 } 1263 1264 static void 1265 ClearPaths(SearchPathList *paths) 1266 { 1267 if (paths != NULL) { 1268 SearchPathListNode *ln; 1269 for (ln = paths->first; ln != NULL; ln = ln->next) 1270 SearchPath_Clear(ln->datum); 1271 } 1272 1273 Dir_SetPATH(); 1274 } 1275 1276 /* 1277 * Several special targets take different actions if present with no 1278 * sources: 1279 * a .SUFFIXES line with no sources clears out all old suffixes 1280 * a .PRECIOUS line makes all targets precious 1281 * a .IGNORE line ignores errors for all targets 1282 * a .SILENT line creates silence when making all targets 1283 * a .PATH removes all directories from the search path(s). 1284 */ 1285 static void 1286 ParseDependencySourcesEmpty(ParseSpecial special, SearchPathList *paths) 1287 { 1288 switch (special) { 1289 case SP_SUFFIXES: 1290 Suff_ClearSuffixes(); 1291 break; 1292 case SP_PRECIOUS: 1293 allPrecious = true; 1294 break; 1295 case SP_IGNORE: 1296 opts.ignoreErrors = true; 1297 break; 1298 case SP_SILENT: 1299 opts.silent = true; 1300 break; 1301 case SP_PATH: 1302 ClearPaths(paths); 1303 break; 1304 #ifdef POSIX 1305 case SP_POSIX: 1306 Global_Set("%POSIX", "1003.2"); 1307 break; 1308 #endif 1309 default: 1310 break; 1311 } 1312 } 1313 1314 static void 1315 AddToPaths(const char *dir, SearchPathList *paths) 1316 { 1317 if (paths != NULL) { 1318 SearchPathListNode *ln; 1319 for (ln = paths->first; ln != NULL; ln = ln->next) 1320 (void)SearchPath_Add(ln->datum, dir); 1321 } 1322 } 1323 1324 /* 1325 * If the target was one that doesn't take files as its sources 1326 * but takes something like suffixes, we take each 1327 * space-separated word on the line as a something and deal 1328 * with it accordingly. 1329 * 1330 * If the target was .SUFFIXES, we take each source as a 1331 * suffix and add it to the list of suffixes maintained by the 1332 * Suff module. 1333 * 1334 * If the target was a .PATH, we add the source as a directory 1335 * to search on the search path. 1336 * 1337 * If it was .INCLUDES, the source is taken to be the suffix of 1338 * files which will be #included and whose search path should 1339 * be present in the .INCLUDES variable. 1340 * 1341 * If it was .LIBS, the source is taken to be the suffix of 1342 * files which are considered libraries and whose search path 1343 * should be present in the .LIBS variable. 1344 * 1345 * If it was .NULL, the source is the suffix to use when a file 1346 * has no valid suffix. 1347 * 1348 * If it was .OBJDIR, the source is a new definition for .OBJDIR, 1349 * and will cause make to do a new chdir to that path. 1350 */ 1351 static void 1352 ParseDependencySourceSpecial(ParseSpecial special, char *word, 1353 SearchPathList *paths) 1354 { 1355 switch (special) { 1356 case SP_SUFFIXES: 1357 Suff_AddSuffix(word, &mainNode); 1358 break; 1359 case SP_PATH: 1360 AddToPaths(word, paths); 1361 break; 1362 case SP_INCLUDES: 1363 Suff_AddInclude(word); 1364 break; 1365 case SP_LIBS: 1366 Suff_AddLib(word); 1367 break; 1368 case SP_NULL: 1369 Suff_SetNull(word); 1370 break; 1371 case SP_OBJDIR: 1372 Main_SetObjdir(false, "%s", word); 1373 break; 1374 default: 1375 break; 1376 } 1377 } 1378 1379 static bool 1380 ParseDependencyTargets(char **inout_cp, 1381 char **inout_line, 1382 const char *lstart, 1383 ParseSpecial *inout_special, 1384 GNodeType *inout_targetAttr, 1385 SearchPathList **inout_paths) 1386 { 1387 char *cp; 1388 char *tgt = *inout_line; 1389 char savec; 1390 const char *p; 1391 1392 for (;;) { 1393 /* 1394 * Here LINE points to the beginning of the next word, and 1395 * LSTART points to the actual beginning of the line. 1396 */ 1397 1398 /* Find the end of the next word. */ 1399 cp = tgt; 1400 p = cp; 1401 ParseDependencyTargetWord(&p, lstart); 1402 cp += p - cp; 1403 1404 /* 1405 * If the word is followed by a left parenthesis, it's the 1406 * name of an object file inside an archive (ar file). 1407 */ 1408 if (!ParseIsEscaped(lstart, cp) && *cp == '(') { 1409 /* 1410 * Archives must be handled specially to make sure the 1411 * OP_ARCHV flag is set in their 'type' field, for one 1412 * thing, and because things like "archive(file1.o 1413 * file2.o file3.o)" are permissible. 1414 * 1415 * Arch_ParseArchive will set 'line' to be the first 1416 * non-blank after the archive-spec. It creates/finds 1417 * nodes for the members and places them on the given 1418 * list, returning true if all went well and false if 1419 * there was an error in the specification. On error, 1420 * line should remain untouched. 1421 */ 1422 if (!Arch_ParseArchive(&tgt, targets, SCOPE_CMDLINE)) { 1423 Parse_Error(PARSE_FATAL, 1424 "Error in archive specification: \"%s\"", 1425 tgt); 1426 return false; 1427 } 1428 1429 cp = tgt; 1430 continue; 1431 } 1432 1433 if (*cp == '\0') { 1434 ParseErrorNoDependency(lstart); 1435 return false; 1436 } 1437 1438 /* Insert a null terminator. */ 1439 savec = *cp; 1440 *cp = '\0'; 1441 1442 if (!ParseDependencyTarget(tgt, inout_special, 1443 inout_targetAttr, inout_paths)) 1444 return false; 1445 1446 /* 1447 * Have word in line. Get or create its node and stick it at 1448 * the end of the targets list 1449 */ 1450 if (*inout_special == SP_NOT && *tgt != '\0') 1451 ParseDependencyTargetMundane(tgt); 1452 else if (*inout_special == SP_PATH && *tgt != '.' && 1453 *tgt != '\0') 1454 Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", 1455 tgt); 1456 1457 /* Don't need the inserted null terminator any more. */ 1458 *cp = savec; 1459 1460 /* 1461 * If it is a special type and not .PATH, it's the only target 1462 * we allow on this line. 1463 */ 1464 if (*inout_special != SP_NOT && *inout_special != SP_PATH) 1465 ParseDependencyTargetExtraWarn(&cp, lstart); 1466 else 1467 pp_skip_whitespace(&cp); 1468 1469 tgt = cp; 1470 if (*tgt == '\0') 1471 break; 1472 if ((*tgt == '!' || *tgt == ':') && 1473 !ParseIsEscaped(lstart, tgt)) 1474 break; 1475 } 1476 1477 *inout_cp = cp; 1478 *inout_line = tgt; 1479 return true; 1480 } 1481 1482 static void 1483 ParseDependencySourcesSpecial(char *start, char *end, 1484 ParseSpecial special, SearchPathList *paths) 1485 { 1486 char savec; 1487 1488 while (*start != '\0') { 1489 while (*end != '\0' && !ch_isspace(*end)) 1490 end++; 1491 savec = *end; 1492 *end = '\0'; 1493 ParseDependencySourceSpecial(special, start, paths); 1494 *end = savec; 1495 if (savec != '\0') 1496 end++; 1497 pp_skip_whitespace(&end); 1498 start = end; 1499 } 1500 } 1501 1502 static bool 1503 ParseDependencySourcesMundane(char *start, char *end, 1504 ParseSpecial special, GNodeType targetAttr) 1505 { 1506 while (*start != '\0') { 1507 /* 1508 * The targets take real sources, so we must beware of archive 1509 * specifications (i.e. things with left parentheses in them) 1510 * and handle them accordingly. 1511 */ 1512 for (; *end != '\0' && !ch_isspace(*end); end++) { 1513 if (*end == '(' && end > start && end[-1] != '$') { 1514 /* 1515 * Only stop for a left parenthesis if it 1516 * isn't at the start of a word (that'll be 1517 * for variable changes later) and isn't 1518 * preceded by a dollar sign (a dynamic 1519 * source). 1520 */ 1521 break; 1522 } 1523 } 1524 1525 if (*end == '(') { 1526 GNodeList sources = LST_INIT; 1527 if (!Arch_ParseArchive(&start, &sources, 1528 SCOPE_CMDLINE)) { 1529 Parse_Error(PARSE_FATAL, 1530 "Error in source archive spec \"%s\"", 1531 start); 1532 return false; 1533 } 1534 1535 while (!Lst_IsEmpty(&sources)) { 1536 GNode *gn = Lst_Dequeue(&sources); 1537 ApplyDependencySource(targetAttr, gn->name, 1538 special); 1539 } 1540 Lst_Done(&sources); 1541 end = start; 1542 } else { 1543 if (*end != '\0') { 1544 *end = '\0'; 1545 end++; 1546 } 1547 1548 ApplyDependencySource(targetAttr, start, special); 1549 } 1550 pp_skip_whitespace(&end); 1551 start = end; 1552 } 1553 return true; 1554 } 1555 1556 /* 1557 * In a dependency line like 'targets: sources', parse the sources. 1558 * 1559 * See the tests depsrc-*.mk. 1560 */ 1561 static void 1562 ParseDependencySources(char *line, char *cp, GNodeType targetAttr, 1563 ParseSpecial special, SearchPathList **inout_paths) 1564 { 1565 if (line[0] == '\0') { 1566 ParseDependencySourcesEmpty(special, *inout_paths); 1567 } else if (special == SP_MFLAGS) { 1568 Main_ParseArgLine(line); 1569 /* 1570 * Set the initial character to a null-character so the loop 1571 * to get sources won't get anything. 1572 */ 1573 *line = '\0'; 1574 } else if (special == SP_SHELL) { 1575 if (!Job_ParseShell(line)) { 1576 Parse_Error(PARSE_FATAL, 1577 "improper shell specification"); 1578 return; 1579 } 1580 *line = '\0'; 1581 } else if (special == SP_NOTPARALLEL || special == SP_SINGLESHELL || 1582 special == SP_DELETE_ON_ERROR) { 1583 *line = '\0'; 1584 } 1585 1586 /* Now go for the sources. */ 1587 if (special == SP_SUFFIXES || special == SP_PATH || 1588 special == SP_INCLUDES || special == SP_LIBS || 1589 special == SP_NULL || special == SP_OBJDIR) { 1590 ParseDependencySourcesSpecial(line, cp, special, 1591 *inout_paths); 1592 if (*inout_paths != NULL) { 1593 Lst_Free(*inout_paths); 1594 *inout_paths = NULL; 1595 } 1596 if (special == SP_PATH) 1597 Dir_SetPATH(); 1598 } else { 1599 assert(*inout_paths == NULL); 1600 if (!ParseDependencySourcesMundane(line, cp, special, 1601 targetAttr)) 1602 return; 1603 } 1604 1605 FindMainTarget(); 1606 } 1607 1608 /* 1609 * Parse a dependency line consisting of targets, followed by a dependency 1610 * operator, optionally followed by sources. 1611 * 1612 * The nodes of the sources are linked as children to the nodes of the 1613 * targets. Nodes are created as necessary. 1614 * 1615 * The operator is applied to each node in the global 'targets' list, 1616 * which is where the nodes found for the targets are kept. 1617 * 1618 * The sources are parsed in much the same way as the targets, except 1619 * that they are expanded using the wildcarding scheme of the C-Shell, 1620 * and a target is created for each expanded word. Each of the resulting 1621 * nodes is then linked to each of the targets as one of its children. 1622 * 1623 * Certain targets and sources such as .PHONY or .PRECIOUS are handled 1624 * specially, see ParseSpecial. 1625 * 1626 * Transformation rules such as '.c.o' are also handled here, see 1627 * Suff_AddTransform. 1628 * 1629 * Upon return, the value of the line is unspecified. 1630 */ 1631 static void 1632 ParseDependency(char *line) 1633 { 1634 char *cp; /* our current position */ 1635 GNodeType op; /* the dependency operator on the line */ 1636 SearchPathList *paths; /* search paths to alter when parsing a list 1637 * of .PATH targets */ 1638 GNodeType targetAttr; /* from special sources */ 1639 const char *lstart = line; 1640 1641 /* 1642 * In special targets, the children are linked as children of the 1643 * parent but not vice versa. 1644 */ 1645 ParseSpecial special = SP_NOT; 1646 1647 DEBUG1(PARSE, "ParseDependency(%s)\n", line); 1648 targetAttr = OP_NONE; 1649 1650 paths = NULL; 1651 1652 /* XXX: don't use 'line' as an iterator variable */ 1653 if (!ParseDependencyTargets(&cp, &line, lstart, &special, 1654 &targetAttr, &paths)) 1655 goto out; 1656 1657 if (!Lst_IsEmpty(targets)) 1658 ParseDependencyCheckSpecial(special); 1659 1660 op = ParseDependencyOp(&cp); 1661 ApplyDependencyOperator(op); 1662 1663 pp_skip_whitespace(&cp); 1664 line = cp; /* XXX: 'line' is an inappropriate name */ 1665 1666 ParseDependencySources(line, cp, targetAttr, special, &paths); 1667 1668 out: 1669 if (paths != NULL) 1670 Lst_Free(paths); 1671 } 1672 1673 typedef struct VarAssignParsed { 1674 const char *nameStart; /* unexpanded */ 1675 const char *nameEnd; /* before operator adjustment */ 1676 const char *eq; /* the '=' of the assignment operator */ 1677 } VarAssignParsed; 1678 1679 /* 1680 * Determine the assignment operator and adjust the end of the variable 1681 * name accordingly. 1682 */ 1683 static void 1684 AdjustVarassignOp(const VarAssignParsed *pvar, const char *value, 1685 VarAssign *out_var) 1686 { 1687 const char *op = pvar->eq; 1688 const char *const name = pvar->nameStart; 1689 VarAssignOp type; 1690 1691 if (op > name && op[-1] == '+') { 1692 op--; 1693 type = VAR_APPEND; 1694 1695 } else if (op > name && op[-1] == '?') { 1696 op--; 1697 type = VAR_DEFAULT; 1698 1699 } else if (op > name && op[-1] == ':') { 1700 op--; 1701 type = VAR_SUBST; 1702 1703 } else if (op > name && op[-1] == '!') { 1704 op--; 1705 type = VAR_SHELL; 1706 1707 } else { 1708 type = VAR_NORMAL; 1709 #ifdef SUNSHCMD 1710 while (op > name && ch_isspace(op[-1])) 1711 op--; 1712 1713 if (op >= name + 3 && memcmp(op - 3, ":sh", 3) == 0) { 1714 op -= 3; 1715 type = VAR_SHELL; 1716 } 1717 #endif 1718 } 1719 1720 { 1721 const char *nameEnd = pvar->nameEnd < op ? pvar->nameEnd : op; 1722 out_var->varname = bmake_strsedup(pvar->nameStart, nameEnd); 1723 out_var->op = type; 1724 out_var->value = value; 1725 } 1726 } 1727 1728 /* 1729 * Parse a variable assignment, consisting of a single-word variable name, 1730 * optional whitespace, an assignment operator, optional whitespace and the 1731 * variable value. 1732 * 1733 * Note: There is a lexical ambiguity with assignment modifier characters 1734 * in variable names. This routine interprets the character before the = 1735 * as a modifier. Therefore, an assignment like 1736 * C++=/usr/bin/CC 1737 * is interpreted as "C+ +=" instead of "C++ =". 1738 * 1739 * Used for both lines in a file and command line arguments. 1740 */ 1741 bool 1742 Parse_IsVar(const char *p, VarAssign *out_var) 1743 { 1744 VarAssignParsed pvar; 1745 const char *firstSpace = NULL; 1746 int level = 0; 1747 1748 cpp_skip_hspace(&p); /* Skip to variable name */ 1749 1750 /* 1751 * During parsing, the '+' of the '+=' operator is initially parsed 1752 * as part of the variable name. It is later corrected, as is the 1753 * ':sh' modifier. Of these two (nameEnd and op), the earlier one 1754 * determines the actual end of the variable name. 1755 */ 1756 pvar.nameStart = p; 1757 #ifdef CLEANUP 1758 pvar.nameEnd = NULL; 1759 pvar.eq = NULL; 1760 #endif 1761 1762 /* 1763 * Scan for one of the assignment operators outside a variable 1764 * expansion. 1765 */ 1766 while (*p != '\0') { 1767 char ch = *p++; 1768 if (ch == '(' || ch == '{') { 1769 level++; 1770 continue; 1771 } 1772 if (ch == ')' || ch == '}') { 1773 level--; 1774 continue; 1775 } 1776 1777 if (level != 0) 1778 continue; 1779 1780 if (ch == ' ' || ch == '\t') 1781 if (firstSpace == NULL) 1782 firstSpace = p - 1; 1783 while (ch == ' ' || ch == '\t') 1784 ch = *p++; 1785 1786 #ifdef SUNSHCMD 1787 if (ch == ':' && p[0] == 's' && p[1] == 'h') { 1788 p += 2; 1789 continue; 1790 } 1791 #endif 1792 if (ch == '=') { 1793 pvar.eq = p - 1; 1794 pvar.nameEnd = firstSpace != NULL ? firstSpace : p - 1; 1795 cpp_skip_whitespace(&p); 1796 AdjustVarassignOp(&pvar, p, out_var); 1797 return true; 1798 } 1799 if (*p == '=' && 1800 (ch == '+' || ch == ':' || ch == '?' || ch == '!')) { 1801 pvar.eq = p; 1802 pvar.nameEnd = firstSpace != NULL ? firstSpace : p; 1803 p++; 1804 cpp_skip_whitespace(&p); 1805 AdjustVarassignOp(&pvar, p, out_var); 1806 return true; 1807 } 1808 if (firstSpace != NULL) 1809 return false; 1810 } 1811 1812 return false; 1813 } 1814 1815 /* 1816 * Check for syntax errors such as unclosed expressions or unknown modifiers. 1817 */ 1818 static void 1819 VarCheckSyntax(VarAssignOp type, const char *uvalue, GNode *scope) 1820 { 1821 if (opts.strict) { 1822 if (type != VAR_SUBST && strchr(uvalue, '$') != NULL) { 1823 char *expandedValue; 1824 1825 (void)Var_Subst(uvalue, scope, VARE_PARSE_ONLY, 1826 &expandedValue); 1827 /* TODO: handle errors */ 1828 free(expandedValue); 1829 } 1830 } 1831 } 1832 1833 static void 1834 VarAssign_EvalSubst(GNode *scope, const char *name, const char *uvalue, 1835 FStr *out_avalue) 1836 { 1837 char *evalue; 1838 1839 /* 1840 * make sure that we set the variable the first time to nothing 1841 * so that it gets substituted. 1842 * 1843 * TODO: Add a test that demonstrates why this code is needed, 1844 * apart from making the debug log longer. 1845 */ 1846 if (!Var_ExistsExpand(scope, name)) 1847 Var_SetExpand(scope, name, ""); 1848 1849 (void)Var_Subst(uvalue, scope, VARE_KEEP_DOLLAR_UNDEF, &evalue); 1850 /* TODO: handle errors */ 1851 1852 Var_SetExpand(scope, name, evalue); 1853 1854 *out_avalue = FStr_InitOwn(evalue); 1855 } 1856 1857 static void 1858 VarAssign_EvalShell(const char *name, const char *uvalue, GNode *scope, 1859 FStr *out_avalue) 1860 { 1861 FStr cmd; 1862 const char *errfmt; 1863 char *cmdOut; 1864 1865 cmd = FStr_InitRefer(uvalue); 1866 if (strchr(cmd.str, '$') != NULL) { 1867 char *expanded; 1868 (void)Var_Subst(cmd.str, SCOPE_CMDLINE, VARE_UNDEFERR, 1869 &expanded); 1870 /* TODO: handle errors */ 1871 cmd = FStr_InitOwn(expanded); 1872 } 1873 1874 cmdOut = Cmd_Exec(cmd.str, &errfmt); 1875 Var_SetExpand(scope, name, cmdOut); 1876 *out_avalue = FStr_InitOwn(cmdOut); 1877 1878 if (errfmt != NULL) 1879 Parse_Error(PARSE_WARNING, errfmt, cmd.str); 1880 1881 FStr_Done(&cmd); 1882 } 1883 1884 /* 1885 * Perform a variable assignment. 1886 * 1887 * The actual value of the variable is returned in *out_true_avalue. 1888 * Especially for VAR_SUBST and VAR_SHELL this can differ from the literal 1889 * value. 1890 * 1891 * Return whether the assignment was actually performed, which is usually 1892 * the case. It is only skipped if the operator is '?=' and the variable 1893 * already exists. 1894 */ 1895 static bool 1896 VarAssign_Eval(const char *name, VarAssignOp op, const char *uvalue, 1897 GNode *scope, FStr *out_true_avalue) 1898 { 1899 FStr avalue = FStr_InitRefer(uvalue); 1900 1901 if (op == VAR_APPEND) 1902 Var_AppendExpand(scope, name, uvalue); 1903 else if (op == VAR_SUBST) 1904 VarAssign_EvalSubst(scope, name, uvalue, &avalue); 1905 else if (op == VAR_SHELL) 1906 VarAssign_EvalShell(name, uvalue, scope, &avalue); 1907 else { 1908 if (op == VAR_DEFAULT && Var_ExistsExpand(scope, name)) 1909 return false; 1910 1911 /* Normal assignment -- just do it. */ 1912 Var_SetExpand(scope, name, uvalue); 1913 } 1914 1915 *out_true_avalue = avalue; 1916 return true; 1917 } 1918 1919 static void 1920 VarAssignSpecial(const char *name, const char *avalue) 1921 { 1922 if (strcmp(name, MAKEOVERRIDES) == 0) 1923 Main_ExportMAKEFLAGS(false); /* re-export MAKEFLAGS */ 1924 else if (strcmp(name, ".CURDIR") == 0) { 1925 /* 1926 * Someone is being (too?) clever... 1927 * Let's pretend they know what they are doing and 1928 * re-initialize the 'cur' CachedDir. 1929 */ 1930 Dir_InitCur(avalue); 1931 Dir_SetPATH(); 1932 } else if (strcmp(name, MAKE_JOB_PREFIX) == 0) 1933 Job_SetPrefix(); 1934 else if (strcmp(name, MAKE_EXPORTED) == 0) 1935 Var_ExportVars(avalue); 1936 } 1937 1938 /* Perform the variable assignment in the given scope. */ 1939 void 1940 Parse_Var(VarAssign *var, GNode *scope) 1941 { 1942 FStr avalue; /* actual value (maybe expanded) */ 1943 1944 VarCheckSyntax(var->op, var->value, scope); 1945 if (VarAssign_Eval(var->varname, var->op, var->value, scope, &avalue)) { 1946 VarAssignSpecial(var->varname, avalue.str); 1947 FStr_Done(&avalue); 1948 } 1949 1950 free(var->varname); 1951 } 1952 1953 1954 /* 1955 * See if the command possibly calls a sub-make by using the variable 1956 * expressions ${.MAKE}, ${MAKE} or the plain word "make". 1957 */ 1958 static bool 1959 MaybeSubMake(const char *cmd) 1960 { 1961 const char *start; 1962 1963 for (start = cmd; *start != '\0'; start++) { 1964 const char *p = start; 1965 char endc; 1966 1967 /* XXX: What if progname != "make"? */ 1968 if (strncmp(p, "make", 4) == 0) 1969 if (start == cmd || !ch_isalnum(p[-1])) 1970 if (!ch_isalnum(p[4])) 1971 return true; 1972 1973 if (*p != '$') 1974 continue; 1975 p++; 1976 1977 if (*p == '{') 1978 endc = '}'; 1979 else if (*p == '(') 1980 endc = ')'; 1981 else 1982 continue; 1983 p++; 1984 1985 if (*p == '.') /* Accept either ${.MAKE} or ${MAKE}. */ 1986 p++; 1987 1988 if (strncmp(p, "MAKE", 4) == 0) 1989 if (p[4] == endc) 1990 return true; 1991 } 1992 return false; 1993 } 1994 1995 /* 1996 * Append the command to the target node. 1997 * 1998 * The node may be marked as a submake node if the command is determined to 1999 * be that. 2000 */ 2001 static void 2002 GNode_AddCommand(GNode *gn, char *cmd) 2003 { 2004 /* Add to last (ie current) cohort for :: targets */ 2005 if ((gn->type & OP_DOUBLEDEP) && gn->cohorts.last != NULL) 2006 gn = gn->cohorts.last->datum; 2007 2008 /* if target already supplied, ignore commands */ 2009 if (!(gn->type & OP_HAS_COMMANDS)) { 2010 Lst_Append(&gn->commands, cmd); 2011 if (MaybeSubMake(cmd)) 2012 gn->type |= OP_SUBMAKE; 2013 RememberLocation(gn); 2014 } else { 2015 #if 0 2016 /* XXX: We cannot do this until we fix the tree */ 2017 Lst_Append(&gn->commands, cmd); 2018 Parse_Error(PARSE_WARNING, 2019 "overriding commands for target \"%s\"; " 2020 "previous commands defined at %s: %d ignored", 2021 gn->name, gn->fname, gn->lineno); 2022 #else 2023 Parse_Error(PARSE_WARNING, 2024 "duplicate script for target \"%s\" ignored", 2025 gn->name); 2026 ParseErrorInternal(gn->fname, (size_t)gn->lineno, PARSE_WARNING, 2027 "using previous script for \"%s\" defined here", 2028 gn->name); 2029 #endif 2030 } 2031 } 2032 2033 /* 2034 * Add a directory to the path searched for included makefiles bracketed 2035 * by double-quotes. 2036 */ 2037 void 2038 Parse_AddIncludeDir(const char *dir) 2039 { 2040 (void)SearchPath_Add(parseIncPath, dir); 2041 } 2042 2043 /* 2044 * Handle one of the .[-ds]include directives by remembering the current file 2045 * and pushing the included file on the stack. After the included file has 2046 * finished, parsing continues with the including file; see Parse_PushInput 2047 * and ParseEOF. 2048 * 2049 * System includes are looked up in sysIncPath, any other includes are looked 2050 * up in the parsedir and then in the directories specified by the -I command 2051 * line options. 2052 */ 2053 static void 2054 IncludeFile(const char *file, bool isSystem, bool depinc, bool silent) 2055 { 2056 struct loadedfile *lf; 2057 char *fullname; /* full pathname of file */ 2058 char *newName; 2059 char *slash, *incdir; 2060 int fd; 2061 int i; 2062 2063 fullname = file[0] == '/' ? bmake_strdup(file) : NULL; 2064 2065 if (fullname == NULL && !isSystem) { 2066 /* 2067 * Include files contained in double-quotes are first searched 2068 * relative to the including file's location. We don't want to 2069 * cd there, of course, so we just tack on the old file's 2070 * leading path components and call Dir_FindFile to see if 2071 * we can locate the file. 2072 */ 2073 2074 incdir = bmake_strdup(CurFile()->name.str); 2075 slash = strrchr(incdir, '/'); 2076 if (slash != NULL) { 2077 *slash = '\0'; 2078 /* 2079 * Now do lexical processing of leading "../" on the 2080 * filename. 2081 */ 2082 for (i = 0; strncmp(file + i, "../", 3) == 0; i += 3) { 2083 slash = strrchr(incdir + 1, '/'); 2084 if (slash == NULL || strcmp(slash, "/..") == 0) 2085 break; 2086 *slash = '\0'; 2087 } 2088 newName = str_concat3(incdir, "/", file + i); 2089 fullname = Dir_FindFile(newName, parseIncPath); 2090 if (fullname == NULL) 2091 fullname = Dir_FindFile(newName, 2092 &dirSearchPath); 2093 free(newName); 2094 } 2095 free(incdir); 2096 2097 if (fullname == NULL) { 2098 /* 2099 * Makefile wasn't found in same directory as included 2100 * makefile. 2101 * 2102 * Search for it first on the -I search path, then on 2103 * the .PATH search path, if not found in a -I 2104 * directory. If we have a suffix-specific path, we 2105 * should use that. 2106 */ 2107 const char *suff; 2108 SearchPath *suffPath = NULL; 2109 2110 if ((suff = strrchr(file, '.')) != NULL) { 2111 suffPath = Suff_GetPath(suff); 2112 if (suffPath != NULL) 2113 fullname = Dir_FindFile(file, suffPath); 2114 } 2115 if (fullname == NULL) { 2116 fullname = Dir_FindFile(file, parseIncPath); 2117 if (fullname == NULL) 2118 fullname = Dir_FindFile(file, 2119 &dirSearchPath); 2120 } 2121 } 2122 } 2123 2124 /* Looking for a system file or file still not found */ 2125 if (fullname == NULL) { 2126 /* 2127 * Look for it on the system path 2128 */ 2129 SearchPath *path = Lst_IsEmpty(&sysIncPath->dirs) 2130 ? defSysIncPath : sysIncPath; 2131 fullname = Dir_FindFile(file, path); 2132 } 2133 2134 if (fullname == NULL) { 2135 if (!silent) 2136 Parse_Error(PARSE_FATAL, "Could not find %s", file); 2137 return; 2138 } 2139 2140 /* Actually open the file... */ 2141 fd = open(fullname, O_RDONLY); 2142 if (fd == -1) { 2143 if (!silent) 2144 Parse_Error(PARSE_FATAL, "Cannot open %s", fullname); 2145 free(fullname); 2146 return; 2147 } 2148 2149 /* load it */ 2150 lf = loadfile(fullname, fd); 2151 2152 /* Start reading from this file next */ 2153 Parse_PushInput(fullname, 0, -1, loadedfile_readMore, lf); 2154 CurFile()->lf = lf; 2155 if (depinc) 2156 doing_depend = depinc; /* only turn it on */ 2157 free(fullname); 2158 } 2159 2160 /* 2161 * Parse a directive like '.include' or '.-include'. 2162 * 2163 * .include "user-makefile.mk" 2164 * .include <system-makefile.mk> 2165 */ 2166 static void 2167 ParseInclude(char *directive) 2168 { 2169 char endc; /* '>' or '"' */ 2170 char *p; 2171 bool silent = directive[0] != 'i'; 2172 FStr file; 2173 2174 p = directive + (silent ? 8 : 7); 2175 pp_skip_hspace(&p); 2176 2177 if (*p != '"' && *p != '<') { 2178 Parse_Error(PARSE_FATAL, 2179 ".include filename must be delimited by '\"' or '<'"); 2180 return; 2181 } 2182 2183 if (*p++ == '<') 2184 endc = '>'; 2185 else 2186 endc = '"'; 2187 file = FStr_InitRefer(p); 2188 2189 /* Skip to matching delimiter */ 2190 while (*p != '\0' && *p != endc) 2191 p++; 2192 2193 if (*p != endc) { 2194 Parse_Error(PARSE_FATAL, 2195 "Unclosed .include filename. '%c' expected", endc); 2196 return; 2197 } 2198 2199 *p = '\0'; 2200 2201 if (strchr(file.str, '$') != NULL) { 2202 char *xfile; 2203 Var_Subst(file.str, SCOPE_CMDLINE, VARE_WANTRES, &xfile); 2204 /* TODO: handle errors */ 2205 file = FStr_InitOwn(xfile); 2206 } 2207 2208 IncludeFile(file.str, endc == '>', directive[0] == 'd', silent); 2209 FStr_Done(&file); 2210 } 2211 2212 /* 2213 * Split filename into dirname + basename, then assign these to the 2214 * given variables. 2215 */ 2216 static void 2217 SetFilenameVars(const char *filename, const char *dirvar, const char *filevar) 2218 { 2219 const char *slash, *basename; 2220 FStr dirname; 2221 2222 slash = strrchr(filename, '/'); 2223 if (slash == NULL) { 2224 dirname = FStr_InitRefer(curdir); 2225 basename = filename; 2226 } else { 2227 dirname = FStr_InitOwn(bmake_strsedup(filename, slash)); 2228 basename = slash + 1; 2229 } 2230 2231 Global_Set(dirvar, dirname.str); 2232 Global_Set(filevar, basename); 2233 2234 DEBUG4(PARSE, "SetFilenameVars: ${%s} = `%s' ${%s} = `%s'\n", 2235 dirvar, dirname.str, filevar, basename); 2236 FStr_Done(&dirname); 2237 } 2238 2239 /* 2240 * Return the immediately including file. 2241 * 2242 * This is made complicated since the .for loop is implemented as a special 2243 * kind of .include; see For_Run. 2244 */ 2245 static const char * 2246 GetActuallyIncludingFile(void) 2247 { 2248 size_t i; 2249 const IFile *incs = GetInclude(0); 2250 2251 for (i = includes.len; i >= 2; i--) 2252 if (!incs[i - 1].fromForLoop) 2253 return incs[i - 2].name.str; 2254 return NULL; 2255 } 2256 2257 /* Set .PARSEDIR, .PARSEFILE, .INCLUDEDFROMDIR and .INCLUDEDFROMFILE. */ 2258 static void 2259 SetParseFile(const char *filename) 2260 { 2261 const char *including; 2262 2263 SetFilenameVars(filename, ".PARSEDIR", ".PARSEFILE"); 2264 2265 including = GetActuallyIncludingFile(); 2266 if (including != NULL) { 2267 SetFilenameVars(including, 2268 ".INCLUDEDFROMDIR", ".INCLUDEDFROMFILE"); 2269 } else { 2270 Global_Delete(".INCLUDEDFROMDIR"); 2271 Global_Delete(".INCLUDEDFROMFILE"); 2272 } 2273 } 2274 2275 static bool 2276 StrContainsWord(const char *str, const char *word) 2277 { 2278 size_t strLen = strlen(str); 2279 size_t wordLen = strlen(word); 2280 const char *p; 2281 2282 if (strLen < wordLen) 2283 return false; 2284 2285 for (p = str; p != NULL; p = strchr(p, ' ')) { 2286 if (*p == ' ') 2287 p++; 2288 if (p > str + strLen - wordLen) 2289 return false; 2290 2291 if (memcmp(p, word, wordLen) == 0 && 2292 (p[wordLen] == '\0' || p[wordLen] == ' ')) 2293 return true; 2294 } 2295 return false; 2296 } 2297 2298 /* 2299 * XXX: Searching through a set of words with this linear search is 2300 * inefficient for variables that contain thousands of words. 2301 * 2302 * XXX: The paths in this list don't seem to be normalized in any way. 2303 */ 2304 static bool 2305 VarContainsWord(const char *varname, const char *word) 2306 { 2307 FStr val = Var_Value(SCOPE_GLOBAL, varname); 2308 bool found = val.str != NULL && StrContainsWord(val.str, word); 2309 FStr_Done(&val); 2310 return found; 2311 } 2312 2313 /* 2314 * Track the makefiles we read - so makefiles can set dependencies on them. 2315 * Avoid adding anything more than once. 2316 * 2317 * Time complexity: O(n) per call, in total O(n^2), where n is the number 2318 * of makefiles that have been loaded. 2319 */ 2320 static void 2321 TrackInput(const char *name) 2322 { 2323 if (!VarContainsWord(MAKE_MAKEFILES, name)) 2324 Global_Append(MAKE_MAKEFILES, name); 2325 } 2326 2327 2328 /* 2329 * Start parsing from the given source. 2330 * 2331 * The given file is added to the includes stack. 2332 */ 2333 void 2334 Parse_PushInput(const char *name, int lineno, int fd, 2335 ReadMoreProc readMore, void *readMoreArg) 2336 { 2337 IFile *curFile; 2338 char *buf; 2339 size_t len; 2340 bool fromForLoop = name == NULL; 2341 2342 if (fromForLoop) 2343 name = CurFile()->name.str; 2344 else 2345 TrackInput(name); 2346 2347 DEBUG3(PARSE, "Parse_PushInput: %s %s, line %d\n", 2348 readMore == loadedfile_readMore ? "file" : ".for loop in", 2349 name, lineno); 2350 2351 if (fd == -1 && readMore == NULL) 2352 /* sanity */ 2353 return; 2354 2355 curFile = Vector_Push(&includes); 2356 curFile->name = FStr_InitOwn(bmake_strdup(name)); 2357 curFile->fromForLoop = fromForLoop; 2358 curFile->lineno = lineno; 2359 curFile->first_lineno = lineno; 2360 curFile->readMore = readMore; 2361 curFile->readMoreArg = readMoreArg; 2362 curFile->lf = NULL; 2363 curFile->depending = doing_depend; /* restore this on EOF */ 2364 2365 assert(readMore != NULL); 2366 2367 /* Get first block of input data */ 2368 buf = curFile->readMore(curFile->readMoreArg, &len); 2369 if (buf == NULL) { 2370 /* Was all a waste of time ... */ 2371 FStr_Done(&curFile->name); 2372 free(curFile); 2373 return; 2374 } 2375 curFile->buf_freeIt = buf; 2376 curFile->buf_ptr = buf; 2377 curFile->buf_end = buf + len; 2378 2379 curFile->cond_depth = Cond_save_depth(); 2380 SetParseFile(name); 2381 } 2382 2383 /* Check if the directive is an include directive. */ 2384 static bool 2385 IsInclude(const char *dir, bool sysv) 2386 { 2387 if (dir[0] == 's' || dir[0] == '-' || (dir[0] == 'd' && !sysv)) 2388 dir++; 2389 2390 if (strncmp(dir, "include", 7) != 0) 2391 return false; 2392 2393 /* Space is not mandatory for BSD .include */ 2394 return !sysv || ch_isspace(dir[7]); 2395 } 2396 2397 2398 #ifdef SYSVINCLUDE 2399 /* Check if the line is a SYSV include directive. */ 2400 static bool 2401 IsSysVInclude(const char *line) 2402 { 2403 const char *p; 2404 2405 if (!IsInclude(line, true)) 2406 return false; 2407 2408 /* Avoid interpreting a dependency line as an include */ 2409 for (p = line; (p = strchr(p, ':')) != NULL;) { 2410 2411 /* end of line -> it's a dependency */ 2412 if (*++p == '\0') 2413 return false; 2414 2415 /* '::' operator or ': ' -> it's a dependency */ 2416 if (*p == ':' || ch_isspace(*p)) 2417 return false; 2418 } 2419 return true; 2420 } 2421 2422 /* Push to another file. The line points to the word "include". */ 2423 static void 2424 ParseTraditionalInclude(char *line) 2425 { 2426 char *cp; /* current position in file spec */ 2427 bool done = false; 2428 bool silent = line[0] != 'i'; 2429 char *file = line + (silent ? 8 : 7); 2430 char *all_files; 2431 2432 DEBUG1(PARSE, "ParseTraditionalInclude: %s\n", file); 2433 2434 pp_skip_whitespace(&file); 2435 2436 (void)Var_Subst(file, SCOPE_CMDLINE, VARE_WANTRES, &all_files); 2437 /* TODO: handle errors */ 2438 2439 for (file = all_files; !done; file = cp + 1) { 2440 /* Skip to end of line or next whitespace */ 2441 for (cp = file; *cp != '\0' && !ch_isspace(*cp); cp++) 2442 continue; 2443 2444 if (*cp != '\0') 2445 *cp = '\0'; 2446 else 2447 done = true; 2448 2449 IncludeFile(file, false, false, silent); 2450 } 2451 2452 free(all_files); 2453 } 2454 #endif 2455 2456 #ifdef GMAKEEXPORT 2457 /* Parse "export <variable>=<value>", and actually export it. */ 2458 static void 2459 ParseGmakeExport(char *line) 2460 { 2461 char *variable = line + 6; 2462 char *value; 2463 2464 DEBUG1(PARSE, "ParseGmakeExport: %s\n", variable); 2465 2466 pp_skip_whitespace(&variable); 2467 2468 for (value = variable; *value != '\0' && *value != '='; value++) 2469 continue; 2470 2471 if (*value != '=') { 2472 Parse_Error(PARSE_FATAL, 2473 "Variable/Value missing from \"export\""); 2474 return; 2475 } 2476 *value++ = '\0'; /* terminate variable */ 2477 2478 /* 2479 * Expand the value before putting it in the environment. 2480 */ 2481 (void)Var_Subst(value, SCOPE_CMDLINE, VARE_WANTRES, &value); 2482 /* TODO: handle errors */ 2483 2484 setenv(variable, value, 1); 2485 free(value); 2486 } 2487 #endif 2488 2489 /* 2490 * Called when EOF is reached in the current file. If we were reading an 2491 * include file or a .for loop, the includes stack is popped and things set 2492 * up to go back to reading the previous file at the previous location. 2493 * 2494 * Results: 2495 * true to continue parsing, i.e. it had only reached the end of an 2496 * included file, false if the main file has been parsed completely. 2497 */ 2498 static bool 2499 ParseEOF(void) 2500 { 2501 char *ptr; 2502 size_t len; 2503 IFile *curFile = CurFile(); 2504 2505 assert(curFile->readMore != NULL); 2506 2507 doing_depend = curFile->depending; /* restore this */ 2508 /* get next input buffer, if any */ 2509 ptr = curFile->readMore(curFile->readMoreArg, &len); 2510 curFile->buf_ptr = ptr; 2511 curFile->buf_freeIt = ptr; 2512 curFile->buf_end = ptr == NULL ? NULL : ptr + len; 2513 curFile->lineno = curFile->first_lineno; 2514 if (ptr != NULL) 2515 return true; /* Iterate again */ 2516 2517 /* 2518 * Ensure the makefile (or .for loop) didn't have mismatched 2519 * conditionals. 2520 */ 2521 Cond_restore_depth(curFile->cond_depth); 2522 2523 if (curFile->lf != NULL) { 2524 loadedfile_destroy(curFile->lf); 2525 curFile->lf = NULL; 2526 } 2527 2528 FStr_Done(&curFile->name); 2529 free(curFile->buf_freeIt); 2530 Vector_Pop(&includes); 2531 2532 if (includes.len == 0) { 2533 /* We've run out of input */ 2534 Global_Delete(".PARSEDIR"); 2535 Global_Delete(".PARSEFILE"); 2536 Global_Delete(".INCLUDEDFROMDIR"); 2537 Global_Delete(".INCLUDEDFROMFILE"); 2538 return false; 2539 } 2540 2541 curFile = CurFile(); 2542 DEBUG2(PARSE, "ParseEOF: returning to file %s, line %d\n", 2543 curFile->name.str, curFile->lineno); 2544 2545 SetParseFile(curFile->name.str); 2546 return true; 2547 } 2548 2549 typedef enum ParseRawLineResult { 2550 PRLR_LINE, 2551 PRLR_EOF, 2552 PRLR_ERROR 2553 } ParseRawLineResult; 2554 2555 /* 2556 * Parse until the end of a line, taking into account lines that end with 2557 * backslash-newline. The resulting line goes from out_line to out_line_end; 2558 * the line is not null-terminated. 2559 */ 2560 static ParseRawLineResult 2561 ParseRawLine(IFile *curFile, char **out_line, char **out_line_end, 2562 char **out_firstBackslash, char **out_firstComment) 2563 { 2564 char *line = curFile->buf_ptr; 2565 char *buf_end = curFile->buf_end; 2566 char *p = line; 2567 char *line_end = line; 2568 char *firstBackslash = NULL; 2569 char *firstComment = NULL; 2570 ParseRawLineResult res = PRLR_LINE; 2571 2572 curFile->lineno++; 2573 2574 for (;;) { 2575 char ch; 2576 2577 if (p == buf_end) { 2578 res = PRLR_EOF; 2579 break; 2580 } 2581 2582 ch = *p; 2583 if (ch == '\0' || 2584 (ch == '\\' && p + 1 < buf_end && p[1] == '\0')) { 2585 Parse_Error(PARSE_FATAL, "Zero byte read from file"); 2586 return PRLR_ERROR; 2587 } 2588 2589 /* Treat next character after '\' as literal. */ 2590 if (ch == '\\') { 2591 if (firstBackslash == NULL) 2592 firstBackslash = p; 2593 if (p[1] == '\n') { 2594 curFile->lineno++; 2595 if (p + 2 == buf_end) { 2596 line_end = p; 2597 *line_end = '\n'; 2598 p += 2; 2599 continue; 2600 } 2601 } 2602 p += 2; 2603 line_end = p; 2604 assert(p <= buf_end); 2605 continue; 2606 } 2607 2608 /* 2609 * Remember the first '#' for comment stripping, unless 2610 * the previous char was '[', as in the modifier ':[#]'. 2611 */ 2612 if (ch == '#' && firstComment == NULL && 2613 !(p > line && p[-1] == '[')) 2614 firstComment = line_end; 2615 2616 p++; 2617 if (ch == '\n') 2618 break; 2619 2620 /* We are not interested in trailing whitespace. */ 2621 if (!ch_isspace(ch)) 2622 line_end = p; 2623 } 2624 2625 *out_line = line; 2626 curFile->buf_ptr = p; 2627 *out_line_end = line_end; 2628 *out_firstBackslash = firstBackslash; 2629 *out_firstComment = firstComment; 2630 return res; 2631 } 2632 2633 /* 2634 * Beginning at start, unescape '\#' to '#' and replace backslash-newline 2635 * with a single space. 2636 */ 2637 static void 2638 UnescapeBackslash(char *line, char *start) 2639 { 2640 char *src = start; 2641 char *dst = start; 2642 char *spaceStart = line; 2643 2644 for (;;) { 2645 char ch = *src++; 2646 if (ch != '\\') { 2647 if (ch == '\0') 2648 break; 2649 *dst++ = ch; 2650 continue; 2651 } 2652 2653 ch = *src++; 2654 if (ch == '\0') { 2655 /* Delete '\\' at end of buffer */ 2656 dst--; 2657 break; 2658 } 2659 2660 /* Delete '\\' from before '#' on non-command lines */ 2661 if (ch == '#' && line[0] != '\t') { 2662 *dst++ = ch; 2663 continue; 2664 } 2665 2666 if (ch != '\n') { 2667 /* Leave '\\' in buffer for later */ 2668 *dst++ = '\\'; 2669 /* 2670 * Make sure we don't delete an escaped ' ' from the 2671 * line end. 2672 */ 2673 spaceStart = dst + 1; 2674 *dst++ = ch; 2675 continue; 2676 } 2677 2678 /* 2679 * Escaped '\n' -- replace following whitespace with a single 2680 * ' '. 2681 */ 2682 pp_skip_hspace(&src); 2683 *dst++ = ' '; 2684 } 2685 2686 /* Delete any trailing spaces - eg from empty continuations */ 2687 while (dst > spaceStart && ch_isspace(dst[-1])) 2688 dst--; 2689 *dst = '\0'; 2690 } 2691 2692 typedef enum LineKind { 2693 /* 2694 * Return the next line that is neither empty nor a comment. 2695 * Backslash line continuations are folded into a single space. 2696 * A trailing comment, if any, is discarded. 2697 */ 2698 LK_NONEMPTY, 2699 2700 /* 2701 * Return the next line, even if it is empty or a comment. 2702 * Preserve backslash-newline to keep the line numbers correct. 2703 * 2704 * Used in .for loops to collect the body of the loop while waiting 2705 * for the corresponding .endfor. 2706 */ 2707 LK_FOR_BODY, 2708 2709 /* 2710 * Return the next line that starts with a dot. 2711 * Backslash line continuations are folded into a single space. 2712 * A trailing comment, if any, is discarded. 2713 * 2714 * Used in .if directives to skip over irrelevant branches while 2715 * waiting for the corresponding .endif. 2716 */ 2717 LK_DOT 2718 } LineKind; 2719 2720 /* Return the next "interesting" logical line from the current file. */ 2721 static char * 2722 ReadLowLevelLine(LineKind kind) 2723 { 2724 IFile *curFile = CurFile(); 2725 char *line; 2726 char *line_end; 2727 char *firstBackslash; 2728 char *firstComment; 2729 2730 for (;;) { 2731 ParseRawLineResult res = ParseRawLine(curFile, 2732 &line, &line_end, &firstBackslash, &firstComment); 2733 if (res == PRLR_ERROR) 2734 return NULL; 2735 2736 if (line_end == line || firstComment == line) { 2737 if (res == PRLR_EOF) 2738 return NULL; 2739 if (kind != LK_FOR_BODY) 2740 continue; 2741 } 2742 2743 /* We now have a line of data */ 2744 assert(ch_isspace(*line_end)); 2745 *line_end = '\0'; 2746 2747 if (kind == LK_FOR_BODY) 2748 return line; /* Don't join the physical lines. */ 2749 2750 if (kind == LK_DOT && line[0] != '.') 2751 continue; 2752 break; 2753 } 2754 2755 /* Ignore anything after a non-escaped '#' in non-commands. */ 2756 if (firstComment != NULL && line[0] != '\t') 2757 *firstComment = '\0'; 2758 2759 /* If we didn't see a '\\' then the in-situ data is fine. */ 2760 if (firstBackslash == NULL) 2761 return line; 2762 2763 /* Remove escapes from '\n' and '#' */ 2764 UnescapeBackslash(line, firstBackslash); 2765 2766 return line; 2767 } 2768 2769 static bool 2770 SkipIrrelevantBranches(void) 2771 { 2772 char *line; 2773 2774 while ((line = ReadLowLevelLine(LK_DOT)) != NULL) { 2775 if (Cond_EvalLine(line) == COND_PARSE) 2776 break; 2777 /* 2778 * TODO: Check for typos in .elif directives 2779 * such as .elsif or .elseif. 2780 * 2781 * This check will probably duplicate some of 2782 * the code in ParseLine. Most of the code 2783 * there cannot apply, only ParseVarassign and 2784 * ParseDependencyLine can, and to prevent code 2785 * duplication, these would need to be called 2786 * with a flag called onlyCheckSyntax. 2787 * 2788 * See directive-elif.mk for details. 2789 */ 2790 } 2791 2792 return line != NULL; 2793 } 2794 2795 static bool 2796 ParseForLoop(const char *line) 2797 { 2798 int rval; 2799 int firstLineno; 2800 2801 rval = For_Eval(line); 2802 if (rval == 0) 2803 return false; /* Not a .for line */ 2804 if (rval < 0) 2805 return true; /* Syntax error - error printed, ignore line */ 2806 2807 firstLineno = CurFile()->lineno; 2808 2809 /* Accumulate loop lines until matching .endfor */ 2810 do { 2811 line = ReadLowLevelLine(LK_FOR_BODY); 2812 if (line == NULL) { 2813 Parse_Error(PARSE_FATAL, 2814 "Unexpected end of file in .for loop"); 2815 break; 2816 } 2817 } while (For_Accum(line)); 2818 2819 For_Run(firstLineno); /* Stash each iteration as a new 'input file' */ 2820 2821 return true; /* Read next line from for-loop buffer */ 2822 } 2823 2824 /* 2825 * Read an entire line from the input file. 2826 * 2827 * Empty lines, .if and .for are completely handled by this function, 2828 * leaving only variable assignments, other directives, dependency lines 2829 * and shell commands to the caller. 2830 * 2831 * Results: 2832 * A line without its newline and without any trailing whitespace, 2833 * or NULL. 2834 */ 2835 static char * 2836 ReadHighLevelLine(void) 2837 { 2838 char *line; 2839 2840 for (;;) { 2841 line = ReadLowLevelLine(LK_NONEMPTY); 2842 if (line == NULL) 2843 return NULL; 2844 2845 if (line[0] != '.') 2846 return line; 2847 2848 /* 2849 * The line might be a conditional. Ask the conditional module 2850 * about it and act accordingly 2851 */ 2852 switch (Cond_EvalLine(line)) { 2853 case COND_SKIP: 2854 if (!SkipIrrelevantBranches()) 2855 return NULL; 2856 continue; 2857 case COND_PARSE: 2858 continue; 2859 case COND_INVALID: /* Not a conditional line */ 2860 if (ParseForLoop(line)) 2861 continue; 2862 break; 2863 } 2864 return line; 2865 } 2866 } 2867 2868 static void 2869 FinishDependencyGroup(void) 2870 { 2871 GNodeListNode *ln; 2872 2873 if (targets == NULL) 2874 return; 2875 2876 for (ln = targets->first; ln != NULL; ln = ln->next) { 2877 GNode *gn = ln->datum; 2878 2879 Suff_EndTransform(gn); 2880 2881 /* 2882 * Mark the target as already having commands if it does, to 2883 * keep from having shell commands on multiple dependency 2884 * lines. 2885 */ 2886 if (!Lst_IsEmpty(&gn->commands)) 2887 gn->type |= OP_HAS_COMMANDS; 2888 } 2889 2890 Lst_Free(targets); 2891 targets = NULL; 2892 } 2893 2894 /* Add the command to each target from the current dependency spec. */ 2895 static void 2896 ParseLine_ShellCommand(const char *p) 2897 { 2898 cpp_skip_whitespace(&p); 2899 if (*p == '\0') 2900 return; /* skip empty commands */ 2901 2902 if (targets == NULL) { 2903 Parse_Error(PARSE_FATAL, 2904 "Unassociated shell command \"%s\"", p); 2905 return; 2906 } 2907 2908 { 2909 char *cmd = bmake_strdup(p); 2910 GNodeListNode *ln; 2911 2912 for (ln = targets->first; ln != NULL; ln = ln->next) { 2913 GNode *gn = ln->datum; 2914 GNode_AddCommand(gn, cmd); 2915 } 2916 #ifdef CLEANUP 2917 Lst_Append(&targCmds, cmd); 2918 #endif 2919 } 2920 } 2921 2922 /* 2923 * See if the line starts with one of the known directives, and if so, handle 2924 * the directive. 2925 */ 2926 static bool 2927 ParseDirective(char *line) 2928 { 2929 char *cp = line + 1; 2930 const char *arg; 2931 Substring dir; 2932 2933 pp_skip_whitespace(&cp); 2934 if (IsInclude(cp, false)) { 2935 ParseInclude(cp); 2936 return true; 2937 } 2938 2939 dir.start = cp; 2940 while (ch_isalpha(*cp) || *cp == '-') 2941 cp++; 2942 dir.end = cp; 2943 2944 if (*cp != '\0' && !ch_isspace(*cp)) 2945 return false; 2946 2947 pp_skip_whitespace(&cp); 2948 arg = cp; 2949 2950 if (Substring_Equals(dir, "undef")) 2951 Var_Undef(arg); 2952 else if (Substring_Equals(dir, "export")) 2953 Var_Export(VEM_PLAIN, arg); 2954 else if (Substring_Equals(dir, "export-env")) 2955 Var_Export(VEM_ENV, arg); 2956 else if (Substring_Equals(dir, "export-literal")) 2957 Var_Export(VEM_LITERAL, arg); 2958 else if (Substring_Equals(dir, "unexport")) 2959 Var_UnExport(false, arg); 2960 else if (Substring_Equals(dir, "unexport-env")) 2961 Var_UnExport(true, arg); 2962 else if (Substring_Equals(dir, "info")) 2963 ParseMessage(PARSE_INFO, "info", arg); 2964 else if (Substring_Equals(dir, "warning")) 2965 ParseMessage(PARSE_WARNING, "warning", arg); 2966 else if (Substring_Equals(dir, "error")) 2967 ParseMessage(PARSE_FATAL, "error", arg); 2968 else 2969 return false; 2970 return true; 2971 } 2972 2973 static bool 2974 ParseVarassign(const char *line) 2975 { 2976 VarAssign var; 2977 2978 if (!Parse_IsVar(line, &var)) 2979 return false; 2980 2981 FinishDependencyGroup(); 2982 Parse_Var(&var, SCOPE_GLOBAL); 2983 return true; 2984 } 2985 2986 static char * 2987 FindSemicolon(char *p) 2988 { 2989 int level = 0; 2990 2991 for (; *p != '\0'; p++) { 2992 if (*p == '\\' && p[1] != '\0') { 2993 p++; 2994 continue; 2995 } 2996 2997 if (*p == '$' && (p[1] == '(' || p[1] == '{')) 2998 level++; 2999 else if (level > 0 && (*p == ')' || *p == '}')) 3000 level--; 3001 else if (level == 0 && *p == ';') 3002 break; 3003 } 3004 return p; 3005 } 3006 3007 /* 3008 * dependency -> target... op [source...] [';' command] 3009 * op -> ':' | '::' | '!' 3010 */ 3011 static void 3012 ParseDependencyLine(char *line) 3013 { 3014 VarEvalMode emode; 3015 char *expanded_line; 3016 const char *shellcmd = NULL; 3017 3018 /* 3019 * For some reason - probably to make the parser impossible - 3020 * a ';' can be used to separate commands from dependencies. 3021 * Attempt to avoid ';' inside substitution patterns. 3022 */ 3023 { 3024 char *semicolon = FindSemicolon(line); 3025 if (*semicolon != '\0') { 3026 /* Terminate the dependency list at the ';' */ 3027 *semicolon = '\0'; 3028 shellcmd = semicolon + 1; 3029 } 3030 } 3031 3032 /* 3033 * We now know it's a dependency line so it needs to have all 3034 * variables expanded before being parsed. 3035 * 3036 * XXX: Ideally the dependency line would first be split into 3037 * its left-hand side, dependency operator and right-hand side, 3038 * and then each side would be expanded on its own. This would 3039 * allow for the left-hand side to allow only defined variables 3040 * and to allow variables on the right-hand side to be undefined 3041 * as well. 3042 * 3043 * Parsing the line first would also prevent that targets 3044 * generated from variable expressions are interpreted as the 3045 * dependency operator, such as in "target${:U\:} middle: source", 3046 * in which the middle is interpreted as a source, not a target. 3047 */ 3048 3049 /* 3050 * In lint mode, allow undefined variables to appear in dependency 3051 * lines. 3052 * 3053 * Ideally, only the right-hand side would allow undefined variables 3054 * since it is common to have optional dependencies. Having undefined 3055 * variables on the left-hand side is more unusual though. Since 3056 * both sides are expanded in a single pass, there is not much choice 3057 * what to do here. 3058 * 3059 * In normal mode, it does not matter whether undefined variables are 3060 * allowed or not since as of 2020-09-14, Var_Parse does not print 3061 * any parse errors in such a case. It simply returns the special 3062 * empty string var_Error, which cannot be detected in the result of 3063 * Var_Subst. 3064 */ 3065 emode = opts.strict ? VARE_WANTRES : VARE_UNDEFERR; 3066 (void)Var_Subst(line, SCOPE_CMDLINE, emode, &expanded_line); 3067 /* TODO: handle errors */ 3068 3069 /* Need a fresh list for the target nodes */ 3070 if (targets != NULL) 3071 Lst_Free(targets); 3072 targets = Lst_New(); 3073 3074 ParseDependency(expanded_line); 3075 free(expanded_line); 3076 3077 if (shellcmd != NULL) 3078 ParseLine_ShellCommand(shellcmd); 3079 } 3080 3081 static void 3082 ParseLine(char *line) 3083 { 3084 /* 3085 * Lines that begin with '.' can be pretty much anything: 3086 * - directives like '.include' or '.if', 3087 * - suffix rules like '.c.o:', 3088 * - dependencies for filenames that start with '.', 3089 * - variable assignments like '.tmp=value'. 3090 */ 3091 if (line[0] == '.' && ParseDirective(line)) 3092 return; 3093 3094 if (line[0] == '\t') { 3095 ParseLine_ShellCommand(line + 1); 3096 return; 3097 } 3098 3099 #ifdef SYSVINCLUDE 3100 if (IsSysVInclude(line)) { 3101 /* 3102 * It's an S3/S5-style "include". 3103 */ 3104 ParseTraditionalInclude(line); 3105 return; 3106 } 3107 #endif 3108 3109 #ifdef GMAKEEXPORT 3110 if (strncmp(line, "export", 6) == 0 && ch_isspace(line[6]) && 3111 strchr(line, ':') == NULL) { 3112 /* 3113 * It's a Gmake "export". 3114 */ 3115 ParseGmakeExport(line); 3116 return; 3117 } 3118 #endif 3119 3120 if (ParseVarassign(line)) 3121 return; 3122 3123 FinishDependencyGroup(); 3124 3125 ParseDependencyLine(line); 3126 } 3127 3128 /* 3129 * Parse a top-level makefile, incorporating its content into the global 3130 * dependency graph. 3131 * 3132 * Input: 3133 * name The name of the file being read 3134 * fd The open file to parse; will be closed at the end 3135 */ 3136 void 3137 Parse_File(const char *name, int fd) 3138 { 3139 char *line; /* the line we're working on */ 3140 struct loadedfile *lf; 3141 3142 lf = loadfile(name, fd); 3143 3144 assert(targets == NULL); 3145 3146 if (name == NULL) 3147 name = "(stdin)"; 3148 3149 Parse_PushInput(name, 0, -1, loadedfile_readMore, lf); 3150 CurFile()->lf = lf; 3151 3152 do { 3153 while ((line = ReadHighLevelLine()) != NULL) { 3154 DEBUG2(PARSE, "Parsing line %d: %s\n", 3155 CurFile()->lineno, line); 3156 ParseLine(line); 3157 } 3158 /* Reached EOF, but it may be just EOF of an include file. */ 3159 } while (ParseEOF()); 3160 3161 FinishDependencyGroup(); 3162 3163 if (parseErrors != 0) { 3164 (void)fflush(stdout); 3165 (void)fprintf(stderr, 3166 "%s: Fatal errors encountered -- cannot continue", 3167 progname); 3168 PrintOnError(NULL, NULL); 3169 exit(1); 3170 } 3171 } 3172 3173 /* Initialize the parsing module. */ 3174 void 3175 Parse_Init(void) 3176 { 3177 mainNode = NULL; 3178 parseIncPath = SearchPath_New(); 3179 sysIncPath = SearchPath_New(); 3180 defSysIncPath = SearchPath_New(); 3181 Vector_Init(&includes, sizeof(IFile)); 3182 } 3183 3184 /* Clean up the parsing module. */ 3185 void 3186 Parse_End(void) 3187 { 3188 #ifdef CLEANUP 3189 Lst_DoneCall(&targCmds, free); 3190 assert(targets == NULL); 3191 SearchPath_Free(defSysIncPath); 3192 SearchPath_Free(sysIncPath); 3193 SearchPath_Free(parseIncPath); 3194 assert(includes.len == 0); 3195 Vector_Done(&includes); 3196 #endif 3197 } 3198 3199 3200 /* 3201 * Return a list containing the single main target to create. 3202 * If no such target exists, we Punt with an obnoxious error message. 3203 */ 3204 void 3205 Parse_MainName(GNodeList *mainList) 3206 { 3207 if (mainNode == NULL) 3208 Punt("no target to make."); 3209 3210 Lst_Append(mainList, mainNode); 3211 if (mainNode->type & OP_DOUBLEDEP) 3212 Lst_AppendAll(mainList, &mainNode->cohorts); 3213 3214 Global_Append(".TARGETS", mainNode->name); 3215 } 3216 3217 int 3218 Parse_NumErrors(void) 3219 { 3220 return parseErrors; 3221 } 3222