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