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