1 /* $NetBSD: parse.c,v 1.563 2021/08/14 13:39:43 rillig Exp $ */ 2 3 /* 4 * Copyright (c) 1988, 1989, 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Adam de Boor. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 /* 36 * Copyright (c) 1989 by Berkeley Softworks 37 * All rights reserved. 38 * 39 * This code is derived from software contributed to Berkeley by 40 * Adam de Boor. 41 * 42 * Redistribution and use in source and binary forms, with or without 43 * modification, are permitted provided that the following conditions 44 * are met: 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 2. Redistributions in binary form must reproduce the above copyright 48 * notice, this list of conditions and the following disclaimer in the 49 * documentation and/or other materials provided with the distribution. 50 * 3. All advertising materials mentioning features or use of this software 51 * must display the following acknowledgement: 52 * This product includes software developed by the University of 53 * California, Berkeley and its contributors. 54 * 4. Neither the name of the University nor the names of its contributors 55 * may be used to endorse or promote products derived from this software 56 * without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 */ 70 71 /* 72 * Parsing of makefiles. 73 * 74 * Parse_File is the main entry point and controls most of the other 75 * functions in this module. 76 * 77 * The directories for the .include "..." directive are kept in 78 * 'parseIncPath', while those for .include <...> are kept in 'sysIncPath'. 79 * The targets currently being defined are kept in 'targets'. 80 * 81 * Interface: 82 * Parse_Init Initialize the module 83 * 84 * Parse_End Clean up the module 85 * 86 * Parse_File Parse a top-level makefile. Included files are 87 * handled by IncludeFile instead. 88 * 89 * Parse_IsVar Return true if the given line is a variable 90 * assignment. Used by MainParseArgs to determine if 91 * an argument is a target or a variable assignment. 92 * Used internally for pretty much the same thing. 93 * 94 * Parse_Error Report a parse error, a warning or an informational 95 * message. 96 * 97 * Parse_MainName Returns a list of the main target to create. 98 */ 99 100 #include <sys/types.h> 101 #include <sys/stat.h> 102 #include <errno.h> 103 #include <stdarg.h> 104 #include <stdint.h> 105 106 #include "make.h" 107 #include "dir.h" 108 #include "job.h" 109 #include "pathnames.h" 110 111 /* "@(#)parse.c 8.3 (Berkeley) 3/19/94" */ 112 MAKE_RCSID("$NetBSD: parse.c,v 1.563 2021/08/14 13:39:43 rillig Exp $"); 113 114 /* types and constants */ 115 116 /* 117 * Structure for a file being read ("included file") 118 */ 119 typedef struct IFile { 120 char *fname; /* name of file (relative? absolute?) */ 121 bool fromForLoop; /* simulated .include by the .for loop */ 122 int lineno; /* current line number in file */ 123 int first_lineno; /* line number of start of text */ 124 unsigned int cond_depth; /* 'if' nesting when file opened */ 125 bool depending; /* state of doing_depend on EOF */ 126 127 /* The buffer from which the file's content is read. */ 128 char *buf_freeIt; 129 char *buf_ptr; /* next char to be read */ 130 char *buf_end; 131 132 /* Function to read more data, with a single opaque argument. */ 133 ReadMoreProc readMore; 134 void *readMoreArg; 135 136 struct loadedfile *lf; /* loadedfile object, if any */ 137 } IFile; 138 139 /* 140 * Tokens for target attributes 141 */ 142 typedef enum ParseSpecial { 143 SP_ATTRIBUTE, /* Generic attribute */ 144 SP_BEGIN, /* .BEGIN */ 145 SP_DEFAULT, /* .DEFAULT */ 146 SP_DELETE_ON_ERROR, /* .DELETE_ON_ERROR */ 147 SP_END, /* .END */ 148 SP_ERROR, /* .ERROR */ 149 SP_IGNORE, /* .IGNORE */ 150 SP_INCLUDES, /* .INCLUDES; not mentioned in the manual page */ 151 SP_INTERRUPT, /* .INTERRUPT */ 152 SP_LIBS, /* .LIBS; not mentioned in the manual page */ 153 /* .MAIN and we don't have anything user-specified to make */ 154 SP_MAIN, 155 SP_META, /* .META */ 156 SP_MFLAGS, /* .MFLAGS or .MAKEFLAGS */ 157 SP_NOMETA, /* .NOMETA */ 158 SP_NOMETA_CMP, /* .NOMETA_CMP */ 159 SP_NOPATH, /* .NOPATH */ 160 SP_NOT, /* Not special */ 161 SP_NOTPARALLEL, /* .NOTPARALLEL or .NO_PARALLEL */ 162 SP_NULL, /* .NULL; not mentioned in the manual page */ 163 SP_OBJDIR, /* .OBJDIR */ 164 SP_ORDER, /* .ORDER */ 165 SP_PARALLEL, /* .PARALLEL; not mentioned in the manual page */ 166 SP_PATH, /* .PATH or .PATH.suffix */ 167 SP_PHONY, /* .PHONY */ 168 #ifdef POSIX 169 SP_POSIX, /* .POSIX; not mentioned in the manual page */ 170 #endif 171 SP_PRECIOUS, /* .PRECIOUS */ 172 SP_SHELL, /* .SHELL */ 173 SP_SILENT, /* .SILENT */ 174 SP_SINGLESHELL, /* .SINGLESHELL; not mentioned in the manual page */ 175 SP_STALE, /* .STALE */ 176 SP_SUFFIXES, /* .SUFFIXES */ 177 SP_WAIT /* .WAIT */ 178 } ParseSpecial; 179 180 typedef List SearchPathList; 181 typedef ListNode SearchPathListNode; 182 183 /* result data */ 184 185 /* 186 * The main target to create. This is the first target on the first 187 * dependency line in the first makefile. 188 */ 189 static GNode *mainNode; 190 191 /* eval state */ 192 193 /* 194 * During parsing, the targets from the left-hand side of the currently 195 * active dependency line, or NULL if the current line does not belong to a 196 * dependency line, for example because it is a variable assignment. 197 * 198 * See unit-tests/deptgt.mk, keyword "parse.c:targets". 199 */ 200 static GNodeList *targets; 201 202 #ifdef CLEANUP 203 /* 204 * All shell commands for all targets, in no particular order and possibly 205 * with duplicates. Kept in a separate list since the commands from .USE or 206 * .USEBEFORE nodes are shared with other GNodes, thereby giving up the 207 * easily understandable ownership over the allocated strings. 208 */ 209 static StringList targCmds = LST_INIT; 210 #endif 211 212 /* 213 * Predecessor node for handling .ORDER. Initialized to NULL when .ORDER 214 * seen, then set to each successive source on the line. 215 */ 216 static GNode *order_pred; 217 218 /* parser state */ 219 220 /* number of fatal errors */ 221 static int 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; /* 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 *const line, char *const cp, 1601 GNodeType const tOp, 1602 ParseSpecial const specType, 1603 SearchPathList ** inout_paths) 1604 { 1605 if (line[0] == '\0') { 1606 ParseDependencySourcesEmpty(specType, *inout_paths); 1607 } else if (specType == SP_MFLAGS) { 1608 Main_ParseArgLine(line); 1609 /* 1610 * Set the initial character to a null-character so the loop 1611 * to get sources won't get anything. 1612 */ 1613 *line = '\0'; 1614 } else if (specType == SP_SHELL) { 1615 if (!Job_ParseShell(line)) { 1616 Parse_Error(PARSE_FATAL, 1617 "improper shell specification"); 1618 return; 1619 } 1620 *line = '\0'; 1621 } else if (specType == SP_NOTPARALLEL || specType == SP_SINGLESHELL || 1622 specType == SP_DELETE_ON_ERROR) { 1623 *line = '\0'; 1624 } 1625 1626 /* Now go for the sources. */ 1627 if (specType == SP_SUFFIXES || specType == SP_PATH || 1628 specType == SP_INCLUDES || specType == SP_LIBS || 1629 specType == SP_NULL || specType == SP_OBJDIR) { 1630 ParseDependencySourcesSpecial(line, cp, specType, 1631 *inout_paths); 1632 if (*inout_paths != NULL) { 1633 Lst_Free(*inout_paths); 1634 *inout_paths = NULL; 1635 } 1636 if (specType == SP_PATH) 1637 Dir_SetPATH(); 1638 } else { 1639 assert(*inout_paths == NULL); 1640 if (!ParseDependencySourcesMundane(line, cp, specType, tOp)) 1641 return; 1642 } 1643 1644 FindMainTarget(); 1645 } 1646 1647 /* 1648 * Parse a dependency line consisting of targets, followed by a dependency 1649 * operator, optionally followed by sources. 1650 * 1651 * The nodes of the sources are linked as children to the nodes of the 1652 * targets. Nodes are created as necessary. 1653 * 1654 * The operator is applied to each node in the global 'targets' list, 1655 * which is where the nodes found for the targets are kept, by means of 1656 * the ParseOp function. 1657 * 1658 * The sources are parsed in much the same way as the targets, except 1659 * that they are expanded using the wildcarding scheme of the C-Shell, 1660 * and a target is created for each expanded word. Each of the resulting 1661 * nodes is then linked to each of the targets as one of its children. 1662 * 1663 * Certain targets and sources such as .PHONY or .PRECIOUS are handled 1664 * specially. These are the ones detailed by the specType variable. 1665 * 1666 * The storing of transformation rules such as '.c.o' is also taken care of 1667 * here. A target is recognized as a transformation rule by calling 1668 * Suff_IsTransform. If it is a transformation rule, its node is gotten 1669 * from the suffix module via Suff_AddTransform rather than the standard 1670 * Targ_FindNode in the target module. 1671 * 1672 * Upon return, the value of the line is unspecified. 1673 */ 1674 static void 1675 ParseDependency(char *line) 1676 { 1677 char *cp; /* our current position */ 1678 GNodeType op; /* the operator on the line */ 1679 SearchPathList *paths; /* search paths to alter when parsing 1680 * a list of .PATH targets */ 1681 GNodeType tOp; /* operator from special target */ 1682 /* target names to be found and added to the targets list */ 1683 StringList curTargs = LST_INIT; 1684 char *lstart = line; 1685 1686 /* 1687 * specType contains the SPECial TYPE of the current target. It is 1688 * SP_NOT if the target is unspecial. If it *is* special, however, the 1689 * children are linked as children of the parent but not vice versa. 1690 */ 1691 ParseSpecial specType = SP_NOT; 1692 1693 DEBUG1(PARSE, "ParseDependency(%s)\n", line); 1694 tOp = OP_NONE; 1695 1696 paths = NULL; 1697 1698 /* 1699 * First, grind through the targets. 1700 */ 1701 /* XXX: don't use 'line' as an iterator variable */ 1702 if (!ParseDependencyTargets(&cp, &line, lstart, &specType, &tOp, 1703 &paths, &curTargs)) 1704 goto out; 1705 1706 /* 1707 * Don't need the list of target names anymore. 1708 * The targets themselves are now in the global variable 'targets'. 1709 */ 1710 Lst_Done(&curTargs); 1711 Lst_Init(&curTargs); 1712 1713 if (!Lst_IsEmpty(targets)) 1714 ParseDependencyCheckSpec(specType); 1715 1716 /* 1717 * Have now parsed all the target names. Must parse the operator next. 1718 */ 1719 if (!ParseDependencyOp(&cp, lstart, &op)) 1720 goto out; 1721 1722 /* 1723 * Apply the operator to the target. This is how we remember which 1724 * operator a target was defined with. It fails if the operator 1725 * used isn't consistent across all references. 1726 */ 1727 ApplyDependencyOperator(op); 1728 1729 /* 1730 * Onward to the sources. 1731 * 1732 * LINE will now point to the first source word, if any, or the 1733 * end of the string if not. 1734 */ 1735 pp_skip_whitespace(&cp); 1736 line = cp; /* XXX: 'line' is an inappropriate name */ 1737 1738 ParseDependencySources(line, cp, tOp, specType, &paths); 1739 1740 out: 1741 if (paths != NULL) 1742 Lst_Free(paths); 1743 Lst_Done(&curTargs); 1744 } 1745 1746 typedef struct VarAssignParsed { 1747 const char *nameStart; /* unexpanded */ 1748 const char *nameEnd; /* before operator adjustment */ 1749 const char *eq; /* the '=' of the assignment operator */ 1750 } VarAssignParsed; 1751 1752 /* 1753 * Determine the assignment operator and adjust the end of the variable 1754 * name accordingly. 1755 */ 1756 static void 1757 AdjustVarassignOp(const VarAssignParsed *pvar, const char *value, 1758 VarAssign *out_var) 1759 { 1760 const char *op = pvar->eq; 1761 const char *const name = pvar->nameStart; 1762 VarAssignOp type; 1763 1764 if (op > name && op[-1] == '+') { 1765 type = VAR_APPEND; 1766 op--; 1767 1768 } else if (op > name && op[-1] == '?') { 1769 op--; 1770 type = VAR_DEFAULT; 1771 1772 } else if (op > name && op[-1] == ':') { 1773 op--; 1774 type = VAR_SUBST; 1775 1776 } else if (op > name && op[-1] == '!') { 1777 op--; 1778 type = VAR_SHELL; 1779 1780 } else { 1781 type = VAR_NORMAL; 1782 #ifdef SUNSHCMD 1783 while (op > name && ch_isspace(op[-1])) 1784 op--; 1785 1786 if (op >= name + 3 && op[-3] == ':' && op[-2] == 's' && 1787 op[-1] == 'h') { 1788 type = VAR_SHELL; 1789 op -= 3; 1790 } 1791 #endif 1792 } 1793 1794 { 1795 const char *nameEnd = pvar->nameEnd < op ? pvar->nameEnd : op; 1796 out_var->varname = bmake_strsedup(pvar->nameStart, nameEnd); 1797 out_var->op = type; 1798 out_var->value = value; 1799 } 1800 } 1801 1802 /* 1803 * Parse a variable assignment, consisting of a single-word variable name, 1804 * optional whitespace, an assignment operator, optional whitespace and the 1805 * variable value. 1806 * 1807 * Note: There is a lexical ambiguity with assignment modifier characters 1808 * in variable names. This routine interprets the character before the = 1809 * as a modifier. Therefore, an assignment like 1810 * C++=/usr/bin/CC 1811 * is interpreted as "C+ +=" instead of "C++ =". 1812 * 1813 * Used for both lines in a file and command line arguments. 1814 */ 1815 bool 1816 Parse_IsVar(const char *p, VarAssign *out_var) 1817 { 1818 VarAssignParsed pvar; 1819 const char *firstSpace = NULL; 1820 int level = 0; 1821 1822 cpp_skip_hspace(&p); /* Skip to variable name */ 1823 1824 /* 1825 * During parsing, the '+' of the '+=' operator is initially parsed 1826 * as part of the variable name. It is later corrected, as is the 1827 * ':sh' modifier. Of these two (nameEnd and op), the earlier one 1828 * determines the actual end of the variable name. 1829 */ 1830 pvar.nameStart = p; 1831 #ifdef CLEANUP 1832 pvar.nameEnd = NULL; 1833 pvar.eq = NULL; 1834 #endif 1835 1836 /* 1837 * Scan for one of the assignment operators outside a variable 1838 * expansion. 1839 */ 1840 while (*p != '\0') { 1841 char ch = *p++; 1842 if (ch == '(' || ch == '{') { 1843 level++; 1844 continue; 1845 } 1846 if (ch == ')' || ch == '}') { 1847 level--; 1848 continue; 1849 } 1850 1851 if (level != 0) 1852 continue; 1853 1854 if (ch == ' ' || ch == '\t') 1855 if (firstSpace == NULL) 1856 firstSpace = p - 1; 1857 while (ch == ' ' || ch == '\t') 1858 ch = *p++; 1859 1860 #ifdef SUNSHCMD 1861 if (ch == ':' && p[0] == 's' && p[1] == 'h') { 1862 p += 2; 1863 continue; 1864 } 1865 #endif 1866 if (ch == '=') { 1867 pvar.eq = p - 1; 1868 pvar.nameEnd = firstSpace != NULL ? firstSpace : p - 1; 1869 cpp_skip_whitespace(&p); 1870 AdjustVarassignOp(&pvar, p, out_var); 1871 return true; 1872 } 1873 if (*p == '=' && 1874 (ch == '+' || ch == ':' || ch == '?' || ch == '!')) { 1875 pvar.eq = p; 1876 pvar.nameEnd = firstSpace != NULL ? firstSpace : p; 1877 p++; 1878 cpp_skip_whitespace(&p); 1879 AdjustVarassignOp(&pvar, p, out_var); 1880 return true; 1881 } 1882 if (firstSpace != NULL) 1883 return false; 1884 } 1885 1886 return false; 1887 } 1888 1889 /* 1890 * Check for syntax errors such as unclosed expressions or unknown modifiers. 1891 */ 1892 static void 1893 VarCheckSyntax(VarAssignOp type, const char *uvalue, GNode *scope) 1894 { 1895 if (opts.strict) { 1896 if (type != VAR_SUBST && strchr(uvalue, '$') != NULL) { 1897 char *expandedValue; 1898 1899 (void)Var_Subst(uvalue, scope, VARE_PARSE_ONLY, 1900 &expandedValue); 1901 /* TODO: handle errors */ 1902 free(expandedValue); 1903 } 1904 } 1905 } 1906 1907 static void 1908 VarAssign_EvalSubst(GNode *scope, const char *name, const char *uvalue, 1909 FStr *out_avalue) 1910 { 1911 char *evalue; 1912 1913 /* 1914 * make sure that we set the variable the first time to nothing 1915 * so that it gets substituted. 1916 * 1917 * TODO: Add a test that demonstrates why this code is needed, 1918 * apart from making the debug log longer. 1919 */ 1920 if (!Var_ExistsExpand(scope, name)) 1921 Var_SetExpand(scope, name, ""); 1922 1923 (void)Var_Subst(uvalue, scope, VARE_KEEP_DOLLAR_UNDEF, &evalue); 1924 /* TODO: handle errors */ 1925 1926 Var_SetExpand(scope, name, evalue); 1927 1928 *out_avalue = FStr_InitOwn(evalue); 1929 } 1930 1931 static void 1932 VarAssign_EvalShell(const char *name, const char *uvalue, GNode *scope, 1933 FStr *out_avalue) 1934 { 1935 FStr cmd; 1936 const char *errfmt; 1937 char *cmdOut; 1938 1939 cmd = FStr_InitRefer(uvalue); 1940 if (strchr(cmd.str, '$') != NULL) { 1941 char *expanded; 1942 (void)Var_Subst(cmd.str, SCOPE_CMDLINE, VARE_UNDEFERR, 1943 &expanded); 1944 /* TODO: handle errors */ 1945 cmd = FStr_InitOwn(expanded); 1946 } 1947 1948 cmdOut = Cmd_Exec(cmd.str, &errfmt); 1949 Var_SetExpand(scope, name, cmdOut); 1950 *out_avalue = FStr_InitOwn(cmdOut); 1951 1952 if (errfmt != NULL) 1953 Parse_Error(PARSE_WARNING, errfmt, cmd.str); 1954 1955 FStr_Done(&cmd); 1956 } 1957 1958 /* 1959 * Perform a variable assignment. 1960 * 1961 * The actual value of the variable is returned in *out_true_avalue. 1962 * Especially for VAR_SUBST and VAR_SHELL this can differ from the literal 1963 * value. 1964 * 1965 * Return whether the assignment was actually performed, which is usually 1966 * the case. It is only skipped if the operator is '?=' and the variable 1967 * already exists. 1968 */ 1969 static bool 1970 VarAssign_Eval(const char *name, VarAssignOp op, const char *uvalue, 1971 GNode *scope, FStr *out_true_avalue) 1972 { 1973 FStr avalue = FStr_InitRefer(uvalue); 1974 1975 if (op == VAR_APPEND) 1976 Var_AppendExpand(scope, name, uvalue); 1977 else if (op == VAR_SUBST) 1978 VarAssign_EvalSubst(scope, name, uvalue, &avalue); 1979 else if (op == VAR_SHELL) 1980 VarAssign_EvalShell(name, uvalue, scope, &avalue); 1981 else { 1982 if (op == VAR_DEFAULT && Var_ExistsExpand(scope, name)) 1983 return false; 1984 1985 /* Normal assignment -- just do it. */ 1986 Var_SetExpand(scope, name, uvalue); 1987 } 1988 1989 *out_true_avalue = avalue; 1990 return true; 1991 } 1992 1993 static void 1994 VarAssignSpecial(const char *name, const char *avalue) 1995 { 1996 if (strcmp(name, MAKEOVERRIDES) == 0) 1997 Main_ExportMAKEFLAGS(false); /* re-export MAKEFLAGS */ 1998 else if (strcmp(name, ".CURDIR") == 0) { 1999 /* 2000 * Someone is being (too?) clever... 2001 * Let's pretend they know what they are doing and 2002 * re-initialize the 'cur' CachedDir. 2003 */ 2004 Dir_InitCur(avalue); 2005 Dir_SetPATH(); 2006 } else if (strcmp(name, MAKE_JOB_PREFIX) == 0) 2007 Job_SetPrefix(); 2008 else if (strcmp(name, MAKE_EXPORTED) == 0) 2009 Var_ExportVars(avalue); 2010 } 2011 2012 /* Perform the variable variable assignment in the given scope. */ 2013 void 2014 Parse_Var(VarAssign *var, GNode *scope) 2015 { 2016 FStr avalue; /* actual value (maybe expanded) */ 2017 2018 VarCheckSyntax(var->op, var->value, scope); 2019 if (VarAssign_Eval(var->varname, var->op, var->value, scope, &avalue)) { 2020 VarAssignSpecial(var->varname, avalue.str); 2021 FStr_Done(&avalue); 2022 } 2023 2024 free(var->varname); 2025 } 2026 2027 2028 /* 2029 * See if the command possibly calls a sub-make by using the variable 2030 * expressions ${.MAKE}, ${MAKE} or the plain word "make". 2031 */ 2032 static bool 2033 MaybeSubMake(const char *cmd) 2034 { 2035 const char *start; 2036 2037 for (start = cmd; *start != '\0'; start++) { 2038 const char *p = start; 2039 char endc; 2040 2041 /* XXX: What if progname != "make"? */ 2042 if (p[0] == 'm' && p[1] == 'a' && p[2] == 'k' && p[3] == 'e') 2043 if (start == cmd || !ch_isalnum(p[-1])) 2044 if (!ch_isalnum(p[4])) 2045 return true; 2046 2047 if (*p != '$') 2048 continue; 2049 p++; 2050 2051 if (*p == '{') 2052 endc = '}'; 2053 else if (*p == '(') 2054 endc = ')'; 2055 else 2056 continue; 2057 p++; 2058 2059 if (*p == '.') /* Accept either ${.MAKE} or ${MAKE}. */ 2060 p++; 2061 2062 if (p[0] == 'M' && p[1] == 'A' && p[2] == 'K' && p[3] == 'E') 2063 if (p[4] == endc) 2064 return true; 2065 } 2066 return false; 2067 } 2068 2069 /* 2070 * Append the command to the target node. 2071 * 2072 * The node may be marked as a submake node if the command is determined to 2073 * be that. 2074 */ 2075 static void 2076 ParseAddCmd(GNode *gn, char *cmd) 2077 { 2078 /* Add to last (ie current) cohort for :: targets */ 2079 if ((gn->type & OP_DOUBLEDEP) && gn->cohorts.last != NULL) 2080 gn = gn->cohorts.last->datum; 2081 2082 /* if target already supplied, ignore commands */ 2083 if (!(gn->type & OP_HAS_COMMANDS)) { 2084 Lst_Append(&gn->commands, cmd); 2085 if (MaybeSubMake(cmd)) 2086 gn->type |= OP_SUBMAKE; 2087 RememberLocation(gn); 2088 } else { 2089 #if 0 2090 /* XXX: We cannot do this until we fix the tree */ 2091 Lst_Append(&gn->commands, cmd); 2092 Parse_Error(PARSE_WARNING, 2093 "overriding commands for target \"%s\"; " 2094 "previous commands defined at %s: %d ignored", 2095 gn->name, gn->fname, gn->lineno); 2096 #else 2097 Parse_Error(PARSE_WARNING, 2098 "duplicate script for target \"%s\" ignored", 2099 gn->name); 2100 ParseErrorInternal(gn->fname, (size_t)gn->lineno, PARSE_WARNING, 2101 "using previous script for \"%s\" defined here", 2102 gn->name); 2103 #endif 2104 } 2105 } 2106 2107 /* 2108 * Add a directory to the path searched for included makefiles bracketed 2109 * by double-quotes. 2110 */ 2111 void 2112 Parse_AddIncludeDir(const char *dir) 2113 { 2114 (void)SearchPath_Add(parseIncPath, dir); 2115 } 2116 2117 /* 2118 * Handle one of the .[-ds]include directives by remembering the current file 2119 * and pushing the included file on the stack. After the included file has 2120 * finished, parsing continues with the including file; see Parse_SetInput 2121 * and ParseEOF. 2122 * 2123 * System includes are looked up in sysIncPath, any other includes are looked 2124 * up in the parsedir and then in the directories specified by the -I command 2125 * line options. 2126 */ 2127 static void 2128 IncludeFile(char *file, bool isSystem, bool depinc, bool silent) 2129 { 2130 struct loadedfile *lf; 2131 char *fullname; /* full pathname of file */ 2132 char *newName; 2133 char *slash, *incdir; 2134 int fd; 2135 int i; 2136 2137 fullname = file[0] == '/' ? bmake_strdup(file) : NULL; 2138 2139 if (fullname == NULL && !isSystem) { 2140 /* 2141 * Include files contained in double-quotes are first searched 2142 * relative to the including file's location. We don't want to 2143 * cd there, of course, so we just tack on the old file's 2144 * leading path components and call Dir_FindFile to see if 2145 * we can locate the file. 2146 */ 2147 2148 incdir = bmake_strdup(CurFile()->fname); 2149 slash = strrchr(incdir, '/'); 2150 if (slash != NULL) { 2151 *slash = '\0'; 2152 /* 2153 * Now do lexical processing of leading "../" on the 2154 * filename. 2155 */ 2156 for (i = 0; strncmp(file + i, "../", 3) == 0; i += 3) { 2157 slash = strrchr(incdir + 1, '/'); 2158 if (slash == NULL || strcmp(slash, "/..") == 0) 2159 break; 2160 *slash = '\0'; 2161 } 2162 newName = str_concat3(incdir, "/", file + i); 2163 fullname = Dir_FindFile(newName, parseIncPath); 2164 if (fullname == NULL) 2165 fullname = Dir_FindFile(newName, 2166 &dirSearchPath); 2167 free(newName); 2168 } 2169 free(incdir); 2170 2171 if (fullname == NULL) { 2172 /* 2173 * Makefile wasn't found in same directory as included 2174 * makefile. 2175 * 2176 * Search for it first on the -I search path, then on 2177 * the .PATH search path, if not found in a -I 2178 * directory. If we have a suffix-specific path, we 2179 * should use that. 2180 */ 2181 const char *suff; 2182 SearchPath *suffPath = NULL; 2183 2184 if ((suff = strrchr(file, '.')) != NULL) { 2185 suffPath = Suff_GetPath(suff); 2186 if (suffPath != NULL) 2187 fullname = Dir_FindFile(file, suffPath); 2188 } 2189 if (fullname == NULL) { 2190 fullname = Dir_FindFile(file, parseIncPath); 2191 if (fullname == NULL) 2192 fullname = Dir_FindFile(file, 2193 &dirSearchPath); 2194 } 2195 } 2196 } 2197 2198 /* Looking for a system file or file still not found */ 2199 if (fullname == NULL) { 2200 /* 2201 * Look for it on the system path 2202 */ 2203 SearchPath *path = Lst_IsEmpty(&sysIncPath->dirs) 2204 ? defSysIncPath : sysIncPath; 2205 fullname = Dir_FindFile(file, path); 2206 } 2207 2208 if (fullname == NULL) { 2209 if (!silent) 2210 Parse_Error(PARSE_FATAL, "Could not find %s", file); 2211 return; 2212 } 2213 2214 /* Actually open the file... */ 2215 fd = open(fullname, O_RDONLY); 2216 if (fd == -1) { 2217 if (!silent) 2218 Parse_Error(PARSE_FATAL, "Cannot open %s", fullname); 2219 free(fullname); 2220 return; 2221 } 2222 2223 /* load it */ 2224 lf = loadfile(fullname, fd); 2225 2226 /* Start reading from this file next */ 2227 Parse_SetInput(fullname, 0, -1, loadedfile_readMore, lf); 2228 CurFile()->lf = lf; 2229 if (depinc) 2230 doing_depend = depinc; /* only turn it on */ 2231 } 2232 2233 static void 2234 ParseInclude(char *directive) 2235 { 2236 char endc; /* the character which ends the file spec */ 2237 char *cp; /* current position in file spec */ 2238 bool silent = directive[0] != 'i'; 2239 char *file = directive + (silent ? 8 : 7); 2240 2241 /* Skip to delimiter character so we know where to look */ 2242 pp_skip_hspace(&file); 2243 2244 if (*file != '"' && *file != '<') { 2245 Parse_Error(PARSE_FATAL, 2246 ".include filename must be delimited by '\"' or '<'"); 2247 return; 2248 } 2249 2250 /* 2251 * Set the search path on which to find the include file based on the 2252 * characters which bracket its name. Angle-brackets imply it's 2253 * a system Makefile while double-quotes imply it's a user makefile 2254 */ 2255 if (*file == '<') 2256 endc = '>'; 2257 else 2258 endc = '"'; 2259 2260 /* Skip to matching delimiter */ 2261 for (cp = ++file; *cp != '\0' && *cp != endc; cp++) 2262 continue; 2263 2264 if (*cp != endc) { 2265 Parse_Error(PARSE_FATAL, 2266 "Unclosed .include filename. '%c' expected", endc); 2267 return; 2268 } 2269 2270 *cp = '\0'; 2271 2272 /* 2273 * Substitute for any variables in the filename before trying to 2274 * find the file. 2275 */ 2276 (void)Var_Subst(file, SCOPE_CMDLINE, VARE_WANTRES, &file); 2277 /* TODO: handle errors */ 2278 2279 IncludeFile(file, endc == '>', directive[0] == 'd', silent); 2280 free(file); 2281 } 2282 2283 /* 2284 * Split filename into dirname + basename, then assign these to the 2285 * given variables. 2286 */ 2287 static void 2288 SetFilenameVars(const char *filename, const char *dirvar, const char *filevar) 2289 { 2290 const char *slash, *basename; 2291 FStr dirname; 2292 2293 slash = strrchr(filename, '/'); 2294 if (slash == NULL) { 2295 dirname = FStr_InitRefer(curdir); 2296 basename = filename; 2297 } else { 2298 dirname = FStr_InitOwn(bmake_strsedup(filename, slash)); 2299 basename = slash + 1; 2300 } 2301 2302 Global_SetExpand(dirvar, dirname.str); 2303 Global_SetExpand(filevar, basename); 2304 2305 DEBUG5(PARSE, "%s: ${%s} = `%s' ${%s} = `%s'\n", 2306 __func__, dirvar, dirname.str, filevar, basename); 2307 FStr_Done(&dirname); 2308 } 2309 2310 /* 2311 * Return the immediately including file. 2312 * 2313 * This is made complicated since the .for loop is implemented as a special 2314 * kind of .include; see For_Run. 2315 */ 2316 static const char * 2317 GetActuallyIncludingFile(void) 2318 { 2319 size_t i; 2320 const IFile *incs = GetInclude(0); 2321 2322 for (i = includes.len; i >= 2; i--) 2323 if (!incs[i - 1].fromForLoop) 2324 return incs[i - 2].fname; 2325 return NULL; 2326 } 2327 2328 /* Set .PARSEDIR, .PARSEFILE, .INCLUDEDFROMDIR and .INCLUDEDFROMFILE. */ 2329 static void 2330 ParseSetParseFile(const char *filename) 2331 { 2332 const char *including; 2333 2334 SetFilenameVars(filename, ".PARSEDIR", ".PARSEFILE"); 2335 2336 including = GetActuallyIncludingFile(); 2337 if (including != NULL) { 2338 SetFilenameVars(including, 2339 ".INCLUDEDFROMDIR", ".INCLUDEDFROMFILE"); 2340 } else { 2341 Global_Delete(".INCLUDEDFROMDIR"); 2342 Global_Delete(".INCLUDEDFROMFILE"); 2343 } 2344 } 2345 2346 static bool 2347 StrContainsWord(const char *str, const char *word) 2348 { 2349 size_t strLen = strlen(str); 2350 size_t wordLen = strlen(word); 2351 const char *p, *end; 2352 2353 if (strLen < wordLen) 2354 return false; /* str is too short to contain word */ 2355 2356 end = str + strLen - wordLen; 2357 for (p = str; p != NULL; p = strchr(p, ' ')) { 2358 if (*p == ' ') 2359 p++; 2360 if (p > end) 2361 return false; /* cannot contain word */ 2362 2363 if (memcmp(p, word, wordLen) == 0 && 2364 (p[wordLen] == '\0' || p[wordLen] == ' ')) 2365 return true; 2366 } 2367 return false; 2368 } 2369 2370 /* 2371 * XXX: Searching through a set of words with this linear search is 2372 * inefficient for variables that contain thousands of words. 2373 * 2374 * XXX: The paths in this list don't seem to be normalized in any way. 2375 */ 2376 static bool 2377 VarContainsWord(const char *varname, const char *word) 2378 { 2379 FStr val = Var_Value(SCOPE_GLOBAL, varname); 2380 bool found = val.str != NULL && StrContainsWord(val.str, word); 2381 FStr_Done(&val); 2382 return found; 2383 } 2384 2385 /* 2386 * Track the makefiles we read - so makefiles can set dependencies on them. 2387 * Avoid adding anything more than once. 2388 * 2389 * Time complexity: O(n) per call, in total O(n^2), where n is the number 2390 * of makefiles that have been loaded. 2391 */ 2392 static void 2393 ParseTrackInput(const char *name) 2394 { 2395 if (!VarContainsWord(MAKE_MAKEFILES, name)) 2396 Global_Append(MAKE_MAKEFILES, name); 2397 } 2398 2399 2400 /* 2401 * Start parsing from the given source. 2402 * 2403 * The given file is added to the includes stack. 2404 */ 2405 void 2406 Parse_SetInput(const char *name, int lineno, int fd, 2407 ReadMoreProc readMore, void *readMoreArg) 2408 { 2409 IFile *curFile; 2410 char *buf; 2411 size_t len; 2412 bool fromForLoop = name == NULL; 2413 2414 if (fromForLoop) 2415 name = CurFile()->fname; 2416 else 2417 ParseTrackInput(name); 2418 2419 DEBUG3(PARSE, "Parse_SetInput: %s %s, line %d\n", 2420 readMore == loadedfile_readMore ? "file" : ".for loop in", 2421 name, lineno); 2422 2423 if (fd == -1 && readMore == NULL) 2424 /* sanity */ 2425 return; 2426 2427 curFile = Vector_Push(&includes); 2428 curFile->fname = bmake_strdup(name); 2429 curFile->fromForLoop = fromForLoop; 2430 curFile->lineno = lineno; 2431 curFile->first_lineno = lineno; 2432 curFile->readMore = readMore; 2433 curFile->readMoreArg = readMoreArg; 2434 curFile->lf = NULL; 2435 curFile->depending = doing_depend; /* restore this on EOF */ 2436 2437 assert(readMore != NULL); 2438 2439 /* Get first block of input data */ 2440 buf = curFile->readMore(curFile->readMoreArg, &len); 2441 if (buf == NULL) { 2442 /* Was all a waste of time ... */ 2443 if (curFile->fname != NULL) 2444 free(curFile->fname); 2445 free(curFile); 2446 return; 2447 } 2448 curFile->buf_freeIt = buf; 2449 curFile->buf_ptr = buf; 2450 curFile->buf_end = buf + len; 2451 2452 curFile->cond_depth = Cond_save_depth(); 2453 ParseSetParseFile(name); 2454 } 2455 2456 /* Check if the directive is an include directive. */ 2457 static bool 2458 IsInclude(const char *dir, bool sysv) 2459 { 2460 if (dir[0] == 's' || dir[0] == '-' || (dir[0] == 'd' && !sysv)) 2461 dir++; 2462 2463 if (strncmp(dir, "include", 7) != 0) 2464 return false; 2465 2466 /* Space is not mandatory for BSD .include */ 2467 return !sysv || ch_isspace(dir[7]); 2468 } 2469 2470 2471 #ifdef SYSVINCLUDE 2472 /* Check if the line is a SYSV include directive. */ 2473 static bool 2474 IsSysVInclude(const char *line) 2475 { 2476 const char *p; 2477 2478 if (!IsInclude(line, true)) 2479 return false; 2480 2481 /* Avoid interpreting a dependency line as an include */ 2482 for (p = line; (p = strchr(p, ':')) != NULL;) { 2483 2484 /* end of line -> it's a dependency */ 2485 if (*++p == '\0') 2486 return false; 2487 2488 /* '::' operator or ': ' -> it's a dependency */ 2489 if (*p == ':' || ch_isspace(*p)) 2490 return false; 2491 } 2492 return true; 2493 } 2494 2495 /* Push to another file. The line points to the word "include". */ 2496 static void 2497 ParseTraditionalInclude(char *line) 2498 { 2499 char *cp; /* current position in file spec */ 2500 bool done = false; 2501 bool silent = line[0] != 'i'; 2502 char *file = line + (silent ? 8 : 7); 2503 char *all_files; 2504 2505 DEBUG2(PARSE, "%s: %s\n", __func__, file); 2506 2507 pp_skip_whitespace(&file); 2508 2509 /* 2510 * Substitute for any variables in the file name before trying to 2511 * find the thing. 2512 */ 2513 (void)Var_Subst(file, SCOPE_CMDLINE, VARE_WANTRES, &all_files); 2514 /* TODO: handle errors */ 2515 2516 if (*file == '\0') { 2517 Parse_Error(PARSE_FATAL, "Filename missing from \"include\""); 2518 goto out; 2519 } 2520 2521 for (file = all_files; !done; file = cp + 1) { 2522 /* Skip to end of line or next whitespace */ 2523 for (cp = file; *cp != '\0' && !ch_isspace(*cp); cp++) 2524 continue; 2525 2526 if (*cp != '\0') 2527 *cp = '\0'; 2528 else 2529 done = true; 2530 2531 IncludeFile(file, false, false, silent); 2532 } 2533 out: 2534 free(all_files); 2535 } 2536 #endif 2537 2538 #ifdef GMAKEEXPORT 2539 /* Parse "export <variable>=<value>", and actually export it. */ 2540 static void 2541 ParseGmakeExport(char *line) 2542 { 2543 char *variable = line + 6; 2544 char *value; 2545 2546 DEBUG2(PARSE, "%s: %s\n", __func__, variable); 2547 2548 pp_skip_whitespace(&variable); 2549 2550 for (value = variable; *value != '\0' && *value != '='; value++) 2551 continue; 2552 2553 if (*value != '=') { 2554 Parse_Error(PARSE_FATAL, 2555 "Variable/Value missing from \"export\""); 2556 return; 2557 } 2558 *value++ = '\0'; /* terminate variable */ 2559 2560 /* 2561 * Expand the value before putting it in the environment. 2562 */ 2563 (void)Var_Subst(value, SCOPE_CMDLINE, VARE_WANTRES, &value); 2564 /* TODO: handle errors */ 2565 2566 setenv(variable, value, 1); 2567 free(value); 2568 } 2569 #endif 2570 2571 /* 2572 * Called when EOF is reached in the current file. If we were reading an 2573 * include file or a .for loop, the includes stack is popped and things set 2574 * up to go back to reading the previous file at the previous location. 2575 * 2576 * Results: 2577 * true to continue parsing, i.e. it had only reached the end of an 2578 * included file, false if the main file has been parsed completely. 2579 */ 2580 static bool 2581 ParseEOF(void) 2582 { 2583 char *ptr; 2584 size_t len; 2585 IFile *curFile = CurFile(); 2586 2587 assert(curFile->readMore != NULL); 2588 2589 doing_depend = curFile->depending; /* restore this */ 2590 /* get next input buffer, if any */ 2591 ptr = curFile->readMore(curFile->readMoreArg, &len); 2592 curFile->buf_ptr = ptr; 2593 curFile->buf_freeIt = ptr; 2594 curFile->buf_end = ptr == NULL ? NULL : ptr + len; 2595 curFile->lineno = curFile->first_lineno; 2596 if (ptr != NULL) 2597 return true; /* Iterate again */ 2598 2599 /* Ensure the makefile (or loop) didn't have mismatched conditionals */ 2600 Cond_restore_depth(curFile->cond_depth); 2601 2602 if (curFile->lf != NULL) { 2603 loadedfile_destroy(curFile->lf); 2604 curFile->lf = NULL; 2605 } 2606 2607 /* Dispose of curFile info */ 2608 /* Leak curFile->fname because all the GNodes have pointers to it. */ 2609 free(curFile->buf_freeIt); 2610 Vector_Pop(&includes); 2611 2612 if (includes.len == 0) { 2613 /* We've run out of input */ 2614 Global_Delete(".PARSEDIR"); 2615 Global_Delete(".PARSEFILE"); 2616 Global_Delete(".INCLUDEDFROMDIR"); 2617 Global_Delete(".INCLUDEDFROMFILE"); 2618 return false; 2619 } 2620 2621 curFile = CurFile(); 2622 DEBUG2(PARSE, "ParseEOF: returning to file %s, line %d\n", 2623 curFile->fname, curFile->lineno); 2624 2625 ParseSetParseFile(curFile->fname); 2626 return true; 2627 } 2628 2629 typedef enum ParseRawLineResult { 2630 PRLR_LINE, 2631 PRLR_EOF, 2632 PRLR_ERROR 2633 } ParseRawLineResult; 2634 2635 /* 2636 * Parse until the end of a line, taking into account lines that end with 2637 * backslash-newline. 2638 */ 2639 static ParseRawLineResult 2640 ParseRawLine(IFile *curFile, char **out_line, char **out_line_end, 2641 char **out_firstBackslash, char **out_firstComment) 2642 { 2643 char *line = curFile->buf_ptr; 2644 char *p = line; 2645 char *line_end = line; 2646 char *firstBackslash = NULL; 2647 char *firstComment = NULL; 2648 ParseRawLineResult res = PRLR_LINE; 2649 2650 curFile->lineno++; 2651 2652 for (;;) { 2653 char ch; 2654 2655 if (p == curFile->buf_end) { 2656 res = PRLR_EOF; 2657 break; 2658 } 2659 2660 ch = *p; 2661 if (ch == '\0' || 2662 (ch == '\\' && p + 1 < curFile->buf_end && p[1] == '\0')) { 2663 Parse_Error(PARSE_FATAL, "Zero byte read from file"); 2664 return PRLR_ERROR; 2665 } 2666 2667 /* Treat next character after '\' as literal. */ 2668 if (ch == '\\') { 2669 if (firstBackslash == NULL) 2670 firstBackslash = p; 2671 if (p[1] == '\n') { 2672 curFile->lineno++; 2673 if (p + 2 == curFile->buf_end) { 2674 line_end = p; 2675 *line_end = '\n'; 2676 p += 2; 2677 continue; 2678 } 2679 } 2680 p += 2; 2681 line_end = p; 2682 assert(p <= curFile->buf_end); 2683 continue; 2684 } 2685 2686 /* 2687 * Remember the first '#' for comment stripping, unless 2688 * the previous char was '[', as in the modifier ':[#]'. 2689 */ 2690 if (ch == '#' && firstComment == NULL && 2691 !(p > line && p[-1] == '[')) 2692 firstComment = line_end; 2693 2694 p++; 2695 if (ch == '\n') 2696 break; 2697 2698 /* We are not interested in trailing whitespace. */ 2699 if (!ch_isspace(ch)) 2700 line_end = p; 2701 } 2702 2703 *out_line = line; 2704 curFile->buf_ptr = p; 2705 *out_line_end = line_end; 2706 *out_firstBackslash = firstBackslash; 2707 *out_firstComment = firstComment; 2708 return res; 2709 } 2710 2711 /* 2712 * Beginning at start, unescape '\#' to '#' and replace backslash-newline 2713 * with a single space. 2714 */ 2715 static void 2716 UnescapeBackslash(char *line, char *start) 2717 { 2718 char *src = start; 2719 char *dst = start; 2720 char *spaceStart = line; 2721 2722 for (;;) { 2723 char ch = *src++; 2724 if (ch != '\\') { 2725 if (ch == '\0') 2726 break; 2727 *dst++ = ch; 2728 continue; 2729 } 2730 2731 ch = *src++; 2732 if (ch == '\0') { 2733 /* Delete '\\' at end of buffer */ 2734 dst--; 2735 break; 2736 } 2737 2738 /* Delete '\\' from before '#' on non-command lines */ 2739 if (ch == '#' && line[0] != '\t') { 2740 *dst++ = ch; 2741 continue; 2742 } 2743 2744 if (ch != '\n') { 2745 /* Leave '\\' in buffer for later */ 2746 *dst++ = '\\'; 2747 /* 2748 * Make sure we don't delete an escaped ' ' from the 2749 * line end. 2750 */ 2751 spaceStart = dst + 1; 2752 *dst++ = ch; 2753 continue; 2754 } 2755 2756 /* 2757 * Escaped '\n' -- replace following whitespace with a single 2758 * ' '. 2759 */ 2760 pp_skip_hspace(&src); 2761 *dst++ = ' '; 2762 } 2763 2764 /* Delete any trailing spaces - eg from empty continuations */ 2765 while (dst > spaceStart && ch_isspace(dst[-1])) 2766 dst--; 2767 *dst = '\0'; 2768 } 2769 2770 typedef enum GetLineMode { 2771 /* 2772 * Return the next line that is neither empty nor a comment. 2773 * Backslash line continuations are folded into a single space. 2774 * A trailing comment, if any, is discarded. 2775 */ 2776 GLM_NONEMPTY, 2777 2778 /* 2779 * Return the next line, even if it is empty or a comment. 2780 * Preserve backslash-newline to keep the line numbers correct. 2781 * 2782 * Used in .for loops to collect the body of the loop while waiting 2783 * for the corresponding .endfor. 2784 */ 2785 GLM_FOR_BODY, 2786 2787 /* 2788 * Return the next line that starts with a dot. 2789 * Backslash line continuations are folded into a single space. 2790 * A trailing comment, if any, is discarded. 2791 * 2792 * Used in .if directives to skip over irrelevant branches while 2793 * waiting for the corresponding .endif. 2794 */ 2795 GLM_DOT 2796 } GetLineMode; 2797 2798 /* Return the next "interesting" logical line from the current file. */ 2799 static char * 2800 ParseGetLine(GetLineMode mode) 2801 { 2802 IFile *curFile = CurFile(); 2803 char *line; 2804 char *line_end; 2805 char *firstBackslash; 2806 char *firstComment; 2807 2808 for (;;) { 2809 ParseRawLineResult res = ParseRawLine(curFile, 2810 &line, &line_end, &firstBackslash, &firstComment); 2811 if (res == PRLR_ERROR) 2812 return NULL; 2813 2814 if (line_end == line || firstComment == line) { 2815 if (res == PRLR_EOF) 2816 return NULL; 2817 if (mode != GLM_FOR_BODY) 2818 continue; 2819 } 2820 2821 /* We now have a line of data */ 2822 assert(ch_isspace(*line_end)); 2823 *line_end = '\0'; 2824 2825 if (mode == GLM_FOR_BODY) 2826 return line; /* Don't join the physical lines. */ 2827 2828 if (mode == GLM_DOT && line[0] != '.') 2829 continue; 2830 break; 2831 } 2832 2833 /* Brutally ignore anything after a non-escaped '#' in non-commands. */ 2834 if (firstComment != NULL && line[0] != '\t') 2835 *firstComment = '\0'; 2836 2837 /* If we didn't see a '\\' then the in-situ data is fine. */ 2838 if (firstBackslash == NULL) 2839 return line; 2840 2841 /* Remove escapes from '\n' and '#' */ 2842 UnescapeBackslash(line, firstBackslash); 2843 2844 return line; 2845 } 2846 2847 static bool 2848 ParseSkippedBranches(void) 2849 { 2850 char *line; 2851 2852 while ((line = ParseGetLine(GLM_DOT)) != NULL) { 2853 if (Cond_EvalLine(line) == COND_PARSE) 2854 break; 2855 /* 2856 * TODO: Check for typos in .elif directives 2857 * such as .elsif or .elseif. 2858 * 2859 * This check will probably duplicate some of 2860 * the code in ParseLine. Most of the code 2861 * there cannot apply, only ParseVarassign and 2862 * ParseDependencyLine can, and to prevent code 2863 * duplication, these would need to be called 2864 * with a flag called onlyCheckSyntax. 2865 * 2866 * See directive-elif.mk for details. 2867 */ 2868 } 2869 2870 return line != NULL; 2871 } 2872 2873 static bool 2874 ParseForLoop(const char *line) 2875 { 2876 int rval; 2877 int firstLineno; 2878 2879 rval = For_Eval(line); 2880 if (rval == 0) 2881 return false; /* Not a .for line */ 2882 if (rval < 0) 2883 return true; /* Syntax error - error printed, ignore line */ 2884 2885 firstLineno = CurFile()->lineno; 2886 2887 /* Accumulate loop lines until matching .endfor */ 2888 do { 2889 line = ParseGetLine(GLM_FOR_BODY); 2890 if (line == NULL) { 2891 Parse_Error(PARSE_FATAL, 2892 "Unexpected end of file in for loop."); 2893 break; 2894 } 2895 } while (For_Accum(line)); 2896 2897 For_Run(firstLineno); /* Stash each iteration as a new 'input file' */ 2898 2899 return true; /* Read next line from for-loop buffer */ 2900 } 2901 2902 /* 2903 * Read an entire line from the input file. 2904 * 2905 * Empty lines, .if and .for are completely handled by this function, 2906 * leaving only variable assignments, other directives, dependency lines 2907 * and shell commands to the caller. 2908 * 2909 * Results: 2910 * A line without its newline and without any trailing whitespace, 2911 * or NULL. 2912 */ 2913 static char * 2914 ParseReadLine(void) 2915 { 2916 char *line; 2917 2918 for (;;) { 2919 line = ParseGetLine(GLM_NONEMPTY); 2920 if (line == NULL) 2921 return NULL; 2922 2923 if (line[0] != '.') 2924 return line; 2925 2926 /* 2927 * The line might be a conditional. Ask the conditional module 2928 * about it and act accordingly 2929 */ 2930 switch (Cond_EvalLine(line)) { 2931 case COND_SKIP: 2932 if (!ParseSkippedBranches()) 2933 return NULL; 2934 continue; 2935 case COND_PARSE: 2936 continue; 2937 case COND_INVALID: /* Not a conditional line */ 2938 if (ParseForLoop(line)) 2939 continue; 2940 break; 2941 } 2942 return line; 2943 } 2944 } 2945 2946 static void 2947 FinishDependencyGroup(void) 2948 { 2949 GNodeListNode *ln; 2950 2951 if (targets == NULL) 2952 return; 2953 2954 for (ln = targets->first; ln != NULL; ln = ln->next) { 2955 GNode *gn = ln->datum; 2956 2957 Suff_EndTransform(gn); 2958 2959 /* 2960 * Mark the target as already having commands if it does, to 2961 * keep from having shell commands on multiple dependency 2962 * lines. 2963 */ 2964 if (!Lst_IsEmpty(&gn->commands)) 2965 gn->type |= OP_HAS_COMMANDS; 2966 } 2967 2968 Lst_Free(targets); 2969 targets = NULL; 2970 } 2971 2972 /* Add the command to each target from the current dependency spec. */ 2973 static void 2974 ParseLine_ShellCommand(const char *p) 2975 { 2976 cpp_skip_whitespace(&p); 2977 if (*p == '\0') 2978 return; /* skip empty commands */ 2979 2980 if (targets == NULL) { 2981 Parse_Error(PARSE_FATAL, 2982 "Unassociated shell command \"%s\"", p); 2983 return; 2984 } 2985 2986 { 2987 char *cmd = bmake_strdup(p); 2988 GNodeListNode *ln; 2989 2990 for (ln = targets->first; ln != NULL; ln = ln->next) { 2991 GNode *gn = ln->datum; 2992 ParseAddCmd(gn, cmd); 2993 } 2994 #ifdef CLEANUP 2995 Lst_Append(&targCmds, cmd); 2996 #endif 2997 } 2998 } 2999 3000 MAKE_INLINE bool 3001 IsDirective(const char *dir, size_t dirlen, const char *name) 3002 { 3003 return dirlen == strlen(name) && memcmp(dir, name, dirlen) == 0; 3004 } 3005 3006 /* 3007 * See if the line starts with one of the known directives, and if so, handle 3008 * the directive. 3009 */ 3010 static bool 3011 ParseDirective(char *line) 3012 { 3013 char *cp = line + 1; 3014 const char *dir, *arg; 3015 size_t dirlen; 3016 3017 pp_skip_whitespace(&cp); 3018 if (IsInclude(cp, false)) { 3019 ParseInclude(cp); 3020 return true; 3021 } 3022 3023 dir = cp; 3024 while (ch_isalpha(*cp) || *cp == '-') 3025 cp++; 3026 dirlen = (size_t)(cp - dir); 3027 3028 if (*cp != '\0' && !ch_isspace(*cp)) 3029 return false; 3030 3031 pp_skip_whitespace(&cp); 3032 arg = cp; 3033 3034 if (IsDirective(dir, dirlen, "undef")) { 3035 Var_Undef(cp); 3036 return true; 3037 } else if (IsDirective(dir, dirlen, "export")) { 3038 Var_Export(VEM_PLAIN, arg); 3039 return true; 3040 } else if (IsDirective(dir, dirlen, "export-env")) { 3041 Var_Export(VEM_ENV, arg); 3042 return true; 3043 } else if (IsDirective(dir, dirlen, "export-literal")) { 3044 Var_Export(VEM_LITERAL, arg); 3045 return true; 3046 } else if (IsDirective(dir, dirlen, "unexport")) { 3047 Var_UnExport(false, arg); 3048 return true; 3049 } else if (IsDirective(dir, dirlen, "unexport-env")) { 3050 Var_UnExport(true, arg); 3051 return true; 3052 } else if (IsDirective(dir, dirlen, "info")) { 3053 ParseMessage(PARSE_INFO, "info", arg); 3054 return true; 3055 } else if (IsDirective(dir, dirlen, "warning")) { 3056 ParseMessage(PARSE_WARNING, "warning", arg); 3057 return true; 3058 } else if (IsDirective(dir, dirlen, "error")) { 3059 ParseMessage(PARSE_FATAL, "error", arg); 3060 return true; 3061 } 3062 return false; 3063 } 3064 3065 static bool 3066 ParseVarassign(const char *line) 3067 { 3068 VarAssign var; 3069 3070 if (!Parse_IsVar(line, &var)) 3071 return false; 3072 3073 FinishDependencyGroup(); 3074 Parse_Var(&var, SCOPE_GLOBAL); 3075 return true; 3076 } 3077 3078 static char * 3079 FindSemicolon(char *p) 3080 { 3081 int level = 0; 3082 3083 for (; *p != '\0'; p++) { 3084 if (*p == '\\' && p[1] != '\0') { 3085 p++; 3086 continue; 3087 } 3088 3089 if (*p == '$' && (p[1] == '(' || p[1] == '{')) 3090 level++; 3091 else if (level > 0 && (*p == ')' || *p == '}')) 3092 level--; 3093 else if (level == 0 && *p == ';') 3094 break; 3095 } 3096 return p; 3097 } 3098 3099 /* 3100 * dependency -> target... op [source...] [';' command] 3101 * op -> ':' | '::' | '!' 3102 */ 3103 static void 3104 ParseDependencyLine(char *line) 3105 { 3106 VarEvalMode emode; 3107 char *expanded_line; 3108 const char *shellcmd = NULL; 3109 3110 /* 3111 * For some reason - probably to make the parser impossible - 3112 * a ';' can be used to separate commands from dependencies. 3113 * Attempt to avoid ';' inside substitution patterns. 3114 */ 3115 { 3116 char *semicolon = FindSemicolon(line); 3117 if (*semicolon != '\0') { 3118 /* Terminate the dependency list at the ';' */ 3119 *semicolon = '\0'; 3120 shellcmd = semicolon + 1; 3121 } 3122 } 3123 3124 /* 3125 * We now know it's a dependency line so it needs to have all 3126 * variables expanded before being parsed. 3127 * 3128 * XXX: Ideally the dependency line would first be split into 3129 * its left-hand side, dependency operator and right-hand side, 3130 * and then each side would be expanded on its own. This would 3131 * allow for the left-hand side to allow only defined variables 3132 * and to allow variables on the right-hand side to be undefined 3133 * as well. 3134 * 3135 * Parsing the line first would also prevent that targets 3136 * generated from variable expressions are interpreted as the 3137 * dependency operator, such as in "target${:U\:} middle: source", 3138 * in which the middle is interpreted as a source, not a target. 3139 */ 3140 3141 /* In lint mode, allow undefined variables to appear in 3142 * dependency lines. 3143 * 3144 * Ideally, only the right-hand side would allow undefined 3145 * variables since it is common to have optional dependencies. 3146 * Having undefined variables on the left-hand side is more 3147 * unusual though. Since both sides are expanded in a single 3148 * pass, there is not much choice what to do here. 3149 * 3150 * In normal mode, it does not matter whether undefined 3151 * variables are allowed or not since as of 2020-09-14, 3152 * Var_Parse does not print any parse errors in such a case. 3153 * It simply returns the special empty string var_Error, 3154 * which cannot be detected in the result of Var_Subst. */ 3155 emode = opts.strict ? VARE_WANTRES : VARE_UNDEFERR; 3156 (void)Var_Subst(line, SCOPE_CMDLINE, emode, &expanded_line); 3157 /* TODO: handle errors */ 3158 3159 /* Need a fresh list for the target nodes */ 3160 if (targets != NULL) 3161 Lst_Free(targets); 3162 targets = Lst_New(); 3163 3164 ParseDependency(expanded_line); 3165 free(expanded_line); 3166 3167 if (shellcmd != NULL) 3168 ParseLine_ShellCommand(shellcmd); 3169 } 3170 3171 static void 3172 ParseLine(char *line) 3173 { 3174 /* 3175 * Lines that begin with '.' can be pretty much anything: 3176 * - directives like '.include' or '.if', 3177 * - suffix rules like '.c.o:', 3178 * - dependencies for filenames that start with '.', 3179 * - variable assignments like '.tmp=value'. 3180 */ 3181 if (line[0] == '.' && ParseDirective(line)) 3182 return; 3183 3184 if (line[0] == '\t') { 3185 ParseLine_ShellCommand(line + 1); 3186 return; 3187 } 3188 3189 #ifdef SYSVINCLUDE 3190 if (IsSysVInclude(line)) { 3191 /* 3192 * It's an S3/S5-style "include". 3193 */ 3194 ParseTraditionalInclude(line); 3195 return; 3196 } 3197 #endif 3198 3199 #ifdef GMAKEEXPORT 3200 if (strncmp(line, "export", 6) == 0 && ch_isspace(line[6]) && 3201 strchr(line, ':') == NULL) { 3202 /* 3203 * It's a Gmake "export". 3204 */ 3205 ParseGmakeExport(line); 3206 return; 3207 } 3208 #endif 3209 3210 if (ParseVarassign(line)) 3211 return; 3212 3213 FinishDependencyGroup(); 3214 3215 ParseDependencyLine(line); 3216 } 3217 3218 /* 3219 * Parse a top-level makefile, incorporating its content into the global 3220 * dependency graph. 3221 * 3222 * Input: 3223 * name The name of the file being read 3224 * fd The open file to parse; will be closed at the end 3225 */ 3226 void 3227 Parse_File(const char *name, int fd) 3228 { 3229 char *line; /* the line we're working on */ 3230 struct loadedfile *lf; 3231 3232 lf = loadfile(name, fd); 3233 3234 assert(targets == NULL); 3235 3236 if (name == NULL) 3237 name = "(stdin)"; 3238 3239 Parse_SetInput(name, 0, -1, loadedfile_readMore, lf); 3240 CurFile()->lf = lf; 3241 3242 do { 3243 while ((line = ParseReadLine()) != NULL) { 3244 DEBUG2(PARSE, "ParseReadLine (%d): '%s'\n", 3245 CurFile()->lineno, line); 3246 ParseLine(line); 3247 } 3248 /* Reached EOF, but it may be just EOF of an include file. */ 3249 } while (ParseEOF()); 3250 3251 FinishDependencyGroup(); 3252 3253 if (parseErrors != 0) { 3254 (void)fflush(stdout); 3255 (void)fprintf(stderr, 3256 "%s: Fatal errors encountered -- cannot continue", 3257 progname); 3258 PrintOnError(NULL, NULL); 3259 exit(1); 3260 } 3261 } 3262 3263 /* Initialize the parsing module. */ 3264 void 3265 Parse_Init(void) 3266 { 3267 mainNode = NULL; 3268 parseIncPath = SearchPath_New(); 3269 sysIncPath = SearchPath_New(); 3270 defSysIncPath = SearchPath_New(); 3271 Vector_Init(&includes, sizeof(IFile)); 3272 } 3273 3274 /* Clean up the parsing module. */ 3275 void 3276 Parse_End(void) 3277 { 3278 #ifdef CLEANUP 3279 Lst_DoneCall(&targCmds, free); 3280 assert(targets == NULL); 3281 SearchPath_Free(defSysIncPath); 3282 SearchPath_Free(sysIncPath); 3283 SearchPath_Free(parseIncPath); 3284 assert(includes.len == 0); 3285 Vector_Done(&includes); 3286 #endif 3287 } 3288 3289 3290 /* 3291 * Return a list containing the single main target to create. 3292 * If no such target exists, we Punt with an obnoxious error message. 3293 */ 3294 void 3295 Parse_MainName(GNodeList *mainList) 3296 { 3297 if (mainNode == NULL) 3298 Punt("no target to make."); 3299 3300 Lst_Append(mainList, mainNode); 3301 if (mainNode->type & OP_DOUBLEDEP) 3302 Lst_AppendAll(mainList, &mainNode->cohorts); 3303 3304 Global_Append(".TARGETS", mainNode->name); 3305 } 3306 3307 int 3308 Parse_NumErrors(void) 3309 { 3310 return parseErrors; 3311 } 3312