1 /* $NetBSD: parse.c,v 1.565 2021/09/21 23:06:18 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.565 2021/09/21 23:06:18 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 parseErrors = 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[17]; /* 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 RememberLocation(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 parseErrors++; 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 RememberLocation(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 RememberLocation(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 RememberLocation(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 RememberLocation(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 /* 1058 * Handle special targets like .PATH, .DEFAULT, .BEGIN, .ORDER. 1059 * 1060 * See the tests deptgt-*.mk. 1061 */ 1062 static void 1063 ParseDependencyTargetSpecial(ParseSpecial *inout_specType, 1064 const char *targetName, 1065 SearchPathList **inout_paths) 1066 { 1067 switch (*inout_specType) { 1068 case SP_PATH: 1069 if (*inout_paths == NULL) 1070 *inout_paths = Lst_New(); 1071 Lst_Append(*inout_paths, &dirSearchPath); 1072 break; 1073 case SP_MAIN: 1074 /* 1075 * Allow targets from the command line to override the 1076 * .MAIN node. 1077 */ 1078 if (!Lst_IsEmpty(&opts.create)) 1079 *inout_specType = SP_NOT; 1080 break; 1081 case SP_BEGIN: 1082 case SP_END: 1083 case SP_STALE: 1084 case SP_ERROR: 1085 case SP_INTERRUPT: { 1086 GNode *gn = Targ_GetNode(targetName); 1087 if (doing_depend) 1088 RememberLocation(gn); 1089 gn->type |= OP_NOTMAIN | OP_SPECIAL; 1090 Lst_Append(targets, gn); 1091 break; 1092 } 1093 case SP_DEFAULT: { 1094 /* 1095 * Need to create a node to hang commands on, but we don't 1096 * want it in the graph, nor do we want it to be the Main 1097 * Target. We claim the node is a transformation rule to make 1098 * life easier later, when we'll use Make_HandleUse to 1099 * actually apply the .DEFAULT commands. 1100 */ 1101 GNode *gn = GNode_New(".DEFAULT"); 1102 gn->type |= OP_NOTMAIN | OP_TRANSFORM; 1103 Lst_Append(targets, gn); 1104 defaultNode = gn; 1105 break; 1106 } 1107 case SP_DELETE_ON_ERROR: 1108 deleteOnError = true; 1109 break; 1110 case SP_NOTPARALLEL: 1111 opts.maxJobs = 1; 1112 break; 1113 case SP_SINGLESHELL: 1114 opts.compatMake = true; 1115 break; 1116 case SP_ORDER: 1117 order_pred = NULL; 1118 break; 1119 default: 1120 break; 1121 } 1122 } 1123 1124 /* 1125 * .PATH<suffix> has to be handled specially. 1126 * Call on the suffix module to give us a path to modify. 1127 */ 1128 static bool 1129 ParseDependencyTargetPath(const char *suffixName, 1130 SearchPathList **inout_paths) 1131 { 1132 SearchPath *path; 1133 1134 path = Suff_GetPath(suffixName); 1135 if (path == NULL) { 1136 Parse_Error(PARSE_FATAL, 1137 "Suffix '%s' not defined (yet)", suffixName); 1138 return false; 1139 } 1140 1141 if (*inout_paths == NULL) 1142 *inout_paths = Lst_New(); 1143 Lst_Append(*inout_paths, path); 1144 1145 return true; 1146 } 1147 1148 /* 1149 * See if it's a special target and if so set specType to match it. 1150 */ 1151 static bool 1152 ParseDependencyTarget(const char *targetName, 1153 ParseSpecial *inout_specType, 1154 GNodeType *out_tOp, SearchPathList **inout_paths) 1155 { 1156 int keywd; 1157 1158 if (!(targetName[0] == '.' && ch_isupper(targetName[1]))) 1159 return true; 1160 1161 /* 1162 * See if the target is a special target that must have it 1163 * or its sources handled specially. 1164 */ 1165 keywd = ParseFindKeyword(targetName); 1166 if (keywd != -1) { 1167 if (*inout_specType == SP_PATH && 1168 parseKeywords[keywd].spec != SP_PATH) { 1169 Parse_Error(PARSE_FATAL, "Mismatched special targets"); 1170 return false; 1171 } 1172 1173 *inout_specType = parseKeywords[keywd].spec; 1174 *out_tOp = parseKeywords[keywd].op; 1175 1176 ParseDependencyTargetSpecial(inout_specType, targetName, 1177 inout_paths); 1178 1179 } else if (strncmp(targetName, ".PATH", 5) == 0) { 1180 *inout_specType = SP_PATH; 1181 if (!ParseDependencyTargetPath(targetName + 5, inout_paths)) 1182 return false; 1183 } 1184 return true; 1185 } 1186 1187 static void 1188 ParseDependencyTargetMundane(char *targetName, StringList *curTargs) 1189 { 1190 if (Dir_HasWildcards(targetName)) { 1191 /* 1192 * Targets are to be sought only in the current directory, 1193 * so create an empty path for the thing. Note we need to 1194 * use Dir_Destroy in the destruction of the path as the 1195 * Dir module could have added a directory to the path... 1196 */ 1197 SearchPath *emptyPath = SearchPath_New(); 1198 1199 SearchPath_Expand(emptyPath, targetName, curTargs); 1200 1201 SearchPath_Free(emptyPath); 1202 } else { 1203 /* 1204 * No wildcards, but we want to avoid code duplication, 1205 * so create a list with the word on it. 1206 */ 1207 Lst_Append(curTargs, targetName); 1208 } 1209 1210 /* Apply the targets. */ 1211 1212 while (!Lst_IsEmpty(curTargs)) { 1213 char *targName = Lst_Dequeue(curTargs); 1214 GNode *gn = Suff_IsTransform(targName) 1215 ? Suff_AddTransform(targName) 1216 : Targ_GetNode(targName); 1217 if (doing_depend) 1218 RememberLocation(gn); 1219 1220 Lst_Append(targets, gn); 1221 } 1222 } 1223 1224 static void 1225 ParseDependencyTargetExtraWarn(char **pp, const char *lstart) 1226 { 1227 bool warning = false; 1228 char *cp = *pp; 1229 1230 while (*cp != '\0') { 1231 if (!ParseIsEscaped(lstart, cp) && (*cp == '!' || *cp == ':')) 1232 break; 1233 if (ParseIsEscaped(lstart, cp) || (*cp != ' ' && *cp != '\t')) 1234 warning = true; 1235 cp++; 1236 } 1237 if (warning) 1238 Parse_Error(PARSE_WARNING, "Extra target ignored"); 1239 1240 *pp = cp; 1241 } 1242 1243 static void 1244 ParseDependencyCheckSpec(ParseSpecial specType) 1245 { 1246 switch (specType) { 1247 default: 1248 Parse_Error(PARSE_WARNING, 1249 "Special and mundane targets don't mix. " 1250 "Mundane ones ignored"); 1251 break; 1252 case SP_DEFAULT: 1253 case SP_STALE: 1254 case SP_BEGIN: 1255 case SP_END: 1256 case SP_ERROR: 1257 case SP_INTERRUPT: 1258 /* 1259 * These create nodes on which to hang commands, so targets 1260 * shouldn't be empty. 1261 */ 1262 case SP_NOT: 1263 /* Nothing special here -- targets can be empty if it wants. */ 1264 break; 1265 } 1266 } 1267 1268 /* 1269 * In a dependency line like 'targets: sources' or 'targets! sources', parse 1270 * the operator ':', '::' or '!' from between the targets and the sources. 1271 */ 1272 static bool 1273 ParseDependencyOp(char **pp, const char *lstart, GNodeType *out_op) 1274 { 1275 const char *cp = *pp; 1276 1277 if (*cp == '!') { 1278 *out_op = OP_FORCE; 1279 (*pp)++; 1280 return true; 1281 } 1282 1283 if (*cp == ':') { 1284 if (cp[1] == ':') { 1285 *out_op = OP_DOUBLEDEP; 1286 (*pp) += 2; 1287 } else { 1288 *out_op = OP_DEPENDS; 1289 (*pp)++; 1290 } 1291 return true; 1292 } 1293 1294 { 1295 const char *msg = lstart[0] == '.' 1296 ? "Unknown directive" : "Missing dependency operator"; 1297 Parse_Error(PARSE_FATAL, "%s", msg); 1298 return false; 1299 } 1300 } 1301 1302 static void 1303 ClearPaths(SearchPathList *paths) 1304 { 1305 if (paths != NULL) { 1306 SearchPathListNode *ln; 1307 for (ln = paths->first; ln != NULL; ln = ln->next) 1308 SearchPath_Clear(ln->datum); 1309 } 1310 1311 Dir_SetPATH(); 1312 } 1313 1314 /* 1315 * Several special targets take different actions if present with no 1316 * sources: 1317 * a .SUFFIXES line with no sources clears out all old suffixes 1318 * a .PRECIOUS line makes all targets precious 1319 * a .IGNORE line ignores errors for all targets 1320 * a .SILENT line creates silence when making all targets 1321 * a .PATH removes all directories from the search path(s). 1322 */ 1323 static void 1324 ParseDependencySourcesEmpty(ParseSpecial specType, SearchPathList *paths) 1325 { 1326 switch (specType) { 1327 case SP_SUFFIXES: 1328 Suff_ClearSuffixes(); 1329 break; 1330 case SP_PRECIOUS: 1331 allPrecious = true; 1332 break; 1333 case SP_IGNORE: 1334 opts.ignoreErrors = true; 1335 break; 1336 case SP_SILENT: 1337 opts.beSilent = true; 1338 break; 1339 case SP_PATH: 1340 ClearPaths(paths); 1341 break; 1342 #ifdef POSIX 1343 case SP_POSIX: 1344 Global_Set("%POSIX", "1003.2"); 1345 break; 1346 #endif 1347 default: 1348 break; 1349 } 1350 } 1351 1352 static void 1353 AddToPaths(const char *dir, SearchPathList *paths) 1354 { 1355 if (paths != NULL) { 1356 SearchPathListNode *ln; 1357 for (ln = paths->first; ln != NULL; ln = ln->next) 1358 (void)SearchPath_Add(ln->datum, dir); 1359 } 1360 } 1361 1362 /* 1363 * If the target was one that doesn't take files as its sources 1364 * but takes something like suffixes, we take each 1365 * space-separated word on the line as a something and deal 1366 * with it accordingly. 1367 * 1368 * If the target was .SUFFIXES, we take each source as a 1369 * suffix and add it to the list of suffixes maintained by the 1370 * Suff module. 1371 * 1372 * If the target was a .PATH, we add the source as a directory 1373 * to search on the search path. 1374 * 1375 * If it was .INCLUDES, the source is taken to be the suffix of 1376 * files which will be #included and whose search path should 1377 * be present in the .INCLUDES variable. 1378 * 1379 * If it was .LIBS, the source is taken to be the suffix of 1380 * files which are considered libraries and whose search path 1381 * should be present in the .LIBS variable. 1382 * 1383 * If it was .NULL, the source is the suffix to use when a file 1384 * has no valid suffix. 1385 * 1386 * If it was .OBJDIR, the source is a new definition for .OBJDIR, 1387 * and will cause make to do a new chdir to that path. 1388 */ 1389 static void 1390 ParseDependencySourceSpecial(ParseSpecial specType, char *word, 1391 SearchPathList *paths) 1392 { 1393 switch (specType) { 1394 case SP_SUFFIXES: 1395 Suff_AddSuffix(word, &mainNode); 1396 break; 1397 case SP_PATH: 1398 AddToPaths(word, paths); 1399 break; 1400 case SP_INCLUDES: 1401 Suff_AddInclude(word); 1402 break; 1403 case SP_LIBS: 1404 Suff_AddLib(word); 1405 break; 1406 case SP_NULL: 1407 Suff_SetNull(word); 1408 break; 1409 case SP_OBJDIR: 1410 Main_SetObjdir(false, "%s", word); 1411 break; 1412 default: 1413 break; 1414 } 1415 } 1416 1417 static bool 1418 ParseDependencyTargets(char **inout_cp, 1419 char **inout_line, 1420 const char *lstart, 1421 ParseSpecial *inout_specType, 1422 GNodeType *inout_tOp, 1423 SearchPathList **inout_paths, 1424 StringList *curTargs) 1425 { 1426 char *cp; 1427 char *tgt = *inout_line; 1428 char savec; 1429 const char *p; 1430 1431 for (;;) { 1432 /* 1433 * Here LINE points to the beginning of the next word, and 1434 * LSTART points to the actual beginning of the line. 1435 */ 1436 1437 /* Find the end of the next word. */ 1438 cp = tgt; 1439 p = cp; 1440 ParseDependencyTargetWord(&p, lstart); 1441 cp += p - cp; 1442 1443 /* 1444 * If the word is followed by a left parenthesis, it's the 1445 * name of an object file inside an archive (ar file). 1446 */ 1447 if (!ParseIsEscaped(lstart, cp) && *cp == '(') { 1448 /* 1449 * Archives must be handled specially to make sure the 1450 * OP_ARCHV flag is set in their 'type' field, for one 1451 * thing, and because things like "archive(file1.o 1452 * file2.o file3.o)" are permissible. 1453 * 1454 * Arch_ParseArchive will set 'line' to be the first 1455 * non-blank after the archive-spec. It creates/finds 1456 * nodes for the members and places them on the given 1457 * list, returning true if all went well and false if 1458 * there was an error in the specification. On error, 1459 * line should remain untouched. 1460 */ 1461 if (!Arch_ParseArchive(&tgt, targets, SCOPE_CMDLINE)) { 1462 Parse_Error(PARSE_FATAL, 1463 "Error in archive specification: \"%s\"", 1464 tgt); 1465 return false; 1466 } 1467 1468 cp = tgt; 1469 continue; 1470 } 1471 1472 if (*cp == '\0') { 1473 ParseErrorNoDependency(lstart); 1474 return false; 1475 } 1476 1477 /* Insert a null terminator. */ 1478 savec = *cp; 1479 *cp = '\0'; 1480 1481 if (!ParseDependencyTarget(tgt, inout_specType, inout_tOp, 1482 inout_paths)) 1483 return false; 1484 1485 /* 1486 * Have word in line. Get or create its node and stick it at 1487 * the end of the targets list 1488 */ 1489 if (*inout_specType == SP_NOT && *tgt != '\0') 1490 ParseDependencyTargetMundane(tgt, curTargs); 1491 else if (*inout_specType == SP_PATH && *tgt != '.' && 1492 *tgt != '\0') 1493 Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", 1494 tgt); 1495 1496 /* Don't need the inserted null terminator any more. */ 1497 *cp = savec; 1498 1499 /* 1500 * If it is a special type and not .PATH, it's the only target 1501 * we allow on this line. 1502 */ 1503 if (*inout_specType != SP_NOT && *inout_specType != SP_PATH) 1504 ParseDependencyTargetExtraWarn(&cp, lstart); 1505 else 1506 pp_skip_whitespace(&cp); 1507 1508 tgt = cp; 1509 if (*tgt == '\0') 1510 break; 1511 if ((*tgt == '!' || *tgt == ':') && 1512 !ParseIsEscaped(lstart, tgt)) 1513 break; 1514 } 1515 1516 *inout_cp = cp; 1517 *inout_line = tgt; 1518 return true; 1519 } 1520 1521 static void 1522 ParseDependencySourcesSpecial(char *start, char *end, 1523 ParseSpecial specType, SearchPathList *paths) 1524 { 1525 char savec; 1526 1527 while (*start != '\0') { 1528 while (*end != '\0' && !ch_isspace(*end)) 1529 end++; 1530 savec = *end; 1531 *end = '\0'; 1532 ParseDependencySourceSpecial(specType, start, paths); 1533 *end = savec; 1534 if (savec != '\0') 1535 end++; 1536 pp_skip_whitespace(&end); 1537 start = end; 1538 } 1539 } 1540 1541 static bool 1542 ParseDependencySourcesMundane(char *start, char *end, 1543 ParseSpecial specType, GNodeType tOp) 1544 { 1545 while (*start != '\0') { 1546 /* 1547 * The targets take real sources, so we must beware of archive 1548 * specifications (i.e. things with left parentheses in them) 1549 * and handle them accordingly. 1550 */ 1551 for (; *end != '\0' && !ch_isspace(*end); end++) { 1552 if (*end == '(' && end > start && end[-1] != '$') { 1553 /* 1554 * Only stop for a left parenthesis if it 1555 * isn't at the start of a word (that'll be 1556 * for variable changes later) and isn't 1557 * preceded by a dollar sign (a dynamic 1558 * source). 1559 */ 1560 break; 1561 } 1562 } 1563 1564 if (*end == '(') { 1565 GNodeList sources = LST_INIT; 1566 if (!Arch_ParseArchive(&start, &sources, 1567 SCOPE_CMDLINE)) { 1568 Parse_Error(PARSE_FATAL, 1569 "Error in source archive spec \"%s\"", 1570 start); 1571 return false; 1572 } 1573 1574 while (!Lst_IsEmpty(&sources)) { 1575 GNode *gn = Lst_Dequeue(&sources); 1576 ParseDependencySource(tOp, gn->name, specType); 1577 } 1578 Lst_Done(&sources); 1579 end = start; 1580 } else { 1581 if (*end != '\0') { 1582 *end = '\0'; 1583 end++; 1584 } 1585 1586 ParseDependencySource(tOp, start, specType); 1587 } 1588 pp_skip_whitespace(&end); 1589 start = end; 1590 } 1591 return true; 1592 } 1593 1594 /* 1595 * In a dependency line like 'targets: sources', parse the sources. 1596 * 1597 * See the tests depsrc-*.mk. 1598 */ 1599 static void 1600 ParseDependencySources(char *line, char *cp, GNodeType tOp, 1601 ParseSpecial specType, SearchPathList **inout_paths) 1602 { 1603 if (line[0] == '\0') { 1604 ParseDependencySourcesEmpty(specType, *inout_paths); 1605 } else if (specType == SP_MFLAGS) { 1606 Main_ParseArgLine(line); 1607 /* 1608 * Set the initial character to a null-character so the loop 1609 * to get sources won't get anything. 1610 */ 1611 *line = '\0'; 1612 } else if (specType == SP_SHELL) { 1613 if (!Job_ParseShell(line)) { 1614 Parse_Error(PARSE_FATAL, 1615 "improper shell specification"); 1616 return; 1617 } 1618 *line = '\0'; 1619 } else if (specType == SP_NOTPARALLEL || specType == SP_SINGLESHELL || 1620 specType == SP_DELETE_ON_ERROR) { 1621 *line = '\0'; 1622 } 1623 1624 /* Now go for the sources. */ 1625 if (specType == SP_SUFFIXES || specType == SP_PATH || 1626 specType == SP_INCLUDES || specType == SP_LIBS || 1627 specType == SP_NULL || specType == SP_OBJDIR) { 1628 ParseDependencySourcesSpecial(line, cp, specType, 1629 *inout_paths); 1630 if (*inout_paths != NULL) { 1631 Lst_Free(*inout_paths); 1632 *inout_paths = NULL; 1633 } 1634 if (specType == SP_PATH) 1635 Dir_SetPATH(); 1636 } else { 1637 assert(*inout_paths == NULL); 1638 if (!ParseDependencySourcesMundane(line, cp, specType, tOp)) 1639 return; 1640 } 1641 1642 FindMainTarget(); 1643 } 1644 1645 /* 1646 * Parse a dependency line consisting of targets, followed by a dependency 1647 * operator, optionally followed by sources. 1648 * 1649 * The nodes of the sources are linked as children to the nodes of the 1650 * targets. Nodes are created as necessary. 1651 * 1652 * The operator is applied to each node in the global 'targets' list, 1653 * which is where the nodes found for the targets are kept, by means of 1654 * the ParseOp function. 1655 * 1656 * The sources are parsed in much the same way as the targets, except 1657 * that they are expanded using the wildcarding scheme of the C-Shell, 1658 * and a target is created for each expanded word. Each of the resulting 1659 * nodes is then linked to each of the targets as one of its children. 1660 * 1661 * Certain targets and sources such as .PHONY or .PRECIOUS are handled 1662 * specially. These are the ones detailed by the specType variable. 1663 * 1664 * The storing of transformation rules such as '.c.o' is also taken care of 1665 * here. A target is recognized as a transformation rule by calling 1666 * Suff_IsTransform. If it is a transformation rule, its node is gotten 1667 * from the suffix module via Suff_AddTransform rather than the standard 1668 * Targ_FindNode in the target module. 1669 * 1670 * Upon return, the value of the line is unspecified. 1671 */ 1672 static void 1673 ParseDependency(char *line) 1674 { 1675 char *cp; /* our current position */ 1676 GNodeType op; /* the operator on the line */ 1677 SearchPathList *paths; /* search paths to alter when parsing 1678 * a list of .PATH targets */ 1679 GNodeType tOp; /* operator from special target */ 1680 /* target names to be found and added to the targets list */ 1681 StringList curTargs = LST_INIT; 1682 char *lstart = line; 1683 1684 /* 1685 * specType contains the SPECial TYPE of the current target. It is 1686 * SP_NOT if the target is unspecial. If it *is* special, however, the 1687 * children are linked as children of the parent but not vice versa. 1688 */ 1689 ParseSpecial specType = SP_NOT; 1690 1691 DEBUG1(PARSE, "ParseDependency(%s)\n", line); 1692 tOp = OP_NONE; 1693 1694 paths = NULL; 1695 1696 /* 1697 * First, grind through the targets. 1698 */ 1699 /* XXX: don't use 'line' as an iterator variable */ 1700 if (!ParseDependencyTargets(&cp, &line, lstart, &specType, &tOp, 1701 &paths, &curTargs)) 1702 goto out; 1703 1704 /* 1705 * Don't need the list of target names anymore. 1706 * The targets themselves are now in the global variable 'targets'. 1707 */ 1708 Lst_Done(&curTargs); 1709 Lst_Init(&curTargs); 1710 1711 if (!Lst_IsEmpty(targets)) 1712 ParseDependencyCheckSpec(specType); 1713 1714 /* 1715 * Have now parsed all the target names. Must parse the operator next. 1716 */ 1717 if (!ParseDependencyOp(&cp, lstart, &op)) 1718 goto out; 1719 1720 /* 1721 * Apply the operator to the target. This is how we remember which 1722 * operator a target was defined with. It fails if the operator 1723 * used isn't consistent across all references. 1724 */ 1725 ApplyDependencyOperator(op); 1726 1727 /* 1728 * Onward to the sources. 1729 * 1730 * LINE will now point to the first source word, if any, or the 1731 * end of the string if not. 1732 */ 1733 pp_skip_whitespace(&cp); 1734 line = cp; /* XXX: 'line' is an inappropriate name */ 1735 1736 ParseDependencySources(line, cp, tOp, specType, &paths); 1737 1738 out: 1739 if (paths != NULL) 1740 Lst_Free(paths); 1741 Lst_Done(&curTargs); 1742 } 1743 1744 typedef struct VarAssignParsed { 1745 const char *nameStart; /* unexpanded */ 1746 const char *nameEnd; /* before operator adjustment */ 1747 const char *eq; /* the '=' of the assignment operator */ 1748 } VarAssignParsed; 1749 1750 /* 1751 * Determine the assignment operator and adjust the end of the variable 1752 * name accordingly. 1753 */ 1754 static void 1755 AdjustVarassignOp(const VarAssignParsed *pvar, const char *value, 1756 VarAssign *out_var) 1757 { 1758 const char *op = pvar->eq; 1759 const char *const name = pvar->nameStart; 1760 VarAssignOp type; 1761 1762 if (op > name && op[-1] == '+') { 1763 type = VAR_APPEND; 1764 op--; 1765 1766 } else if (op > name && op[-1] == '?') { 1767 op--; 1768 type = VAR_DEFAULT; 1769 1770 } else if (op > name && op[-1] == ':') { 1771 op--; 1772 type = VAR_SUBST; 1773 1774 } else if (op > name && op[-1] == '!') { 1775 op--; 1776 type = VAR_SHELL; 1777 1778 } else { 1779 type = VAR_NORMAL; 1780 #ifdef SUNSHCMD 1781 while (op > name && ch_isspace(op[-1])) 1782 op--; 1783 1784 if (op >= name + 3 && op[-3] == ':' && op[-2] == 's' && 1785 op[-1] == 'h') { 1786 type = VAR_SHELL; 1787 op -= 3; 1788 } 1789 #endif 1790 } 1791 1792 { 1793 const char *nameEnd = pvar->nameEnd < op ? pvar->nameEnd : op; 1794 out_var->varname = bmake_strsedup(pvar->nameStart, nameEnd); 1795 out_var->op = type; 1796 out_var->value = value; 1797 } 1798 } 1799 1800 /* 1801 * Parse a variable assignment, consisting of a single-word variable name, 1802 * optional whitespace, an assignment operator, optional whitespace and the 1803 * variable value. 1804 * 1805 * Note: There is a lexical ambiguity with assignment modifier characters 1806 * in variable names. This routine interprets the character before the = 1807 * as a modifier. Therefore, an assignment like 1808 * C++=/usr/bin/CC 1809 * is interpreted as "C+ +=" instead of "C++ =". 1810 * 1811 * Used for both lines in a file and command line arguments. 1812 */ 1813 bool 1814 Parse_IsVar(const char *p, VarAssign *out_var) 1815 { 1816 VarAssignParsed pvar; 1817 const char *firstSpace = NULL; 1818 int level = 0; 1819 1820 cpp_skip_hspace(&p); /* Skip to variable name */ 1821 1822 /* 1823 * During parsing, the '+' of the '+=' operator is initially parsed 1824 * as part of the variable name. It is later corrected, as is the 1825 * ':sh' modifier. Of these two (nameEnd and op), the earlier one 1826 * determines the actual end of the variable name. 1827 */ 1828 pvar.nameStart = p; 1829 #ifdef CLEANUP 1830 pvar.nameEnd = NULL; 1831 pvar.eq = NULL; 1832 #endif 1833 1834 /* 1835 * Scan for one of the assignment operators outside a variable 1836 * expansion. 1837 */ 1838 while (*p != '\0') { 1839 char ch = *p++; 1840 if (ch == '(' || ch == '{') { 1841 level++; 1842 continue; 1843 } 1844 if (ch == ')' || ch == '}') { 1845 level--; 1846 continue; 1847 } 1848 1849 if (level != 0) 1850 continue; 1851 1852 if (ch == ' ' || ch == '\t') 1853 if (firstSpace == NULL) 1854 firstSpace = p - 1; 1855 while (ch == ' ' || ch == '\t') 1856 ch = *p++; 1857 1858 #ifdef SUNSHCMD 1859 if (ch == ':' && p[0] == 's' && p[1] == 'h') { 1860 p += 2; 1861 continue; 1862 } 1863 #endif 1864 if (ch == '=') { 1865 pvar.eq = p - 1; 1866 pvar.nameEnd = firstSpace != NULL ? firstSpace : p - 1; 1867 cpp_skip_whitespace(&p); 1868 AdjustVarassignOp(&pvar, p, out_var); 1869 return true; 1870 } 1871 if (*p == '=' && 1872 (ch == '+' || ch == ':' || ch == '?' || ch == '!')) { 1873 pvar.eq = p; 1874 pvar.nameEnd = firstSpace != NULL ? firstSpace : p; 1875 p++; 1876 cpp_skip_whitespace(&p); 1877 AdjustVarassignOp(&pvar, p, out_var); 1878 return true; 1879 } 1880 if (firstSpace != NULL) 1881 return false; 1882 } 1883 1884 return false; 1885 } 1886 1887 /* 1888 * Check for syntax errors such as unclosed expressions or unknown modifiers. 1889 */ 1890 static void 1891 VarCheckSyntax(VarAssignOp type, const char *uvalue, GNode *scope) 1892 { 1893 if (opts.strict) { 1894 if (type != VAR_SUBST && strchr(uvalue, '$') != NULL) { 1895 char *expandedValue; 1896 1897 (void)Var_Subst(uvalue, scope, VARE_PARSE_ONLY, 1898 &expandedValue); 1899 /* TODO: handle errors */ 1900 free(expandedValue); 1901 } 1902 } 1903 } 1904 1905 static void 1906 VarAssign_EvalSubst(GNode *scope, const char *name, const char *uvalue, 1907 FStr *out_avalue) 1908 { 1909 char *evalue; 1910 1911 /* 1912 * make sure that we set the variable the first time to nothing 1913 * so that it gets substituted. 1914 * 1915 * TODO: Add a test that demonstrates why this code is needed, 1916 * apart from making the debug log longer. 1917 */ 1918 if (!Var_ExistsExpand(scope, name)) 1919 Var_SetExpand(scope, name, ""); 1920 1921 (void)Var_Subst(uvalue, scope, VARE_KEEP_DOLLAR_UNDEF, &evalue); 1922 /* TODO: handle errors */ 1923 1924 Var_SetExpand(scope, name, evalue); 1925 1926 *out_avalue = FStr_InitOwn(evalue); 1927 } 1928 1929 static void 1930 VarAssign_EvalShell(const char *name, const char *uvalue, GNode *scope, 1931 FStr *out_avalue) 1932 { 1933 FStr cmd; 1934 const char *errfmt; 1935 char *cmdOut; 1936 1937 cmd = FStr_InitRefer(uvalue); 1938 if (strchr(cmd.str, '$') != NULL) { 1939 char *expanded; 1940 (void)Var_Subst(cmd.str, SCOPE_CMDLINE, VARE_UNDEFERR, 1941 &expanded); 1942 /* TODO: handle errors */ 1943 cmd = FStr_InitOwn(expanded); 1944 } 1945 1946 cmdOut = Cmd_Exec(cmd.str, &errfmt); 1947 Var_SetExpand(scope, name, cmdOut); 1948 *out_avalue = FStr_InitOwn(cmdOut); 1949 1950 if (errfmt != NULL) 1951 Parse_Error(PARSE_WARNING, errfmt, cmd.str); 1952 1953 FStr_Done(&cmd); 1954 } 1955 1956 /* 1957 * Perform a variable assignment. 1958 * 1959 * The actual value of the variable is returned in *out_true_avalue. 1960 * Especially for VAR_SUBST and VAR_SHELL this can differ from the literal 1961 * value. 1962 * 1963 * Return whether the assignment was actually performed, which is usually 1964 * the case. It is only skipped if the operator is '?=' and the variable 1965 * already exists. 1966 */ 1967 static bool 1968 VarAssign_Eval(const char *name, VarAssignOp op, const char *uvalue, 1969 GNode *scope, FStr *out_true_avalue) 1970 { 1971 FStr avalue = FStr_InitRefer(uvalue); 1972 1973 if (op == VAR_APPEND) 1974 Var_AppendExpand(scope, name, uvalue); 1975 else if (op == VAR_SUBST) 1976 VarAssign_EvalSubst(scope, name, uvalue, &avalue); 1977 else if (op == VAR_SHELL) 1978 VarAssign_EvalShell(name, uvalue, scope, &avalue); 1979 else { 1980 if (op == VAR_DEFAULT && Var_ExistsExpand(scope, name)) 1981 return false; 1982 1983 /* Normal assignment -- just do it. */ 1984 Var_SetExpand(scope, name, uvalue); 1985 } 1986 1987 *out_true_avalue = avalue; 1988 return true; 1989 } 1990 1991 static void 1992 VarAssignSpecial(const char *name, const char *avalue) 1993 { 1994 if (strcmp(name, MAKEOVERRIDES) == 0) 1995 Main_ExportMAKEFLAGS(false); /* re-export MAKEFLAGS */ 1996 else if (strcmp(name, ".CURDIR") == 0) { 1997 /* 1998 * Someone is being (too?) clever... 1999 * Let's pretend they know what they are doing and 2000 * re-initialize the 'cur' CachedDir. 2001 */ 2002 Dir_InitCur(avalue); 2003 Dir_SetPATH(); 2004 } else if (strcmp(name, MAKE_JOB_PREFIX) == 0) 2005 Job_SetPrefix(); 2006 else if (strcmp(name, MAKE_EXPORTED) == 0) 2007 Var_ExportVars(avalue); 2008 } 2009 2010 /* Perform the variable variable assignment in the given scope. */ 2011 void 2012 Parse_Var(VarAssign *var, GNode *scope) 2013 { 2014 FStr avalue; /* actual value (maybe expanded) */ 2015 2016 VarCheckSyntax(var->op, var->value, scope); 2017 if (VarAssign_Eval(var->varname, var->op, var->value, scope, &avalue)) { 2018 VarAssignSpecial(var->varname, avalue.str); 2019 FStr_Done(&avalue); 2020 } 2021 2022 free(var->varname); 2023 } 2024 2025 2026 /* 2027 * See if the command possibly calls a sub-make by using the variable 2028 * expressions ${.MAKE}, ${MAKE} or the plain word "make". 2029 */ 2030 static bool 2031 MaybeSubMake(const char *cmd) 2032 { 2033 const char *start; 2034 2035 for (start = cmd; *start != '\0'; start++) { 2036 const char *p = start; 2037 char endc; 2038 2039 /* XXX: What if progname != "make"? */ 2040 if (p[0] == 'm' && p[1] == 'a' && p[2] == 'k' && p[3] == 'e') 2041 if (start == cmd || !ch_isalnum(p[-1])) 2042 if (!ch_isalnum(p[4])) 2043 return true; 2044 2045 if (*p != '$') 2046 continue; 2047 p++; 2048 2049 if (*p == '{') 2050 endc = '}'; 2051 else if (*p == '(') 2052 endc = ')'; 2053 else 2054 continue; 2055 p++; 2056 2057 if (*p == '.') /* Accept either ${.MAKE} or ${MAKE}. */ 2058 p++; 2059 2060 if (p[0] == 'M' && p[1] == 'A' && p[2] == 'K' && p[3] == 'E') 2061 if (p[4] == endc) 2062 return true; 2063 } 2064 return false; 2065 } 2066 2067 /* 2068 * Append the command to the target node. 2069 * 2070 * The node may be marked as a submake node if the command is determined to 2071 * be that. 2072 */ 2073 static void 2074 ParseAddCmd(GNode *gn, char *cmd) 2075 { 2076 /* Add to last (ie current) cohort for :: targets */ 2077 if ((gn->type & OP_DOUBLEDEP) && gn->cohorts.last != NULL) 2078 gn = gn->cohorts.last->datum; 2079 2080 /* if target already supplied, ignore commands */ 2081 if (!(gn->type & OP_HAS_COMMANDS)) { 2082 Lst_Append(&gn->commands, cmd); 2083 if (MaybeSubMake(cmd)) 2084 gn->type |= OP_SUBMAKE; 2085 RememberLocation(gn); 2086 } else { 2087 #if 0 2088 /* XXX: We cannot do this until we fix the tree */ 2089 Lst_Append(&gn->commands, cmd); 2090 Parse_Error(PARSE_WARNING, 2091 "overriding commands for target \"%s\"; " 2092 "previous commands defined at %s: %d ignored", 2093 gn->name, gn->fname, gn->lineno); 2094 #else 2095 Parse_Error(PARSE_WARNING, 2096 "duplicate script for target \"%s\" ignored", 2097 gn->name); 2098 ParseErrorInternal(gn->fname, (size_t)gn->lineno, PARSE_WARNING, 2099 "using previous script for \"%s\" defined here", 2100 gn->name); 2101 #endif 2102 } 2103 } 2104 2105 /* 2106 * Add a directory to the path searched for included makefiles bracketed 2107 * by double-quotes. 2108 */ 2109 void 2110 Parse_AddIncludeDir(const char *dir) 2111 { 2112 (void)SearchPath_Add(parseIncPath, dir); 2113 } 2114 2115 /* 2116 * Handle one of the .[-ds]include directives by remembering the current file 2117 * and pushing the included file on the stack. After the included file has 2118 * finished, parsing continues with the including file; see Parse_SetInput 2119 * and ParseEOF. 2120 * 2121 * System includes are looked up in sysIncPath, any other includes are looked 2122 * up in the parsedir and then in the directories specified by the -I command 2123 * line options. 2124 */ 2125 static void 2126 IncludeFile(char *file, bool isSystem, bool depinc, bool silent) 2127 { 2128 struct loadedfile *lf; 2129 char *fullname; /* full pathname of file */ 2130 char *newName; 2131 char *slash, *incdir; 2132 int fd; 2133 int i; 2134 2135 fullname = file[0] == '/' ? bmake_strdup(file) : NULL; 2136 2137 if (fullname == NULL && !isSystem) { 2138 /* 2139 * Include files contained in double-quotes are first searched 2140 * relative to the including file's location. We don't want to 2141 * cd there, of course, so we just tack on the old file's 2142 * leading path components and call Dir_FindFile to see if 2143 * we can locate the file. 2144 */ 2145 2146 incdir = bmake_strdup(CurFile()->fname); 2147 slash = strrchr(incdir, '/'); 2148 if (slash != NULL) { 2149 *slash = '\0'; 2150 /* 2151 * Now do lexical processing of leading "../" on the 2152 * filename. 2153 */ 2154 for (i = 0; strncmp(file + i, "../", 3) == 0; i += 3) { 2155 slash = strrchr(incdir + 1, '/'); 2156 if (slash == NULL || strcmp(slash, "/..") == 0) 2157 break; 2158 *slash = '\0'; 2159 } 2160 newName = str_concat3(incdir, "/", file + i); 2161 fullname = Dir_FindFile(newName, parseIncPath); 2162 if (fullname == NULL) 2163 fullname = Dir_FindFile(newName, 2164 &dirSearchPath); 2165 free(newName); 2166 } 2167 free(incdir); 2168 2169 if (fullname == NULL) { 2170 /* 2171 * Makefile wasn't found in same directory as included 2172 * makefile. 2173 * 2174 * Search for it first on the -I search path, then on 2175 * the .PATH search path, if not found in a -I 2176 * directory. If we have a suffix-specific path, we 2177 * should use that. 2178 */ 2179 const char *suff; 2180 SearchPath *suffPath = NULL; 2181 2182 if ((suff = strrchr(file, '.')) != NULL) { 2183 suffPath = Suff_GetPath(suff); 2184 if (suffPath != NULL) 2185 fullname = Dir_FindFile(file, suffPath); 2186 } 2187 if (fullname == NULL) { 2188 fullname = Dir_FindFile(file, parseIncPath); 2189 if (fullname == NULL) 2190 fullname = Dir_FindFile(file, 2191 &dirSearchPath); 2192 } 2193 } 2194 } 2195 2196 /* Looking for a system file or file still not found */ 2197 if (fullname == NULL) { 2198 /* 2199 * Look for it on the system path 2200 */ 2201 SearchPath *path = Lst_IsEmpty(&sysIncPath->dirs) 2202 ? defSysIncPath : sysIncPath; 2203 fullname = Dir_FindFile(file, path); 2204 } 2205 2206 if (fullname == NULL) { 2207 if (!silent) 2208 Parse_Error(PARSE_FATAL, "Could not find %s", file); 2209 return; 2210 } 2211 2212 /* Actually open the file... */ 2213 fd = open(fullname, O_RDONLY); 2214 if (fd == -1) { 2215 if (!silent) 2216 Parse_Error(PARSE_FATAL, "Cannot open %s", fullname); 2217 free(fullname); 2218 return; 2219 } 2220 2221 /* load it */ 2222 lf = loadfile(fullname, fd); 2223 2224 /* Start reading from this file next */ 2225 Parse_SetInput(fullname, 0, -1, loadedfile_readMore, lf); 2226 CurFile()->lf = lf; 2227 if (depinc) 2228 doing_depend = depinc; /* only turn it on */ 2229 } 2230 2231 static void 2232 ParseInclude(char *directive) 2233 { 2234 char endc; /* the character which ends the file spec */ 2235 char *cp; /* current position in file spec */ 2236 bool silent = directive[0] != 'i'; 2237 char *file = directive + (silent ? 8 : 7); 2238 2239 /* Skip to delimiter character so we know where to look */ 2240 pp_skip_hspace(&file); 2241 2242 if (*file != '"' && *file != '<') { 2243 Parse_Error(PARSE_FATAL, 2244 ".include filename must be delimited by '\"' or '<'"); 2245 return; 2246 } 2247 2248 /* 2249 * Set the search path on which to find the include file based on the 2250 * characters which bracket its name. Angle-brackets imply it's 2251 * a system Makefile while double-quotes imply it's a user makefile 2252 */ 2253 if (*file == '<') 2254 endc = '>'; 2255 else 2256 endc = '"'; 2257 2258 /* Skip to matching delimiter */ 2259 for (cp = ++file; *cp != '\0' && *cp != endc; cp++) 2260 continue; 2261 2262 if (*cp != endc) { 2263 Parse_Error(PARSE_FATAL, 2264 "Unclosed .include filename. '%c' expected", endc); 2265 return; 2266 } 2267 2268 *cp = '\0'; 2269 2270 /* 2271 * Substitute for any variables in the filename before trying to 2272 * find the file. 2273 */ 2274 (void)Var_Subst(file, SCOPE_CMDLINE, VARE_WANTRES, &file); 2275 /* TODO: handle errors */ 2276 2277 IncludeFile(file, endc == '>', directive[0] == 'd', silent); 2278 free(file); 2279 } 2280 2281 /* 2282 * Split filename into dirname + basename, then assign these to the 2283 * given variables. 2284 */ 2285 static void 2286 SetFilenameVars(const char *filename, const char *dirvar, const char *filevar) 2287 { 2288 const char *slash, *basename; 2289 FStr dirname; 2290 2291 slash = strrchr(filename, '/'); 2292 if (slash == NULL) { 2293 dirname = FStr_InitRefer(curdir); 2294 basename = filename; 2295 } else { 2296 dirname = FStr_InitOwn(bmake_strsedup(filename, slash)); 2297 basename = slash + 1; 2298 } 2299 2300 Global_SetExpand(dirvar, dirname.str); 2301 Global_SetExpand(filevar, basename); 2302 2303 DEBUG5(PARSE, "%s: ${%s} = `%s' ${%s} = `%s'\n", 2304 __func__, dirvar, dirname.str, filevar, basename); 2305 FStr_Done(&dirname); 2306 } 2307 2308 /* 2309 * Return the immediately including file. 2310 * 2311 * This is made complicated since the .for loop is implemented as a special 2312 * kind of .include; see For_Run. 2313 */ 2314 static const char * 2315 GetActuallyIncludingFile(void) 2316 { 2317 size_t i; 2318 const IFile *incs = GetInclude(0); 2319 2320 for (i = includes.len; i >= 2; i--) 2321 if (!incs[i - 1].fromForLoop) 2322 return incs[i - 2].fname; 2323 return NULL; 2324 } 2325 2326 /* Set .PARSEDIR, .PARSEFILE, .INCLUDEDFROMDIR and .INCLUDEDFROMFILE. */ 2327 static void 2328 ParseSetParseFile(const char *filename) 2329 { 2330 const char *including; 2331 2332 SetFilenameVars(filename, ".PARSEDIR", ".PARSEFILE"); 2333 2334 including = GetActuallyIncludingFile(); 2335 if (including != NULL) { 2336 SetFilenameVars(including, 2337 ".INCLUDEDFROMDIR", ".INCLUDEDFROMFILE"); 2338 } else { 2339 Global_Delete(".INCLUDEDFROMDIR"); 2340 Global_Delete(".INCLUDEDFROMFILE"); 2341 } 2342 } 2343 2344 static bool 2345 StrContainsWord(const char *str, const char *word) 2346 { 2347 size_t strLen = strlen(str); 2348 size_t wordLen = strlen(word); 2349 const char *p, *end; 2350 2351 if (strLen < wordLen) 2352 return false; /* str is too short to contain word */ 2353 2354 end = str + strLen - wordLen; 2355 for (p = str; p != NULL; p = strchr(p, ' ')) { 2356 if (*p == ' ') 2357 p++; 2358 if (p > end) 2359 return false; /* cannot contain word */ 2360 2361 if (memcmp(p, word, wordLen) == 0 && 2362 (p[wordLen] == '\0' || p[wordLen] == ' ')) 2363 return true; 2364 } 2365 return false; 2366 } 2367 2368 /* 2369 * XXX: Searching through a set of words with this linear search is 2370 * inefficient for variables that contain thousands of words. 2371 * 2372 * XXX: The paths in this list don't seem to be normalized in any way. 2373 */ 2374 static bool 2375 VarContainsWord(const char *varname, const char *word) 2376 { 2377 FStr val = Var_Value(SCOPE_GLOBAL, varname); 2378 bool found = val.str != NULL && StrContainsWord(val.str, word); 2379 FStr_Done(&val); 2380 return found; 2381 } 2382 2383 /* 2384 * Track the makefiles we read - so makefiles can set dependencies on them. 2385 * Avoid adding anything more than once. 2386 * 2387 * Time complexity: O(n) per call, in total O(n^2), where n is the number 2388 * of makefiles that have been loaded. 2389 */ 2390 static void 2391 ParseTrackInput(const char *name) 2392 { 2393 if (!VarContainsWord(MAKE_MAKEFILES, name)) 2394 Global_Append(MAKE_MAKEFILES, name); 2395 } 2396 2397 2398 /* 2399 * Start parsing from the given source. 2400 * 2401 * The given file is added to the includes stack. 2402 */ 2403 void 2404 Parse_SetInput(const char *name, int lineno, int fd, 2405 ReadMoreProc readMore, void *readMoreArg) 2406 { 2407 IFile *curFile; 2408 char *buf; 2409 size_t len; 2410 bool fromForLoop = name == NULL; 2411 2412 if (fromForLoop) 2413 name = CurFile()->fname; 2414 else 2415 ParseTrackInput(name); 2416 2417 DEBUG3(PARSE, "Parse_SetInput: %s %s, line %d\n", 2418 readMore == loadedfile_readMore ? "file" : ".for loop in", 2419 name, lineno); 2420 2421 if (fd == -1 && readMore == NULL) 2422 /* sanity */ 2423 return; 2424 2425 curFile = Vector_Push(&includes); 2426 curFile->fname = bmake_strdup(name); 2427 curFile->fromForLoop = fromForLoop; 2428 curFile->lineno = lineno; 2429 curFile->first_lineno = lineno; 2430 curFile->readMore = readMore; 2431 curFile->readMoreArg = readMoreArg; 2432 curFile->lf = NULL; 2433 curFile->depending = doing_depend; /* restore this on EOF */ 2434 2435 assert(readMore != NULL); 2436 2437 /* Get first block of input data */ 2438 buf = curFile->readMore(curFile->readMoreArg, &len); 2439 if (buf == NULL) { 2440 /* Was all a waste of time ... */ 2441 if (curFile->fname != NULL) 2442 free(curFile->fname); 2443 free(curFile); 2444 return; 2445 } 2446 curFile->buf_freeIt = buf; 2447 curFile->buf_ptr = buf; 2448 curFile->buf_end = buf + len; 2449 2450 curFile->cond_depth = Cond_save_depth(); 2451 ParseSetParseFile(name); 2452 } 2453 2454 /* Check if the directive is an include directive. */ 2455 static bool 2456 IsInclude(const char *dir, bool sysv) 2457 { 2458 if (dir[0] == 's' || dir[0] == '-' || (dir[0] == 'd' && !sysv)) 2459 dir++; 2460 2461 if (strncmp(dir, "include", 7) != 0) 2462 return false; 2463 2464 /* Space is not mandatory for BSD .include */ 2465 return !sysv || ch_isspace(dir[7]); 2466 } 2467 2468 2469 #ifdef SYSVINCLUDE 2470 /* Check if the line is a SYSV include directive. */ 2471 static bool 2472 IsSysVInclude(const char *line) 2473 { 2474 const char *p; 2475 2476 if (!IsInclude(line, true)) 2477 return false; 2478 2479 /* Avoid interpreting a dependency line as an include */ 2480 for (p = line; (p = strchr(p, ':')) != NULL;) { 2481 2482 /* end of line -> it's a dependency */ 2483 if (*++p == '\0') 2484 return false; 2485 2486 /* '::' operator or ': ' -> it's a dependency */ 2487 if (*p == ':' || ch_isspace(*p)) 2488 return false; 2489 } 2490 return true; 2491 } 2492 2493 /* Push to another file. The line points to the word "include". */ 2494 static void 2495 ParseTraditionalInclude(char *line) 2496 { 2497 char *cp; /* current position in file spec */ 2498 bool done = false; 2499 bool silent = line[0] != 'i'; 2500 char *file = line + (silent ? 8 : 7); 2501 char *all_files; 2502 2503 DEBUG2(PARSE, "%s: %s\n", __func__, file); 2504 2505 pp_skip_whitespace(&file); 2506 2507 /* 2508 * Substitute for any variables in the file name before trying to 2509 * find the thing. 2510 */ 2511 (void)Var_Subst(file, SCOPE_CMDLINE, VARE_WANTRES, &all_files); 2512 /* TODO: handle errors */ 2513 2514 if (*file == '\0') { 2515 Parse_Error(PARSE_FATAL, "Filename missing from \"include\""); 2516 goto out; 2517 } 2518 2519 for (file = all_files; !done; file = cp + 1) { 2520 /* Skip to end of line or next whitespace */ 2521 for (cp = file; *cp != '\0' && !ch_isspace(*cp); cp++) 2522 continue; 2523 2524 if (*cp != '\0') 2525 *cp = '\0'; 2526 else 2527 done = true; 2528 2529 IncludeFile(file, false, false, silent); 2530 } 2531 out: 2532 free(all_files); 2533 } 2534 #endif 2535 2536 #ifdef GMAKEEXPORT 2537 /* Parse "export <variable>=<value>", and actually export it. */ 2538 static void 2539 ParseGmakeExport(char *line) 2540 { 2541 char *variable = line + 6; 2542 char *value; 2543 2544 DEBUG2(PARSE, "%s: %s\n", __func__, variable); 2545 2546 pp_skip_whitespace(&variable); 2547 2548 for (value = variable; *value != '\0' && *value != '='; value++) 2549 continue; 2550 2551 if (*value != '=') { 2552 Parse_Error(PARSE_FATAL, 2553 "Variable/Value missing from \"export\""); 2554 return; 2555 } 2556 *value++ = '\0'; /* terminate variable */ 2557 2558 /* 2559 * Expand the value before putting it in the environment. 2560 */ 2561 (void)Var_Subst(value, SCOPE_CMDLINE, VARE_WANTRES, &value); 2562 /* TODO: handle errors */ 2563 2564 setenv(variable, value, 1); 2565 free(value); 2566 } 2567 #endif 2568 2569 /* 2570 * Called when EOF is reached in the current file. If we were reading an 2571 * include file or a .for loop, the includes stack is popped and things set 2572 * up to go back to reading the previous file at the previous location. 2573 * 2574 * Results: 2575 * true to continue parsing, i.e. it had only reached the end of an 2576 * included file, false if the main file has been parsed completely. 2577 */ 2578 static bool 2579 ParseEOF(void) 2580 { 2581 char *ptr; 2582 size_t len; 2583 IFile *curFile = CurFile(); 2584 2585 assert(curFile->readMore != NULL); 2586 2587 doing_depend = curFile->depending; /* restore this */ 2588 /* get next input buffer, if any */ 2589 ptr = curFile->readMore(curFile->readMoreArg, &len); 2590 curFile->buf_ptr = ptr; 2591 curFile->buf_freeIt = ptr; 2592 curFile->buf_end = ptr == NULL ? NULL : ptr + len; 2593 curFile->lineno = curFile->first_lineno; 2594 if (ptr != NULL) 2595 return true; /* Iterate again */ 2596 2597 /* Ensure the makefile (or loop) didn't have mismatched conditionals */ 2598 Cond_restore_depth(curFile->cond_depth); 2599 2600 if (curFile->lf != NULL) { 2601 loadedfile_destroy(curFile->lf); 2602 curFile->lf = NULL; 2603 } 2604 2605 /* Dispose of curFile info */ 2606 /* Leak curFile->fname because all the GNodes have pointers to it. */ 2607 free(curFile->buf_freeIt); 2608 Vector_Pop(&includes); 2609 2610 if (includes.len == 0) { 2611 /* We've run out of input */ 2612 Global_Delete(".PARSEDIR"); 2613 Global_Delete(".PARSEFILE"); 2614 Global_Delete(".INCLUDEDFROMDIR"); 2615 Global_Delete(".INCLUDEDFROMFILE"); 2616 return false; 2617 } 2618 2619 curFile = CurFile(); 2620 DEBUG2(PARSE, "ParseEOF: returning to file %s, line %d\n", 2621 curFile->fname, curFile->lineno); 2622 2623 ParseSetParseFile(curFile->fname); 2624 return true; 2625 } 2626 2627 typedef enum ParseRawLineResult { 2628 PRLR_LINE, 2629 PRLR_EOF, 2630 PRLR_ERROR 2631 } ParseRawLineResult; 2632 2633 /* 2634 * Parse until the end of a line, taking into account lines that end with 2635 * backslash-newline. 2636 */ 2637 static ParseRawLineResult 2638 ParseRawLine(IFile *curFile, char **out_line, char **out_line_end, 2639 char **out_firstBackslash, char **out_firstComment) 2640 { 2641 char *line = curFile->buf_ptr; 2642 char *p = line; 2643 char *line_end = line; 2644 char *firstBackslash = NULL; 2645 char *firstComment = NULL; 2646 ParseRawLineResult res = PRLR_LINE; 2647 2648 curFile->lineno++; 2649 2650 for (;;) { 2651 char ch; 2652 2653 if (p == curFile->buf_end) { 2654 res = PRLR_EOF; 2655 break; 2656 } 2657 2658 ch = *p; 2659 if (ch == '\0' || 2660 (ch == '\\' && p + 1 < curFile->buf_end && p[1] == '\0')) { 2661 Parse_Error(PARSE_FATAL, "Zero byte read from file"); 2662 return PRLR_ERROR; 2663 } 2664 2665 /* Treat next character after '\' as literal. */ 2666 if (ch == '\\') { 2667 if (firstBackslash == NULL) 2668 firstBackslash = p; 2669 if (p[1] == '\n') { 2670 curFile->lineno++; 2671 if (p + 2 == curFile->buf_end) { 2672 line_end = p; 2673 *line_end = '\n'; 2674 p += 2; 2675 continue; 2676 } 2677 } 2678 p += 2; 2679 line_end = p; 2680 assert(p <= curFile->buf_end); 2681 continue; 2682 } 2683 2684 /* 2685 * Remember the first '#' for comment stripping, unless 2686 * the previous char was '[', as in the modifier ':[#]'. 2687 */ 2688 if (ch == '#' && firstComment == NULL && 2689 !(p > line && p[-1] == '[')) 2690 firstComment = line_end; 2691 2692 p++; 2693 if (ch == '\n') 2694 break; 2695 2696 /* We are not interested in trailing whitespace. */ 2697 if (!ch_isspace(ch)) 2698 line_end = p; 2699 } 2700 2701 *out_line = line; 2702 curFile->buf_ptr = p; 2703 *out_line_end = line_end; 2704 *out_firstBackslash = firstBackslash; 2705 *out_firstComment = firstComment; 2706 return res; 2707 } 2708 2709 /* 2710 * Beginning at start, unescape '\#' to '#' and replace backslash-newline 2711 * with a single space. 2712 */ 2713 static void 2714 UnescapeBackslash(char *line, char *start) 2715 { 2716 char *src = start; 2717 char *dst = start; 2718 char *spaceStart = line; 2719 2720 for (;;) { 2721 char ch = *src++; 2722 if (ch != '\\') { 2723 if (ch == '\0') 2724 break; 2725 *dst++ = ch; 2726 continue; 2727 } 2728 2729 ch = *src++; 2730 if (ch == '\0') { 2731 /* Delete '\\' at end of buffer */ 2732 dst--; 2733 break; 2734 } 2735 2736 /* Delete '\\' from before '#' on non-command lines */ 2737 if (ch == '#' && line[0] != '\t') { 2738 *dst++ = ch; 2739 continue; 2740 } 2741 2742 if (ch != '\n') { 2743 /* Leave '\\' in buffer for later */ 2744 *dst++ = '\\'; 2745 /* 2746 * Make sure we don't delete an escaped ' ' from the 2747 * line end. 2748 */ 2749 spaceStart = dst + 1; 2750 *dst++ = ch; 2751 continue; 2752 } 2753 2754 /* 2755 * Escaped '\n' -- replace following whitespace with a single 2756 * ' '. 2757 */ 2758 pp_skip_hspace(&src); 2759 *dst++ = ' '; 2760 } 2761 2762 /* Delete any trailing spaces - eg from empty continuations */ 2763 while (dst > spaceStart && ch_isspace(dst[-1])) 2764 dst--; 2765 *dst = '\0'; 2766 } 2767 2768 typedef enum GetLineMode { 2769 /* 2770 * Return the next line that is neither empty nor a comment. 2771 * Backslash line continuations are folded into a single space. 2772 * A trailing comment, if any, is discarded. 2773 */ 2774 GLM_NONEMPTY, 2775 2776 /* 2777 * Return the next line, even if it is empty or a comment. 2778 * Preserve backslash-newline to keep the line numbers correct. 2779 * 2780 * Used in .for loops to collect the body of the loop while waiting 2781 * for the corresponding .endfor. 2782 */ 2783 GLM_FOR_BODY, 2784 2785 /* 2786 * Return the next line that starts with a dot. 2787 * Backslash line continuations are folded into a single space. 2788 * A trailing comment, if any, is discarded. 2789 * 2790 * Used in .if directives to skip over irrelevant branches while 2791 * waiting for the corresponding .endif. 2792 */ 2793 GLM_DOT 2794 } GetLineMode; 2795 2796 /* Return the next "interesting" logical line from the current file. */ 2797 static char * 2798 ParseGetLine(GetLineMode mode) 2799 { 2800 IFile *curFile = CurFile(); 2801 char *line; 2802 char *line_end; 2803 char *firstBackslash; 2804 char *firstComment; 2805 2806 for (;;) { 2807 ParseRawLineResult res = ParseRawLine(curFile, 2808 &line, &line_end, &firstBackslash, &firstComment); 2809 if (res == PRLR_ERROR) 2810 return NULL; 2811 2812 if (line_end == line || firstComment == line) { 2813 if (res == PRLR_EOF) 2814 return NULL; 2815 if (mode != GLM_FOR_BODY) 2816 continue; 2817 } 2818 2819 /* We now have a line of data */ 2820 assert(ch_isspace(*line_end)); 2821 *line_end = '\0'; 2822 2823 if (mode == GLM_FOR_BODY) 2824 return line; /* Don't join the physical lines. */ 2825 2826 if (mode == GLM_DOT && line[0] != '.') 2827 continue; 2828 break; 2829 } 2830 2831 /* Brutally ignore anything after a non-escaped '#' in non-commands. */ 2832 if (firstComment != NULL && line[0] != '\t') 2833 *firstComment = '\0'; 2834 2835 /* If we didn't see a '\\' then the in-situ data is fine. */ 2836 if (firstBackslash == NULL) 2837 return line; 2838 2839 /* Remove escapes from '\n' and '#' */ 2840 UnescapeBackslash(line, firstBackslash); 2841 2842 return line; 2843 } 2844 2845 static bool 2846 ParseSkippedBranches(void) 2847 { 2848 char *line; 2849 2850 while ((line = ParseGetLine(GLM_DOT)) != NULL) { 2851 if (Cond_EvalLine(line) == COND_PARSE) 2852 break; 2853 /* 2854 * TODO: Check for typos in .elif directives 2855 * such as .elsif or .elseif. 2856 * 2857 * This check will probably duplicate some of 2858 * the code in ParseLine. Most of the code 2859 * there cannot apply, only ParseVarassign and 2860 * ParseDependencyLine can, and to prevent code 2861 * duplication, these would need to be called 2862 * with a flag called onlyCheckSyntax. 2863 * 2864 * See directive-elif.mk for details. 2865 */ 2866 } 2867 2868 return line != NULL; 2869 } 2870 2871 static bool 2872 ParseForLoop(const char *line) 2873 { 2874 int rval; 2875 int firstLineno; 2876 2877 rval = For_Eval(line); 2878 if (rval == 0) 2879 return false; /* Not a .for line */ 2880 if (rval < 0) 2881 return true; /* Syntax error - error printed, ignore line */ 2882 2883 firstLineno = CurFile()->lineno; 2884 2885 /* Accumulate loop lines until matching .endfor */ 2886 do { 2887 line = ParseGetLine(GLM_FOR_BODY); 2888 if (line == NULL) { 2889 Parse_Error(PARSE_FATAL, 2890 "Unexpected end of file in for loop."); 2891 break; 2892 } 2893 } while (For_Accum(line)); 2894 2895 For_Run(firstLineno); /* Stash each iteration as a new 'input file' */ 2896 2897 return true; /* Read next line from for-loop buffer */ 2898 } 2899 2900 /* 2901 * Read an entire line from the input file. 2902 * 2903 * Empty lines, .if and .for are completely handled by this function, 2904 * leaving only variable assignments, other directives, dependency lines 2905 * and shell commands to the caller. 2906 * 2907 * Results: 2908 * A line without its newline and without any trailing whitespace, 2909 * or NULL. 2910 */ 2911 static char * 2912 ParseReadLine(void) 2913 { 2914 char *line; 2915 2916 for (;;) { 2917 line = ParseGetLine(GLM_NONEMPTY); 2918 if (line == NULL) 2919 return NULL; 2920 2921 if (line[0] != '.') 2922 return line; 2923 2924 /* 2925 * The line might be a conditional. Ask the conditional module 2926 * about it and act accordingly 2927 */ 2928 switch (Cond_EvalLine(line)) { 2929 case COND_SKIP: 2930 if (!ParseSkippedBranches()) 2931 return NULL; 2932 continue; 2933 case COND_PARSE: 2934 continue; 2935 case COND_INVALID: /* Not a conditional line */ 2936 if (ParseForLoop(line)) 2937 continue; 2938 break; 2939 } 2940 return line; 2941 } 2942 } 2943 2944 static void 2945 FinishDependencyGroup(void) 2946 { 2947 GNodeListNode *ln; 2948 2949 if (targets == NULL) 2950 return; 2951 2952 for (ln = targets->first; ln != NULL; ln = ln->next) { 2953 GNode *gn = ln->datum; 2954 2955 Suff_EndTransform(gn); 2956 2957 /* 2958 * Mark the target as already having commands if it does, to 2959 * keep from having shell commands on multiple dependency 2960 * lines. 2961 */ 2962 if (!Lst_IsEmpty(&gn->commands)) 2963 gn->type |= OP_HAS_COMMANDS; 2964 } 2965 2966 Lst_Free(targets); 2967 targets = NULL; 2968 } 2969 2970 /* Add the command to each target from the current dependency spec. */ 2971 static void 2972 ParseLine_ShellCommand(const char *p) 2973 { 2974 cpp_skip_whitespace(&p); 2975 if (*p == '\0') 2976 return; /* skip empty commands */ 2977 2978 if (targets == NULL) { 2979 Parse_Error(PARSE_FATAL, 2980 "Unassociated shell command \"%s\"", p); 2981 return; 2982 } 2983 2984 { 2985 char *cmd = bmake_strdup(p); 2986 GNodeListNode *ln; 2987 2988 for (ln = targets->first; ln != NULL; ln = ln->next) { 2989 GNode *gn = ln->datum; 2990 ParseAddCmd(gn, cmd); 2991 } 2992 #ifdef CLEANUP 2993 Lst_Append(&targCmds, cmd); 2994 #endif 2995 } 2996 } 2997 2998 MAKE_INLINE bool 2999 IsDirective(const char *dir, size_t dirlen, const char *name) 3000 { 3001 return dirlen == strlen(name) && memcmp(dir, name, dirlen) == 0; 3002 } 3003 3004 /* 3005 * See if the line starts with one of the known directives, and if so, handle 3006 * the directive. 3007 */ 3008 static bool 3009 ParseDirective(char *line) 3010 { 3011 char *cp = line + 1; 3012 const char *dir, *arg; 3013 size_t dirlen; 3014 3015 pp_skip_whitespace(&cp); 3016 if (IsInclude(cp, false)) { 3017 ParseInclude(cp); 3018 return true; 3019 } 3020 3021 dir = cp; 3022 while (ch_isalpha(*cp) || *cp == '-') 3023 cp++; 3024 dirlen = (size_t)(cp - dir); 3025 3026 if (*cp != '\0' && !ch_isspace(*cp)) 3027 return false; 3028 3029 pp_skip_whitespace(&cp); 3030 arg = cp; 3031 3032 if (IsDirective(dir, dirlen, "undef")) { 3033 Var_Undef(cp); 3034 return true; 3035 } else if (IsDirective(dir, dirlen, "export")) { 3036 Var_Export(VEM_PLAIN, arg); 3037 return true; 3038 } else if (IsDirective(dir, dirlen, "export-env")) { 3039 Var_Export(VEM_ENV, arg); 3040 return true; 3041 } else if (IsDirective(dir, dirlen, "export-literal")) { 3042 Var_Export(VEM_LITERAL, arg); 3043 return true; 3044 } else if (IsDirective(dir, dirlen, "unexport")) { 3045 Var_UnExport(false, arg); 3046 return true; 3047 } else if (IsDirective(dir, dirlen, "unexport-env")) { 3048 Var_UnExport(true, arg); 3049 return true; 3050 } else if (IsDirective(dir, dirlen, "info")) { 3051 ParseMessage(PARSE_INFO, "info", arg); 3052 return true; 3053 } else if (IsDirective(dir, dirlen, "warning")) { 3054 ParseMessage(PARSE_WARNING, "warning", arg); 3055 return true; 3056 } else if (IsDirective(dir, dirlen, "error")) { 3057 ParseMessage(PARSE_FATAL, "error", arg); 3058 return true; 3059 } 3060 return false; 3061 } 3062 3063 static bool 3064 ParseVarassign(const char *line) 3065 { 3066 VarAssign var; 3067 3068 if (!Parse_IsVar(line, &var)) 3069 return false; 3070 3071 FinishDependencyGroup(); 3072 Parse_Var(&var, SCOPE_GLOBAL); 3073 return true; 3074 } 3075 3076 static char * 3077 FindSemicolon(char *p) 3078 { 3079 int level = 0; 3080 3081 for (; *p != '\0'; p++) { 3082 if (*p == '\\' && p[1] != '\0') { 3083 p++; 3084 continue; 3085 } 3086 3087 if (*p == '$' && (p[1] == '(' || p[1] == '{')) 3088 level++; 3089 else if (level > 0 && (*p == ')' || *p == '}')) 3090 level--; 3091 else if (level == 0 && *p == ';') 3092 break; 3093 } 3094 return p; 3095 } 3096 3097 /* 3098 * dependency -> target... op [source...] [';' command] 3099 * op -> ':' | '::' | '!' 3100 */ 3101 static void 3102 ParseDependencyLine(char *line) 3103 { 3104 VarEvalMode emode; 3105 char *expanded_line; 3106 const char *shellcmd = NULL; 3107 3108 /* 3109 * For some reason - probably to make the parser impossible - 3110 * a ';' can be used to separate commands from dependencies. 3111 * Attempt to avoid ';' inside substitution patterns. 3112 */ 3113 { 3114 char *semicolon = FindSemicolon(line); 3115 if (*semicolon != '\0') { 3116 /* Terminate the dependency list at the ';' */ 3117 *semicolon = '\0'; 3118 shellcmd = semicolon + 1; 3119 } 3120 } 3121 3122 /* 3123 * We now know it's a dependency line so it needs to have all 3124 * variables expanded before being parsed. 3125 * 3126 * XXX: Ideally the dependency line would first be split into 3127 * its left-hand side, dependency operator and right-hand side, 3128 * and then each side would be expanded on its own. This would 3129 * allow for the left-hand side to allow only defined variables 3130 * and to allow variables on the right-hand side to be undefined 3131 * as well. 3132 * 3133 * Parsing the line first would also prevent that targets 3134 * generated from variable expressions are interpreted as the 3135 * dependency operator, such as in "target${:U\:} middle: source", 3136 * in which the middle is interpreted as a source, not a target. 3137 */ 3138 3139 /* In lint mode, allow undefined variables to appear in 3140 * dependency lines. 3141 * 3142 * Ideally, only the right-hand side would allow undefined 3143 * variables since it is common to have optional dependencies. 3144 * Having undefined variables on the left-hand side is more 3145 * unusual though. Since both sides are expanded in a single 3146 * pass, there is not much choice what to do here. 3147 * 3148 * In normal mode, it does not matter whether undefined 3149 * variables are allowed or not since as of 2020-09-14, 3150 * Var_Parse does not print any parse errors in such a case. 3151 * It simply returns the special empty string var_Error, 3152 * which cannot be detected in the result of Var_Subst. */ 3153 emode = opts.strict ? VARE_WANTRES : VARE_UNDEFERR; 3154 (void)Var_Subst(line, SCOPE_CMDLINE, emode, &expanded_line); 3155 /* TODO: handle errors */ 3156 3157 /* Need a fresh list for the target nodes */ 3158 if (targets != NULL) 3159 Lst_Free(targets); 3160 targets = Lst_New(); 3161 3162 ParseDependency(expanded_line); 3163 free(expanded_line); 3164 3165 if (shellcmd != NULL) 3166 ParseLine_ShellCommand(shellcmd); 3167 } 3168 3169 static void 3170 ParseLine(char *line) 3171 { 3172 /* 3173 * Lines that begin with '.' can be pretty much anything: 3174 * - directives like '.include' or '.if', 3175 * - suffix rules like '.c.o:', 3176 * - dependencies for filenames that start with '.', 3177 * - variable assignments like '.tmp=value'. 3178 */ 3179 if (line[0] == '.' && ParseDirective(line)) 3180 return; 3181 3182 if (line[0] == '\t') { 3183 ParseLine_ShellCommand(line + 1); 3184 return; 3185 } 3186 3187 #ifdef SYSVINCLUDE 3188 if (IsSysVInclude(line)) { 3189 /* 3190 * It's an S3/S5-style "include". 3191 */ 3192 ParseTraditionalInclude(line); 3193 return; 3194 } 3195 #endif 3196 3197 #ifdef GMAKEEXPORT 3198 if (strncmp(line, "export", 6) == 0 && ch_isspace(line[6]) && 3199 strchr(line, ':') == NULL) { 3200 /* 3201 * It's a Gmake "export". 3202 */ 3203 ParseGmakeExport(line); 3204 return; 3205 } 3206 #endif 3207 3208 if (ParseVarassign(line)) 3209 return; 3210 3211 FinishDependencyGroup(); 3212 3213 ParseDependencyLine(line); 3214 } 3215 3216 /* 3217 * Parse a top-level makefile, incorporating its content into the global 3218 * dependency graph. 3219 * 3220 * Input: 3221 * name The name of the file being read 3222 * fd The open file to parse; will be closed at the end 3223 */ 3224 void 3225 Parse_File(const char *name, int fd) 3226 { 3227 char *line; /* the line we're working on */ 3228 struct loadedfile *lf; 3229 3230 lf = loadfile(name, fd); 3231 3232 assert(targets == NULL); 3233 3234 if (name == NULL) 3235 name = "(stdin)"; 3236 3237 Parse_SetInput(name, 0, -1, loadedfile_readMore, lf); 3238 CurFile()->lf = lf; 3239 3240 do { 3241 while ((line = ParseReadLine()) != NULL) { 3242 DEBUG2(PARSE, "ParseReadLine (%d): '%s'\n", 3243 CurFile()->lineno, line); 3244 ParseLine(line); 3245 } 3246 /* Reached EOF, but it may be just EOF of an include file. */ 3247 } while (ParseEOF()); 3248 3249 FinishDependencyGroup(); 3250 3251 if (parseErrors != 0) { 3252 (void)fflush(stdout); 3253 (void)fprintf(stderr, 3254 "%s: Fatal errors encountered -- cannot continue", 3255 progname); 3256 PrintOnError(NULL, NULL); 3257 exit(1); 3258 } 3259 } 3260 3261 /* Initialize the parsing module. */ 3262 void 3263 Parse_Init(void) 3264 { 3265 mainNode = NULL; 3266 parseIncPath = SearchPath_New(); 3267 sysIncPath = SearchPath_New(); 3268 defSysIncPath = SearchPath_New(); 3269 Vector_Init(&includes, sizeof(IFile)); 3270 } 3271 3272 /* Clean up the parsing module. */ 3273 void 3274 Parse_End(void) 3275 { 3276 #ifdef CLEANUP 3277 Lst_DoneCall(&targCmds, free); 3278 assert(targets == NULL); 3279 SearchPath_Free(defSysIncPath); 3280 SearchPath_Free(sysIncPath); 3281 SearchPath_Free(parseIncPath); 3282 assert(includes.len == 0); 3283 Vector_Done(&includes); 3284 #endif 3285 } 3286 3287 3288 /* 3289 * Return a list containing the single main target to create. 3290 * If no such target exists, we Punt with an obnoxious error message. 3291 */ 3292 void 3293 Parse_MainName(GNodeList *mainList) 3294 { 3295 if (mainNode == NULL) 3296 Punt("no target to make."); 3297 3298 Lst_Append(mainList, mainNode); 3299 if (mainNode->type & OP_DOUBLEDEP) 3300 Lst_AppendAll(mainList, &mainNode->cohorts); 3301 3302 Global_Append(".TARGETS", mainNode->name); 3303 } 3304 3305 int 3306 Parse_NumErrors(void) 3307 { 3308 return parseErrors; 3309 } 3310