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