1 /* 2 * Copyright (c) 1988, 1989, 1990 The Regents of the University of California. 3 * Copyright (c) 1988, 1989 by Adam de Boor 4 * Copyright (c) 1989 by Berkeley Softworks 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Adam de Boor. 9 * 10 * %sccs.include.redist.c% 11 */ 12 13 #ifndef lint 14 static char sccsid[] = "@(#)parse.c 5.22 (Berkeley) 06/02/93"; 15 #endif /* not lint */ 16 17 /*- 18 * parse.c -- 19 * Functions to parse a makefile. 20 * 21 * One function, Parse_Init, must be called before any functions 22 * in this module are used. After that, the function Parse_File is the 23 * main entry point and controls most of the other functions in this 24 * module. 25 * 26 * Most important structures are kept in Lsts. Directories for 27 * the #include "..." function are kept in the 'parseIncPath' Lst, while 28 * those for the #include <...> are kept in the 'sysIncPath' Lst. The 29 * targets currently being defined are kept in the 'targets' Lst. 30 * 31 * The variables 'fname' and 'lineno' are used to track the name 32 * of the current file and the line number in that file so that error 33 * messages can be more meaningful. 34 * 35 * Interface: 36 * Parse_Init Initialization function which must be 37 * called before anything else in this module 38 * is used. 39 * 40 * Parse_File Function used to parse a makefile. It must 41 * be given the name of the file, which should 42 * already have been opened, and a function 43 * to call to read a character from the file. 44 * 45 * Parse_IsVar Returns TRUE if the given line is a 46 * variable assignment. Used by MainParseArgs 47 * to determine if an argument is a target 48 * or a variable assignment. Used internally 49 * for pretty much the same thing... 50 * 51 * Parse_Error Function called when an error occurs in 52 * parsing. Used by the variable and 53 * conditional modules. 54 * Parse_MainName Returns a Lst of the main target to create. 55 */ 56 57 #if __STDC__ 58 #include <stdarg.h> 59 #else 60 #include <varargs.h> 61 #endif 62 #include <stdio.h> 63 #include <ctype.h> 64 #include <errno.h> 65 #include <sys/wait.h> 66 #include "make.h" 67 #include "hash.h" 68 #include "dir.h" 69 #include "job.h" 70 #include "buf.h" 71 #include "pathnames.h" 72 73 /* 74 * These values are returned by ParseEOF to tell Parse_File whether to 75 * CONTINUE parsing, i.e. it had only reached the end of an include file, 76 * or if it's DONE. 77 */ 78 #define CONTINUE 1 79 #define DONE 0 80 static Lst targets; /* targets we're working on */ 81 static Boolean inLine; /* true if currently in a dependency 82 * line or its commands */ 83 typedef struct { 84 char *str; 85 char *ptr; 86 } PTR; 87 88 static char *fname; /* name of current file (for errors) */ 89 static int lineno; /* line number in current file */ 90 static FILE *curFILE = NULL; /* current makefile */ 91 92 static PTR *curPTR = NULL; /* current makefile */ 93 94 static int fatals = 0; 95 96 static GNode *mainNode; /* The main target to create. This is the 97 * first target on the first dependency 98 * line in the first makefile */ 99 /* 100 * Definitions for handling #include specifications 101 */ 102 typedef struct IFile { 103 char *fname; /* name of previous file */ 104 int lineno; /* saved line number */ 105 FILE * F; /* the open stream */ 106 PTR * p; /* the char pointer */ 107 } IFile; 108 109 static Lst includes; /* stack of IFiles generated by 110 * #includes */ 111 Lst parseIncPath; /* list of directories for "..." includes */ 112 Lst sysIncPath; /* list of directories for <...> includes */ 113 114 /*- 115 * specType contains the SPECial TYPE of the current target. It is 116 * Not if the target is unspecial. If it *is* special, however, the children 117 * are linked as children of the parent but not vice versa. This variable is 118 * set in ParseDoDependency 119 */ 120 typedef enum { 121 Begin, /* .BEGIN */ 122 Default, /* .DEFAULT */ 123 End, /* .END */ 124 Ignore, /* .IGNORE */ 125 Includes, /* .INCLUDES */ 126 Interrupt, /* .INTERRUPT */ 127 Libs, /* .LIBS */ 128 MFlags, /* .MFLAGS or .MAKEFLAGS */ 129 Main, /* .MAIN and we don't have anything user-specified to 130 * make */ 131 NoExport, /* .NOEXPORT */ 132 Not, /* Not special */ 133 NotParallel, /* .NOTPARALELL */ 134 Null, /* .NULL */ 135 Order, /* .ORDER */ 136 ExPath, /* .PATH */ 137 Precious, /* .PRECIOUS */ 138 ExShell, /* .SHELL */ 139 Silent, /* .SILENT */ 140 SingleShell, /* .SINGLESHELL */ 141 Suffixes, /* .SUFFIXES */ 142 Attribute /* Generic attribute */ 143 } ParseSpecial; 144 145 static ParseSpecial specType; 146 147 /* 148 * Predecessor node for handling .ORDER. Initialized to NILGNODE when .ORDER 149 * seen, then set to each successive source on the line. 150 */ 151 static GNode *predecessor; 152 153 /* 154 * The parseKeywords table is searched using binary search when deciding 155 * if a target or source is special. The 'spec' field is the ParseSpecial 156 * type of the keyword ("Not" if the keyword isn't special as a target) while 157 * the 'op' field is the operator to apply to the list of targets if the 158 * keyword is used as a source ("0" if the keyword isn't special as a source) 159 */ 160 static struct { 161 char *name; /* Name of keyword */ 162 ParseSpecial spec; /* Type when used as a target */ 163 int op; /* Operator when used as a source */ 164 } parseKeywords[] = { 165 { ".BEGIN", Begin, 0 }, 166 { ".DEFAULT", Default, 0 }, 167 { ".OPTIONAL", Attribute, OP_OPTIONAL }, 168 { ".END", End, 0 }, 169 { ".EXEC", Attribute, OP_EXEC }, 170 { ".IGNORE", Ignore, OP_IGNORE }, 171 { ".INCLUDES", Includes, 0 }, 172 { ".INTERRUPT", Interrupt, 0 }, 173 { ".INVISIBLE", Attribute, OP_INVISIBLE }, 174 { ".JOIN", Attribute, OP_JOIN }, 175 { ".LIBS", Libs, 0 }, 176 { ".MAIN", Main, 0 }, 177 { ".MAKE", Attribute, OP_MAKE }, 178 { ".MAKEFLAGS", MFlags, 0 }, 179 { ".MFLAGS", MFlags, 0 }, 180 { ".NOTMAIN", Attribute, OP_NOTMAIN }, 181 { ".NOTPARALLEL", NotParallel, 0 }, 182 { ".NULL", Null, 0 }, 183 { ".ORDER", Order, 0 }, 184 { ".PATH", ExPath, 0 }, 185 { ".PRECIOUS", Precious, OP_PRECIOUS }, 186 { ".RECURSIVE", Attribute, OP_MAKE }, 187 { ".SHELL", ExShell, 0 }, 188 { ".SILENT", Silent, OP_SILENT }, 189 { ".SINGLESHELL", SingleShell, 0 }, 190 { ".SUFFIXES", Suffixes, 0 }, 191 { ".USE", Attribute, OP_USE }, 192 }; 193 194 static int ParseFindKeyword __P((char *)); 195 static int ParseLinkSrc __P((GNode *, GNode *)); 196 static int ParseDoOp __P((GNode *, int)); 197 static void ParseDoSrc __P((int, char *)); 198 static int ParseFindMain __P((GNode *)); 199 static int ParseAddDir __P((Lst, char *)); 200 static int ParseClearPath __P((Lst)); 201 static void ParseDoDependency __P((char *)); 202 static int ParseAddCmd __P((GNode *, char *)); 203 static int ParseReadc __P((void)); 204 static void ParseUnreadc __P((int)); 205 static int ParseHasCommands __P((GNode *)); 206 static void ParseDoInclude __P((char *)); 207 #ifdef SYSVINCLUDE 208 static void ParseTraditionalInclude __P((char *)); 209 #endif 210 static int ParseEOF __P((int)); 211 static char *ParseReadLine __P((void)); 212 static char *ParseSkipLine __P((int)); 213 static void ParseFinishLine __P((void)); 214 215 /*- 216 *---------------------------------------------------------------------- 217 * ParseFindKeyword -- 218 * Look in the table of keywords for one matching the given string. 219 * 220 * Results: 221 * The index of the keyword, or -1 if it isn't there. 222 * 223 * Side Effects: 224 * None 225 *---------------------------------------------------------------------- 226 */ 227 static int 228 ParseFindKeyword (str) 229 char *str; /* String to find */ 230 { 231 register int start, 232 end, 233 cur; 234 register int diff; 235 236 start = 0; 237 end = (sizeof(parseKeywords)/sizeof(parseKeywords[0])) - 1; 238 239 do { 240 cur = start + ((end - start) / 2); 241 diff = strcmp (str, parseKeywords[cur].name); 242 243 if (diff == 0) { 244 return (cur); 245 } else if (diff < 0) { 246 end = cur - 1; 247 } else { 248 start = cur + 1; 249 } 250 } while (start <= end); 251 return (-1); 252 } 253 254 /*- 255 * Parse_Error -- 256 * Error message abort function for parsing. Prints out the context 257 * of the error (line number and file) as well as the message with 258 * two optional arguments. 259 * 260 * Results: 261 * None 262 * 263 * Side Effects: 264 * "fatals" is incremented if the level is PARSE_FATAL. 265 */ 266 /* VARARGS */ 267 void 268 #if __STDC__ 269 Parse_Error(int type, const char *fmt, ...) 270 #else 271 Parse_Error(type, fmt, va_alist) 272 int type; 273 char *fmt; 274 va_dcl 275 #endif 276 { 277 va_list ap; 278 #if __STDC__ 279 va_start(ap, fmt); 280 #else 281 va_start(ap); 282 #endif 283 (void)fprintf(stderr, "\"%s\", line %d: ", fname, lineno); 284 if (type == PARSE_WARNING) 285 (void)fprintf(stderr, "warning: "); 286 (void)vfprintf(stderr, fmt, ap); 287 va_end(ap); 288 (void)fprintf(stderr, "\n"); 289 (void)fflush(stderr); 290 if (type == PARSE_FATAL) 291 fatals += 1; 292 } 293 294 /*- 295 *--------------------------------------------------------------------- 296 * ParseLinkSrc -- 297 * Link the parent node to its new child. Used in a Lst_ForEach by 298 * ParseDoDependency. If the specType isn't 'Not', the parent 299 * isn't linked as a parent of the child. 300 * 301 * Results: 302 * Always = 0 303 * 304 * Side Effects: 305 * New elements are added to the parents list of cgn and the 306 * children list of cgn. the unmade field of pgn is updated 307 * to reflect the additional child. 308 *--------------------------------------------------------------------- 309 */ 310 static int 311 ParseLinkSrc (pgn, cgn) 312 GNode *pgn; /* The parent node */ 313 GNode *cgn; /* The child node */ 314 { 315 if (Lst_Member (pgn->children, (ClientData)cgn) == NILLNODE) { 316 (void)Lst_AtEnd (pgn->children, (ClientData)cgn); 317 if (specType == Not) { 318 (void)Lst_AtEnd (cgn->parents, (ClientData)pgn); 319 } 320 pgn->unmade += 1; 321 } 322 return (0); 323 } 324 325 /*- 326 *--------------------------------------------------------------------- 327 * ParseDoOp -- 328 * Apply the parsed operator to the given target node. Used in a 329 * Lst_ForEach call by ParseDoDependency once all targets have 330 * been found and their operator parsed. If the previous and new 331 * operators are incompatible, a major error is taken. 332 * 333 * Results: 334 * Always 0 335 * 336 * Side Effects: 337 * The type field of the node is altered to reflect any new bits in 338 * the op. 339 *--------------------------------------------------------------------- 340 */ 341 static int 342 ParseDoOp (gn, op) 343 GNode *gn; /* The node to which the operator is to be 344 * applied */ 345 int op; /* The operator to apply */ 346 { 347 /* 348 * If the dependency mask of the operator and the node don't match and 349 * the node has actually had an operator applied to it before, and 350 * the operator actually has some dependency information in it, complain. 351 */ 352 if (((op & OP_OPMASK) != (gn->type & OP_OPMASK)) && 353 !OP_NOP(gn->type) && !OP_NOP(op)) 354 { 355 Parse_Error (PARSE_FATAL, "Inconsistent operator for %s", gn->name); 356 return (1); 357 } 358 359 if ((op == OP_DOUBLEDEP) && ((gn->type & OP_OPMASK) == OP_DOUBLEDEP)) { 360 /* 361 * If the node was the object of a :: operator, we need to create a 362 * new instance of it for the children and commands on this dependency 363 * line. The new instance is placed on the 'cohorts' list of the 364 * initial one (note the initial one is not on its own cohorts list) 365 * and the new instance is linked to all parents of the initial 366 * instance. 367 */ 368 register GNode *cohort; 369 LstNode ln; 370 371 cohort = Targ_NewGN(gn->name); 372 /* 373 * Duplicate links to parents so graph traversal is simple. Perhaps 374 * some type bits should be duplicated? 375 * 376 * Make the cohort invisible as well to avoid duplicating it into 377 * other variables. True, parents of this target won't tend to do 378 * anything with their local variables, but better safe than 379 * sorry. 380 */ 381 Lst_ForEach(gn->parents, ParseLinkSrc, (ClientData)cohort); 382 cohort->type = OP_DOUBLEDEP|OP_INVISIBLE; 383 (void)Lst_AtEnd(gn->cohorts, (ClientData)cohort); 384 385 /* 386 * Replace the node in the targets list with the new copy 387 */ 388 ln = Lst_Member(targets, (ClientData)gn); 389 Lst_Replace(ln, (ClientData)cohort); 390 gn = cohort; 391 } 392 /* 393 * We don't want to nuke any previous flags (whatever they were) so we 394 * just OR the new operator into the old 395 */ 396 gn->type |= op; 397 398 return (0); 399 } 400 401 /*- 402 *--------------------------------------------------------------------- 403 * ParseDoSrc -- 404 * Given the name of a source, figure out if it is an attribute 405 * and apply it to the targets if it is. Else decide if there is 406 * some attribute which should be applied *to* the source because 407 * of some special target and apply it if so. Otherwise, make the 408 * source be a child of the targets in the list 'targets' 409 * 410 * Results: 411 * None 412 * 413 * Side Effects: 414 * Operator bits may be added to the list of targets or to the source. 415 * The targets may have a new source added to their lists of children. 416 *--------------------------------------------------------------------- 417 */ 418 static void 419 ParseDoSrc (tOp, src) 420 int tOp; /* operator (if any) from special targets */ 421 char *src; /* name of the source to handle */ 422 { 423 int op; /* operator (if any) from special source */ 424 GNode *gn; 425 426 op = 0; 427 if (*src == '.' && isupper (src[1])) { 428 int keywd = ParseFindKeyword(src); 429 if (keywd != -1) { 430 op = parseKeywords[keywd].op; 431 } 432 } 433 if (op != 0) { 434 Lst_ForEach (targets, ParseDoOp, (ClientData)op); 435 } else if (specType == Main) { 436 /* 437 * If we have noted the existence of a .MAIN, it means we need 438 * to add the sources of said target to the list of things 439 * to create. The string 'src' is likely to be free, so we 440 * must make a new copy of it. Note that this will only be 441 * invoked if the user didn't specify a target on the command 442 * line. This is to allow #ifmake's to succeed, or something... 443 */ 444 (void) Lst_AtEnd (create, (ClientData)strdup(src)); 445 /* 446 * Add the name to the .TARGETS variable as well, so the user cna 447 * employ that, if desired. 448 */ 449 Var_Append(".TARGETS", src, VAR_GLOBAL); 450 } else if (specType == Order) { 451 /* 452 * Create proper predecessor/successor links between the previous 453 * source and the current one. 454 */ 455 gn = Targ_FindNode(src, TARG_CREATE); 456 if (predecessor != NILGNODE) { 457 (void)Lst_AtEnd(predecessor->successors, (ClientData)gn); 458 (void)Lst_AtEnd(gn->preds, (ClientData)predecessor); 459 } 460 /* 461 * The current source now becomes the predecessor for the next one. 462 */ 463 predecessor = gn; 464 } else { 465 /* 466 * If the source is not an attribute, we need to find/create 467 * a node for it. After that we can apply any operator to it 468 * from a special target or link it to its parents, as 469 * appropriate. 470 * 471 * In the case of a source that was the object of a :: operator, 472 * the attribute is applied to all of its instances (as kept in 473 * the 'cohorts' list of the node) or all the cohorts are linked 474 * to all the targets. 475 */ 476 gn = Targ_FindNode (src, TARG_CREATE); 477 if (tOp) { 478 gn->type |= tOp; 479 } else { 480 Lst_ForEach (targets, ParseLinkSrc, (ClientData)gn); 481 } 482 if ((gn->type & OP_OPMASK) == OP_DOUBLEDEP) { 483 register GNode *cohort; 484 register LstNode ln; 485 486 for (ln=Lst_First(gn->cohorts); ln != NILLNODE; ln = Lst_Succ(ln)){ 487 cohort = (GNode *)Lst_Datum(ln); 488 if (tOp) { 489 cohort->type |= tOp; 490 } else { 491 Lst_ForEach(targets, ParseLinkSrc, (ClientData)cohort); 492 } 493 } 494 } 495 } 496 } 497 498 /*- 499 *----------------------------------------------------------------------- 500 * ParseFindMain -- 501 * Find a real target in the list and set it to be the main one. 502 * Called by ParseDoDependency when a main target hasn't been found 503 * yet. 504 * 505 * Results: 506 * 0 if main not found yet, 1 if it is. 507 * 508 * Side Effects: 509 * mainNode is changed and Targ_SetMain is called. 510 * 511 *----------------------------------------------------------------------- 512 */ 513 static int 514 ParseFindMain(gn) 515 GNode *gn; /* Node to examine */ 516 { 517 if ((gn->type & (OP_NOTMAIN|OP_USE|OP_EXEC|OP_TRANSFORM)) == 0) { 518 mainNode = gn; 519 Targ_SetMain(gn); 520 return (1); 521 } else { 522 return (0); 523 } 524 } 525 526 /*- 527 *----------------------------------------------------------------------- 528 * ParseAddDir -- 529 * Front-end for Dir_AddDir to make sure Lst_ForEach keeps going 530 * 531 * Results: 532 * === 0 533 * 534 * Side Effects: 535 * See Dir_AddDir. 536 * 537 *----------------------------------------------------------------------- 538 */ 539 static int 540 ParseAddDir(path, name) 541 Lst path; 542 char *name; 543 { 544 Dir_AddDir(path, name); 545 return(0); 546 } 547 548 /*- 549 *----------------------------------------------------------------------- 550 * ParseClearPath -- 551 * Front-end for Dir_ClearPath to make sure Lst_ForEach keeps going 552 * 553 * Results: 554 * === 0 555 * 556 * Side Effects: 557 * See Dir_ClearPath 558 * 559 *----------------------------------------------------------------------- 560 */ 561 static int 562 ParseClearPath(path) 563 Lst path; 564 { 565 Dir_ClearPath(path); 566 return(0); 567 } 568 569 /*- 570 *--------------------------------------------------------------------- 571 * ParseDoDependency -- 572 * Parse the dependency line in line. 573 * 574 * Results: 575 * None 576 * 577 * Side Effects: 578 * The nodes of the sources are linked as children to the nodes of the 579 * targets. Some nodes may be created. 580 * 581 * We parse a dependency line by first extracting words from the line and 582 * finding nodes in the list of all targets with that name. This is done 583 * until a character is encountered which is an operator character. Currently 584 * these are only ! and :. At this point the operator is parsed and the 585 * pointer into the line advanced until the first source is encountered. 586 * The parsed operator is applied to each node in the 'targets' list, 587 * which is where the nodes found for the targets are kept, by means of 588 * the ParseDoOp function. 589 * The sources are read in much the same way as the targets were except 590 * that now they are expanded using the wildcarding scheme of the C-Shell 591 * and all instances of the resulting words in the list of all targets 592 * are found. Each of the resulting nodes is then linked to each of the 593 * targets as one of its children. 594 * Certain targets are handled specially. These are the ones detailed 595 * by the specType variable. 596 * The storing of transformation rules is also taken care of here. 597 * A target is recognized as a transformation rule by calling 598 * Suff_IsTransform. If it is a transformation rule, its node is gotten 599 * from the suffix module via Suff_AddTransform rather than the standard 600 * Targ_FindNode in the target module. 601 *--------------------------------------------------------------------- 602 */ 603 static void 604 ParseDoDependency (line) 605 char *line; /* the line to parse */ 606 { 607 register char *cp; /* our current position */ 608 register GNode *gn; /* a general purpose temporary node */ 609 register int op; /* the operator on the line */ 610 char savec; /* a place to save a character */ 611 Lst paths; /* List of search paths to alter when parsing 612 * a list of .PATH targets */ 613 int tOp; /* operator from special target */ 614 Lst sources; /* list of source names after expansion */ 615 Lst curTargs; /* list of target names to be found and added 616 * to the targets list */ 617 618 tOp = 0; 619 620 specType = Not; 621 paths = (Lst)NULL; 622 623 curTargs = Lst_Init(FALSE); 624 625 do { 626 for (cp = line; 627 *cp && !isspace (*cp) && 628 (*cp != '!') && (*cp != ':') && (*cp != '('); 629 cp++) 630 { 631 if (*cp == '$') { 632 /* 633 * Must be a dynamic source (would have been expanded 634 * otherwise), so call the Var module to parse the puppy 635 * so we can safely advance beyond it...There should be 636 * no errors in this, as they would have been discovered 637 * in the initial Var_Subst and we wouldn't be here. 638 */ 639 int length; 640 Boolean freeIt; 641 char *result; 642 643 result=Var_Parse(cp, VAR_CMD, TRUE, &length, &freeIt); 644 645 if (freeIt) { 646 free(result); 647 } 648 cp += length-1; 649 } 650 continue; 651 } 652 if (*cp == '(') { 653 /* 654 * Archives must be handled specially to make sure the OP_ARCHV 655 * flag is set in their 'type' field, for one thing, and because 656 * things like "archive(file1.o file2.o file3.o)" are permissible. 657 * Arch_ParseArchive will set 'line' to be the first non-blank 658 * after the archive-spec. It creates/finds nodes for the members 659 * and places them on the given list, returning SUCCESS if all 660 * went well and FAILURE if there was an error in the 661 * specification. On error, line should remain untouched. 662 */ 663 if (Arch_ParseArchive (&line, targets, VAR_CMD) != SUCCESS) { 664 Parse_Error (PARSE_FATAL, 665 "Error in archive specification: \"%s\"", line); 666 return; 667 } else { 668 continue; 669 } 670 } 671 savec = *cp; 672 673 if (!*cp) { 674 /* 675 * Ending a dependency line without an operator is a Bozo 676 * no-no 677 */ 678 Parse_Error (PARSE_FATAL, "Need an operator"); 679 return; 680 } 681 *cp = '\0'; 682 /* 683 * Have a word in line. See if it's a special target and set 684 * specType to match it. 685 */ 686 if (*line == '.' && isupper (line[1])) { 687 /* 688 * See if the target is a special target that must have it 689 * or its sources handled specially. 690 */ 691 int keywd = ParseFindKeyword(line); 692 if (keywd != -1) { 693 if (specType == ExPath && parseKeywords[keywd].spec != ExPath) { 694 Parse_Error(PARSE_FATAL, "Mismatched special targets"); 695 return; 696 } 697 698 specType = parseKeywords[keywd].spec; 699 tOp = parseKeywords[keywd].op; 700 701 /* 702 * Certain special targets have special semantics: 703 * .PATH Have to set the dirSearchPath 704 * variable too 705 * .MAIN Its sources are only used if 706 * nothing has been specified to 707 * create. 708 * .DEFAULT Need to create a node to hang 709 * commands on, but we don't want 710 * it in the graph, nor do we want 711 * it to be the Main Target, so we 712 * create it, set OP_NOTMAIN and 713 * add it to the list, setting 714 * DEFAULT to the new node for 715 * later use. We claim the node is 716 * A transformation rule to make 717 * life easier later, when we'll 718 * use Make_HandleUse to actually 719 * apply the .DEFAULT commands. 720 * .BEGIN 721 * .END 722 * .INTERRUPT Are not to be considered the 723 * main target. 724 * .NOTPARALLEL Make only one target at a time. 725 * .SINGLESHELL Create a shell for each command. 726 * .ORDER Must set initial predecessor to NIL 727 */ 728 switch (specType) { 729 case ExPath: 730 if (paths == NULL) { 731 paths = Lst_Init(FALSE); 732 } 733 (void)Lst_AtEnd(paths, (ClientData)dirSearchPath); 734 break; 735 case Main: 736 if (!Lst_IsEmpty(create)) { 737 specType = Not; 738 } 739 break; 740 case Begin: 741 case End: 742 case Interrupt: 743 gn = Targ_FindNode(line, TARG_CREATE); 744 gn->type |= OP_NOTMAIN; 745 (void)Lst_AtEnd(targets, (ClientData)gn); 746 break; 747 case Default: 748 gn = Targ_NewGN(".DEFAULT"); 749 gn->type |= (OP_NOTMAIN|OP_TRANSFORM); 750 (void)Lst_AtEnd(targets, (ClientData)gn); 751 DEFAULT = gn; 752 break; 753 case NotParallel: 754 { 755 extern int maxJobs; 756 757 maxJobs = 1; 758 break; 759 } 760 case SingleShell: 761 compatMake = 1; 762 break; 763 case Order: 764 predecessor = NILGNODE; 765 break; 766 default: 767 break; 768 } 769 } else if (strncmp (line, ".PATH", 5) == 0) { 770 /* 771 * .PATH<suffix> has to be handled specially. 772 * Call on the suffix module to give us a path to 773 * modify. 774 */ 775 Lst path; 776 777 specType = ExPath; 778 path = Suff_GetPath (&line[5]); 779 if (path == NILLST) { 780 Parse_Error (PARSE_FATAL, 781 "Suffix '%s' not defined (yet)", 782 &line[5]); 783 return; 784 } else { 785 if (paths == (Lst)NULL) { 786 paths = Lst_Init(FALSE); 787 } 788 (void)Lst_AtEnd(paths, (ClientData)path); 789 } 790 } 791 } 792 793 /* 794 * Have word in line. Get or create its node and stick it at 795 * the end of the targets list 796 */ 797 if ((specType == Not) && (*line != '\0')) { 798 if (Dir_HasWildcards(line)) { 799 /* 800 * Targets are to be sought only in the current directory, 801 * so create an empty path for the thing. Note we need to 802 * use Dir_Destroy in the destruction of the path as the 803 * Dir module could have added a directory to the path... 804 */ 805 Lst emptyPath = Lst_Init(FALSE); 806 807 Dir_Expand(line, emptyPath, curTargs); 808 809 Lst_Destroy(emptyPath, Dir_Destroy); 810 } else { 811 /* 812 * No wildcards, but we want to avoid code duplication, 813 * so create a list with the word on it. 814 */ 815 (void)Lst_AtEnd(curTargs, (ClientData)line); 816 } 817 818 while(!Lst_IsEmpty(curTargs)) { 819 char *targName = (char *)Lst_DeQueue(curTargs); 820 821 if (!Suff_IsTransform (targName)) { 822 gn = Targ_FindNode (targName, TARG_CREATE); 823 } else { 824 gn = Suff_AddTransform (targName); 825 } 826 827 (void)Lst_AtEnd (targets, (ClientData)gn); 828 } 829 } else if (specType == ExPath && *line != '.' && *line != '\0') { 830 Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line); 831 } 832 833 *cp = savec; 834 /* 835 * If it is a special type and not .PATH, it's the only target we 836 * allow on this line... 837 */ 838 if (specType != Not && specType != ExPath) { 839 Boolean warn = FALSE; 840 841 while ((*cp != '!') && (*cp != ':') && *cp) { 842 if (*cp != ' ' && *cp != '\t') { 843 warn = TRUE; 844 } 845 cp++; 846 } 847 if (warn) { 848 Parse_Error(PARSE_WARNING, "Extra target ignored"); 849 } 850 } else { 851 while (*cp && isspace (*cp)) { 852 cp++; 853 } 854 } 855 line = cp; 856 } while ((*line != '!') && (*line != ':') && *line); 857 858 /* 859 * Don't need the list of target names anymore... 860 */ 861 Lst_Destroy(curTargs, NOFREE); 862 863 if (!Lst_IsEmpty(targets)) { 864 switch(specType) { 865 default: 866 Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored"); 867 break; 868 case Default: 869 case Begin: 870 case End: 871 case Interrupt: 872 /* 873 * These four create nodes on which to hang commands, so 874 * targets shouldn't be empty... 875 */ 876 case Not: 877 /* 878 * Nothing special here -- targets can be empty if it wants. 879 */ 880 break; 881 } 882 } 883 884 /* 885 * Have now parsed all the target names. Must parse the operator next. The 886 * result is left in op . 887 */ 888 if (*cp == '!') { 889 op = OP_FORCE; 890 } else if (*cp == ':') { 891 if (cp[1] == ':') { 892 op = OP_DOUBLEDEP; 893 cp++; 894 } else { 895 op = OP_DEPENDS; 896 } 897 } else { 898 Parse_Error (PARSE_FATAL, "Missing dependency operator"); 899 return; 900 } 901 902 cp++; /* Advance beyond operator */ 903 904 Lst_ForEach (targets, ParseDoOp, (ClientData)op); 905 906 /* 907 * Get to the first source 908 */ 909 while (*cp && isspace (*cp)) { 910 cp++; 911 } 912 line = cp; 913 914 /* 915 * Several special targets take different actions if present with no 916 * sources: 917 * a .SUFFIXES line with no sources clears out all old suffixes 918 * a .PRECIOUS line makes all targets precious 919 * a .IGNORE line ignores errors for all targets 920 * a .SILENT line creates silence when making all targets 921 * a .PATH removes all directories from the search path(s). 922 */ 923 if (!*line) { 924 switch (specType) { 925 case Suffixes: 926 Suff_ClearSuffixes (); 927 break; 928 case Precious: 929 allPrecious = TRUE; 930 break; 931 case Ignore: 932 ignoreErrors = TRUE; 933 break; 934 case Silent: 935 beSilent = TRUE; 936 break; 937 case ExPath: 938 Lst_ForEach(paths, ParseClearPath, (ClientData)NULL); 939 break; 940 default: 941 break; 942 } 943 } else if (specType == MFlags) { 944 /* 945 * Call on functions in main.c to deal with these arguments and 946 * set the initial character to a null-character so the loop to 947 * get sources won't get anything 948 */ 949 Main_ParseArgLine (line); 950 *line = '\0'; 951 } else if (specType == ExShell) { 952 if (Job_ParseShell (line) != SUCCESS) { 953 Parse_Error (PARSE_FATAL, "improper shell specification"); 954 return; 955 } 956 *line = '\0'; 957 } else if ((specType == NotParallel) || (specType == SingleShell)) { 958 *line = '\0'; 959 } 960 961 /* 962 * NOW GO FOR THE SOURCES 963 */ 964 if ((specType == Suffixes) || (specType == ExPath) || 965 (specType == Includes) || (specType == Libs) || 966 (specType == Null)) 967 { 968 while (*line) { 969 /* 970 * If the target was one that doesn't take files as its sources 971 * but takes something like suffixes, we take each 972 * space-separated word on the line as a something and deal 973 * with it accordingly. 974 * 975 * If the target was .SUFFIXES, we take each source as a 976 * suffix and add it to the list of suffixes maintained by the 977 * Suff module. 978 * 979 * If the target was a .PATH, we add the source as a directory 980 * to search on the search path. 981 * 982 * If it was .INCLUDES, the source is taken to be the suffix of 983 * files which will be #included and whose search path should 984 * be present in the .INCLUDES variable. 985 * 986 * If it was .LIBS, the source is taken to be the suffix of 987 * files which are considered libraries and whose search path 988 * should be present in the .LIBS variable. 989 * 990 * If it was .NULL, the source is the suffix to use when a file 991 * has no valid suffix. 992 */ 993 char savec; 994 while (*cp && !isspace (*cp)) { 995 cp++; 996 } 997 savec = *cp; 998 *cp = '\0'; 999 switch (specType) { 1000 case Suffixes: 1001 Suff_AddSuffix (line); 1002 break; 1003 case ExPath: 1004 Lst_ForEach(paths, ParseAddDir, (ClientData)line); 1005 break; 1006 case Includes: 1007 Suff_AddInclude (line); 1008 break; 1009 case Libs: 1010 Suff_AddLib (line); 1011 break; 1012 case Null: 1013 Suff_SetNull (line); 1014 break; 1015 default: 1016 break; 1017 } 1018 *cp = savec; 1019 if (savec != '\0') { 1020 cp++; 1021 } 1022 while (*cp && isspace (*cp)) { 1023 cp++; 1024 } 1025 line = cp; 1026 } 1027 if (paths) { 1028 Lst_Destroy(paths, NOFREE); 1029 } 1030 } else { 1031 while (*line) { 1032 /* 1033 * The targets take real sources, so we must beware of archive 1034 * specifications (i.e. things with left parentheses in them) 1035 * and handle them accordingly. 1036 */ 1037 while (*cp && !isspace (*cp)) { 1038 if ((*cp == '(') && (cp > line) && (cp[-1] != '$')) { 1039 /* 1040 * Only stop for a left parenthesis if it isn't at the 1041 * start of a word (that'll be for variable changes 1042 * later) and isn't preceded by a dollar sign (a dynamic 1043 * source). 1044 */ 1045 break; 1046 } else { 1047 cp++; 1048 } 1049 } 1050 1051 if (*cp == '(') { 1052 GNode *gn; 1053 1054 sources = Lst_Init (FALSE); 1055 if (Arch_ParseArchive (&line, sources, VAR_CMD) != SUCCESS) { 1056 Parse_Error (PARSE_FATAL, 1057 "Error in source archive spec \"%s\"", line); 1058 return; 1059 } 1060 1061 while (!Lst_IsEmpty (sources)) { 1062 gn = (GNode *) Lst_DeQueue (sources); 1063 ParseDoSrc (tOp, gn->name); 1064 } 1065 Lst_Destroy (sources, NOFREE); 1066 cp = line; 1067 } else { 1068 if (*cp) { 1069 *cp = '\0'; 1070 cp += 1; 1071 } 1072 1073 ParseDoSrc (tOp, line); 1074 } 1075 while (*cp && isspace (*cp)) { 1076 cp++; 1077 } 1078 line = cp; 1079 } 1080 } 1081 1082 if (mainNode == NILGNODE) { 1083 /* 1084 * If we have yet to decide on a main target to make, in the 1085 * absence of any user input, we want the first target on 1086 * the first dependency line that is actually a real target 1087 * (i.e. isn't a .USE or .EXEC rule) to be made. 1088 */ 1089 Lst_ForEach (targets, ParseFindMain, (ClientData)0); 1090 } 1091 1092 } 1093 1094 /*- 1095 *--------------------------------------------------------------------- 1096 * Parse_IsVar -- 1097 * Return TRUE if the passed line is a variable assignment. A variable 1098 * assignment consists of a single word followed by optional whitespace 1099 * followed by either a += or an = operator. 1100 * This function is used both by the Parse_File function and main when 1101 * parsing the command-line arguments. 1102 * 1103 * Results: 1104 * TRUE if it is. FALSE if it ain't 1105 * 1106 * Side Effects: 1107 * none 1108 *--------------------------------------------------------------------- 1109 */ 1110 Boolean 1111 Parse_IsVar (line) 1112 register char *line; /* the line to check */ 1113 { 1114 register Boolean wasSpace = FALSE; /* set TRUE if found a space */ 1115 register Boolean haveName = FALSE; /* Set TRUE if have a variable name */ 1116 1117 /* 1118 * Skip to variable name 1119 */ 1120 while ((*line == ' ') || (*line == '\t')) { 1121 line++; 1122 } 1123 1124 while (*line != '=') { 1125 if (*line == '\0') { 1126 /* 1127 * end-of-line -- can't be a variable assignment. 1128 */ 1129 return (FALSE); 1130 } else if ((*line == ' ') || (*line == '\t')) { 1131 /* 1132 * there can be as much white space as desired so long as there is 1133 * only one word before the operator 1134 */ 1135 wasSpace = TRUE; 1136 } else if (wasSpace && haveName) { 1137 /* 1138 * Stop when an = operator is found. 1139 */ 1140 if ((*line == '+') || (*line == ':') || (*line == '?') || 1141 (*line == '!')) { 1142 break; 1143 } 1144 1145 /* 1146 * This is the start of another word, so not assignment. 1147 */ 1148 return (FALSE); 1149 } else { 1150 haveName = TRUE; 1151 wasSpace = FALSE; 1152 } 1153 line++; 1154 } 1155 1156 /* 1157 * A final check: if we stopped on a +, ?, ! or :, the next character must 1158 * be an = or it ain't a valid assignment 1159 */ 1160 if (((*line == '+') || 1161 (*line == '?') || 1162 (*line == ':') || 1163 (*line == '!')) && 1164 (line[1] != '=')) 1165 { 1166 return (FALSE); 1167 } else { 1168 return (haveName); 1169 } 1170 } 1171 1172 /*- 1173 *--------------------------------------------------------------------- 1174 * Parse_DoVar -- 1175 * Take the variable assignment in the passed line and do it in the 1176 * global context. 1177 * 1178 * Note: There is a lexical ambiguity with assignment modifier characters 1179 * in variable names. This routine interprets the character before the = 1180 * as a modifier. Therefore, an assignment like 1181 * C++=/usr/bin/CC 1182 * is interpreted as "C+ +=" instead of "C++ =". 1183 * 1184 * Results: 1185 * none 1186 * 1187 * Side Effects: 1188 * the variable structure of the given variable name is altered in the 1189 * global context. 1190 *--------------------------------------------------------------------- 1191 */ 1192 void 1193 Parse_DoVar (line, ctxt) 1194 char *line; /* a line guaranteed to be a variable 1195 * assignment. This reduces error checks */ 1196 GNode *ctxt; /* Context in which to do the assignment */ 1197 { 1198 register char *cp; /* pointer into line */ 1199 enum { 1200 VAR_SUBST, VAR_APPEND, VAR_SHELL, VAR_NORMAL 1201 } type; /* Type of assignment */ 1202 char *opc; /* ptr to operator character to 1203 * null-terminate the variable name */ 1204 1205 /* 1206 * Skip to variable name 1207 */ 1208 while ((*line == ' ') || (*line == '\t')) { 1209 line++; 1210 } 1211 1212 /* 1213 * Skip to operator character, nulling out whitespace as we go 1214 */ 1215 for (cp = line + 1; *cp != '='; cp++) { 1216 if (isspace (*cp)) { 1217 *cp = '\0'; 1218 } 1219 } 1220 opc = cp-1; /* operator is the previous character */ 1221 *cp++ = '\0'; /* nuke the = */ 1222 1223 /* 1224 * Check operator type 1225 */ 1226 switch (*opc) { 1227 case '+': 1228 type = VAR_APPEND; 1229 *opc = '\0'; 1230 break; 1231 1232 case '?': 1233 /* 1234 * If the variable already has a value, we don't do anything. 1235 */ 1236 *opc = '\0'; 1237 if (Var_Exists(line, ctxt)) { 1238 return; 1239 } else { 1240 type = VAR_NORMAL; 1241 } 1242 break; 1243 1244 case ':': 1245 type = VAR_SUBST; 1246 *opc = '\0'; 1247 break; 1248 1249 case '!': 1250 type = VAR_SHELL; 1251 *opc = '\0'; 1252 break; 1253 1254 default: 1255 type = VAR_NORMAL; 1256 break; 1257 } 1258 1259 while (isspace (*cp)) { 1260 cp++; 1261 } 1262 1263 if (type == VAR_APPEND) { 1264 Var_Append (line, cp, ctxt); 1265 } else if (type == VAR_SUBST) { 1266 /* 1267 * Allow variables in the old value to be undefined, but leave their 1268 * invocation alone -- this is done by forcing oldVars to be false. 1269 * XXX: This can cause recursive variables, but that's not hard to do, 1270 * and this allows someone to do something like 1271 * 1272 * CFLAGS = $(.INCLUDES) 1273 * CFLAGS := -I.. $(CFLAGS) 1274 * 1275 * And not get an error. 1276 */ 1277 Boolean oldOldVars = oldVars; 1278 1279 oldVars = FALSE; 1280 cp = Var_Subst(NULL, cp, ctxt, FALSE); 1281 oldVars = oldOldVars; 1282 1283 Var_Set(line, cp, ctxt); 1284 free(cp); 1285 } else if (type == VAR_SHELL) { 1286 char *args[4]; /* Args for invoking the shell */ 1287 int fds[2]; /* Pipe streams */ 1288 int cpid; /* Child PID */ 1289 int pid; /* PID from wait() */ 1290 Boolean freeCmd; /* TRUE if the command needs to be freed, i.e. 1291 * if any variable expansion was performed */ 1292 1293 1294 /* 1295 * Set up arguments for shell 1296 */ 1297 args[0] = "sh"; 1298 args[1] = "-c"; 1299 if (strchr(cp, '$') != (char *)NULL) { 1300 /* 1301 * There's a dollar sign in the command, so perform variable 1302 * expansion on the whole thing. The resulting string will need 1303 * freeing when we're done, so set freeCmd to TRUE. 1304 */ 1305 args[2] = Var_Subst(NULL, cp, VAR_CMD, TRUE); 1306 freeCmd = TRUE; 1307 } else { 1308 args[2] = cp; 1309 freeCmd = FALSE; 1310 } 1311 args[3] = (char *)NULL; 1312 1313 /* 1314 * Open a pipe for fetching its output 1315 */ 1316 pipe(fds); 1317 1318 /* 1319 * Fork 1320 */ 1321 cpid = vfork(); 1322 if (cpid == 0) { 1323 /* 1324 * Close input side of pipe 1325 */ 1326 close(fds[0]); 1327 1328 /* 1329 * Duplicate the output stream to the shell's output, then 1330 * shut the extra thing down. Note we don't fetch the error 1331 * stream...why not? Why? 1332 */ 1333 dup2(fds[1], 1); 1334 close(fds[1]); 1335 1336 execv("/bin/sh", args); 1337 _exit(1); 1338 } else if (cpid < 0) { 1339 /* 1340 * Couldn't fork -- tell the user and make the variable null 1341 */ 1342 Parse_Error(PARSE_WARNING, "Couldn't exec \"%s\"", cp); 1343 Var_Set(line, "", ctxt); 1344 } else { 1345 int status; 1346 int cc; 1347 Buffer buf; 1348 char *res; 1349 1350 /* 1351 * No need for the writing half 1352 */ 1353 close(fds[1]); 1354 1355 buf = Buf_Init (MAKE_BSIZE); 1356 1357 do { 1358 char result[BUFSIZ]; 1359 cc = read(fds[0], result, sizeof(result)); 1360 if (cc > 0) 1361 Buf_AddBytes(buf, cc, (unsigned char *) result); 1362 } 1363 while (cc > 0 || (cc == -1 && errno == EINTR)); 1364 1365 /* 1366 * Close the input side of the pipe. 1367 */ 1368 close(fds[0]); 1369 1370 /* 1371 * Wait for the process to exit. 1372 */ 1373 while(((pid = wait(&status)) != cpid) && (pid >= 0)) 1374 continue; 1375 1376 res = (char *)Buf_GetAll (buf, &cc); 1377 Buf_Destroy (buf, FALSE); 1378 1379 if (cc == 0) { 1380 /* 1381 * Couldn't read the child's output -- tell the user and 1382 * set the variable to null 1383 */ 1384 Parse_Error(PARSE_WARNING, "Couldn't read shell's output"); 1385 } 1386 1387 if (status) { 1388 /* 1389 * Child returned an error -- tell the user but still use 1390 * the result. 1391 */ 1392 Parse_Error(PARSE_WARNING, "\"%s\" returned non-zero", cp); 1393 } 1394 1395 /* 1396 * Null-terminate the result, convert newlines to spaces and 1397 * install it in the variable. 1398 */ 1399 res[cc] = '\0'; 1400 cp = &res[cc] - 1; 1401 1402 if (*cp == '\n') { 1403 /* 1404 * A final newline is just stripped 1405 */ 1406 *cp-- = '\0'; 1407 } 1408 while (cp >= res) { 1409 if (*cp == '\n') { 1410 *cp = ' '; 1411 } 1412 cp--; 1413 } 1414 Var_Set(line, res, ctxt); 1415 free(res); 1416 1417 } 1418 if (freeCmd) { 1419 free(args[2]); 1420 } 1421 } else { 1422 /* 1423 * Normal assignment -- just do it. 1424 */ 1425 Var_Set (line, cp, ctxt); 1426 } 1427 } 1428 1429 /*- 1430 * ParseAddCmd -- 1431 * Lst_ForEach function to add a command line to all targets 1432 * 1433 * Results: 1434 * Always 0 1435 * 1436 * Side Effects: 1437 * A new element is added to the commands list of the node. 1438 */ 1439 static int 1440 ParseAddCmd(gn, cmd) 1441 GNode *gn; /* the node to which the command is to be added */ 1442 char *cmd; /* the command to add */ 1443 { 1444 /* if target already supplied, ignore commands */ 1445 if (!(gn->type & OP_HAS_COMMANDS)) 1446 (void)Lst_AtEnd(gn->commands, (ClientData)cmd); 1447 return(0); 1448 } 1449 1450 /*- 1451 *----------------------------------------------------------------------- 1452 * ParseHasCommands -- 1453 * Callback procedure for Parse_File when destroying the list of 1454 * targets on the last dependency line. Marks a target as already 1455 * having commands if it does, to keep from having shell commands 1456 * on multiple dependency lines. 1457 * 1458 * Results: 1459 * Always 0. 1460 * 1461 * Side Effects: 1462 * OP_HAS_COMMANDS may be set for the target. 1463 * 1464 *----------------------------------------------------------------------- 1465 */ 1466 static int 1467 ParseHasCommands(gn) 1468 GNode *gn; /* Node to examine */ 1469 { 1470 if (!Lst_IsEmpty(gn->commands)) { 1471 gn->type |= OP_HAS_COMMANDS; 1472 } 1473 return(0); 1474 } 1475 1476 /*- 1477 *----------------------------------------------------------------------- 1478 * Parse_AddIncludeDir -- 1479 * Add a directory to the path searched for included makefiles 1480 * bracketed by double-quotes. Used by functions in main.c 1481 * 1482 * Results: 1483 * None. 1484 * 1485 * Side Effects: 1486 * The directory is appended to the list. 1487 * 1488 *----------------------------------------------------------------------- 1489 */ 1490 void 1491 Parse_AddIncludeDir (dir) 1492 char *dir; /* The name of the directory to add */ 1493 { 1494 Dir_AddDir (parseIncPath, dir); 1495 } 1496 1497 /*- 1498 *--------------------------------------------------------------------- 1499 * ParseDoInclude -- 1500 * Push to another file. 1501 * 1502 * The input is the line minus the #include. A file spec is a string 1503 * enclosed in <> or "". The former is looked for only in sysIncPath. 1504 * The latter in . and the directories specified by -I command line 1505 * options 1506 * 1507 * Results: 1508 * None 1509 * 1510 * Side Effects: 1511 * A structure is added to the includes Lst and readProc, lineno, 1512 * fname and curFILE are altered for the new file 1513 *--------------------------------------------------------------------- 1514 */ 1515 static void 1516 ParseDoInclude (file) 1517 char *file; /* file specification */ 1518 { 1519 char *fullname; /* full pathname of file */ 1520 IFile *oldFile; /* state associated with current file */ 1521 char endc; /* the character which ends the file spec */ 1522 char *cp; /* current position in file spec */ 1523 Boolean isSystem; /* TRUE if makefile is a system makefile */ 1524 1525 /* 1526 * Skip to delimiter character so we know where to look 1527 */ 1528 while ((*file == ' ') || (*file == '\t')) { 1529 file++; 1530 } 1531 1532 if ((*file != '"') && (*file != '<')) { 1533 Parse_Error (PARSE_FATAL, 1534 ".include filename must be delimited by '\"' or '<'"); 1535 return; 1536 } 1537 1538 /* 1539 * Set the search path on which to find the include file based on the 1540 * characters which bracket its name. Angle-brackets imply it's 1541 * a system Makefile while double-quotes imply it's a user makefile 1542 */ 1543 if (*file == '<') { 1544 isSystem = TRUE; 1545 endc = '>'; 1546 } else { 1547 isSystem = FALSE; 1548 endc = '"'; 1549 } 1550 1551 /* 1552 * Skip to matching delimiter 1553 */ 1554 for (cp = ++file; *cp && *cp != endc; cp++) { 1555 continue; 1556 } 1557 1558 if (*cp != endc) { 1559 Parse_Error (PARSE_FATAL, 1560 "Unclosed %cinclude filename. '%c' expected", 1561 '.', endc); 1562 return; 1563 } 1564 *cp = '\0'; 1565 1566 /* 1567 * Substitute for any variables in the file name before trying to 1568 * find the thing. 1569 */ 1570 file = Var_Subst (NULL, file, VAR_CMD, FALSE); 1571 1572 /* 1573 * Now we know the file's name and its search path, we attempt to 1574 * find the durn thing. A return of NULL indicates the file don't 1575 * exist. 1576 */ 1577 if (!isSystem) { 1578 /* 1579 * Include files contained in double-quotes are first searched for 1580 * relative to the including file's location. We don't want to 1581 * cd there, of course, so we just tack on the old file's 1582 * leading path components and call Dir_FindFile to see if 1583 * we can locate the beast. 1584 */ 1585 char *prefEnd; 1586 1587 prefEnd = strrchr (fname, '/'); 1588 if (prefEnd != (char *)NULL) { 1589 char *newName; 1590 1591 *prefEnd = '\0'; 1592 newName = str_concat (fname, file, STR_ADDSLASH); 1593 fullname = Dir_FindFile (newName, parseIncPath); 1594 if (fullname == (char *)NULL) { 1595 fullname = Dir_FindFile(newName, dirSearchPath); 1596 } 1597 free (newName); 1598 *prefEnd = '/'; 1599 } else { 1600 fullname = (char *)NULL; 1601 } 1602 } else { 1603 fullname = (char *)NULL; 1604 } 1605 1606 if (fullname == (char *)NULL) { 1607 /* 1608 * System makefile or makefile wasn't found in same directory as 1609 * included makefile. Search for it first on the -I search path, 1610 * then on the .PATH search path, if not found in a -I directory. 1611 * XXX: Suffix specific? 1612 */ 1613 fullname = Dir_FindFile (file, parseIncPath); 1614 if (fullname == (char *)NULL) { 1615 fullname = Dir_FindFile(file, dirSearchPath); 1616 } 1617 } 1618 1619 if (fullname == (char *)NULL) { 1620 /* 1621 * Still haven't found the makefile. Look for it on the system 1622 * path as a last resort. 1623 */ 1624 fullname = Dir_FindFile(file, sysIncPath); 1625 } 1626 1627 if (fullname == (char *) NULL) { 1628 *cp = endc; 1629 Parse_Error (PARSE_FATAL, "Could not find %s", file); 1630 return; 1631 } 1632 1633 /* 1634 * Once we find the absolute path to the file, we get to save all the 1635 * state from the current file before we can start reading this 1636 * include file. The state is stored in an IFile structure which 1637 * is placed on a list with other IFile structures. The list makes 1638 * a very nice stack to track how we got here... 1639 */ 1640 oldFile = (IFile *) emalloc (sizeof (IFile)); 1641 oldFile->fname = fname; 1642 1643 oldFile->F = curFILE; 1644 oldFile->p = curPTR; 1645 oldFile->lineno = lineno; 1646 1647 (void) Lst_AtFront (includes, (ClientData)oldFile); 1648 1649 /* 1650 * Once the previous state has been saved, we can get down to reading 1651 * the new file. We set up the name of the file to be the absolute 1652 * name of the include file so error messages refer to the right 1653 * place. Naturally enough, we start reading at line number 0. 1654 */ 1655 fname = fullname; 1656 lineno = 0; 1657 1658 curFILE = fopen (fullname, "r"); 1659 curPTR = NULL; 1660 if (curFILE == (FILE * ) NULL) { 1661 Parse_Error (PARSE_FATAL, "Cannot open %s", fullname); 1662 /* 1663 * Pop to previous file 1664 */ 1665 (void) ParseEOF(0); 1666 } 1667 } 1668 1669 1670 /*- 1671 *--------------------------------------------------------------------- 1672 * Parse_FromString -- 1673 * Start Parsing from the given string 1674 * 1675 * Results: 1676 * None 1677 * 1678 * Side Effects: 1679 * A structure is added to the includes Lst and readProc, lineno, 1680 * fname and curFILE are altered for the new file 1681 *--------------------------------------------------------------------- 1682 */ 1683 void 1684 Parse_FromString(str) 1685 char *str; 1686 { 1687 IFile *oldFile; /* state associated with this file */ 1688 1689 if (DEBUG(FOR)) 1690 (void) fprintf(stderr, "%s\n----\n", str); 1691 1692 oldFile = (IFile *) emalloc (sizeof (IFile)); 1693 oldFile->lineno = lineno; 1694 oldFile->fname = fname; 1695 oldFile->F = curFILE; 1696 oldFile->p = curPTR; 1697 1698 (void) Lst_AtFront (includes, (ClientData)oldFile); 1699 1700 curFILE = NULL; 1701 curPTR = (PTR *) emalloc (sizeof (PTR)); 1702 curPTR->str = curPTR->ptr = str; 1703 lineno = 0; 1704 fname = strdup(fname); 1705 } 1706 1707 1708 #ifdef SYSVINCLUDE 1709 /*- 1710 *--------------------------------------------------------------------- 1711 * ParseTraditionalInclude -- 1712 * Push to another file. 1713 * 1714 * The input is the line minus the "include". The file name is 1715 * the string following the "include". 1716 * 1717 * Results: 1718 * None 1719 * 1720 * Side Effects: 1721 * A structure is added to the includes Lst and readProc, lineno, 1722 * fname and curFILE are altered for the new file 1723 *--------------------------------------------------------------------- 1724 */ 1725 static void 1726 ParseTraditionalInclude (file) 1727 char *file; /* file specification */ 1728 { 1729 char *fullname; /* full pathname of file */ 1730 IFile *oldFile; /* state associated with current file */ 1731 char *cp; /* current position in file spec */ 1732 char *prefEnd; 1733 1734 /* 1735 * Skip over whitespace 1736 */ 1737 while ((*file == ' ') || (*file == '\t')) { 1738 file++; 1739 } 1740 1741 if (*file == '\0') { 1742 Parse_Error (PARSE_FATAL, 1743 "Filename missing from \"include\""); 1744 return; 1745 } 1746 1747 /* 1748 * Skip to end of line or next whitespace 1749 */ 1750 for (cp = file; *cp && *cp != '\n' && *cp != '\t' && *cp != ' '; cp++) { 1751 continue; 1752 } 1753 1754 *cp = '\0'; 1755 1756 /* 1757 * Substitute for any variables in the file name before trying to 1758 * find the thing. 1759 */ 1760 file = Var_Subst (NULL, file, VAR_CMD, FALSE); 1761 1762 /* 1763 * Now we know the file's name, we attempt to find the durn thing. 1764 * A return of NULL indicates the file don't exist. 1765 * 1766 * Include files are first searched for relative to the including 1767 * file's location. We don't want to cd there, of course, so we 1768 * just tack on the old file's leading path components and call 1769 * Dir_FindFile to see if we can locate the beast. 1770 * XXX - this *does* search in the current directory, right? 1771 */ 1772 1773 prefEnd = strrchr (fname, '/'); 1774 if (prefEnd != (char *)NULL) { 1775 char *newName; 1776 1777 *prefEnd = '\0'; 1778 newName = str_concat (fname, file, STR_ADDSLASH); 1779 fullname = Dir_FindFile (newName, parseIncPath); 1780 if (fullname == (char *)NULL) { 1781 fullname = Dir_FindFile(newName, dirSearchPath); 1782 } 1783 free (newName); 1784 *prefEnd = '/'; 1785 } else { 1786 fullname = (char *)NULL; 1787 } 1788 1789 if (fullname == (char *)NULL) { 1790 /* 1791 * System makefile or makefile wasn't found in same directory as 1792 * included makefile. Search for it first on the -I search path, 1793 * then on the .PATH search path, if not found in a -I directory. 1794 * XXX: Suffix specific? 1795 */ 1796 fullname = Dir_FindFile (file, parseIncPath); 1797 if (fullname == (char *)NULL) { 1798 fullname = Dir_FindFile(file, dirSearchPath); 1799 } 1800 } 1801 1802 if (fullname == (char *)NULL) { 1803 /* 1804 * Still haven't found the makefile. Look for it on the system 1805 * path as a last resort. 1806 */ 1807 fullname = Dir_FindFile(file, sysIncPath); 1808 } 1809 1810 if (fullname == (char *) NULL) { 1811 Parse_Error (PARSE_FATAL, "Could not find %s", file); 1812 return; 1813 } 1814 1815 /* 1816 * Once we find the absolute path to the file, we get to save all the 1817 * state from the current file before we can start reading this 1818 * include file. The state is stored in an IFile structure which 1819 * is placed on a list with other IFile structures. The list makes 1820 * a very nice stack to track how we got here... 1821 */ 1822 oldFile = (IFile *) emalloc (sizeof (IFile)); 1823 oldFile->fname = fname; 1824 1825 oldFile->F = curFILE; 1826 oldFile->p = curPTR; 1827 oldFile->lineno = lineno; 1828 1829 (void) Lst_AtFront (includes, (ClientData)oldFile); 1830 1831 /* 1832 * Once the previous state has been saved, we can get down to reading 1833 * the new file. We set up the name of the file to be the absolute 1834 * name of the include file so error messages refer to the right 1835 * place. Naturally enough, we start reading at line number 0. 1836 */ 1837 fname = fullname; 1838 lineno = 0; 1839 1840 curFILE = fopen (fullname, "r"); 1841 curPTR = NULL; 1842 if (curFILE == (FILE * ) NULL) { 1843 Parse_Error (PARSE_FATAL, "Cannot open %s", fullname); 1844 /* 1845 * Pop to previous file 1846 */ 1847 (void) ParseEOF(1); 1848 } 1849 } 1850 #endif 1851 1852 /*- 1853 *--------------------------------------------------------------------- 1854 * ParseEOF -- 1855 * Called when EOF is reached in the current file. If we were reading 1856 * an include file, the includes stack is popped and things set up 1857 * to go back to reading the previous file at the previous location. 1858 * 1859 * Results: 1860 * CONTINUE if there's more to do. DONE if not. 1861 * 1862 * Side Effects: 1863 * The old curFILE, is closed. The includes list is shortened. 1864 * lineno, curFILE, and fname are changed if CONTINUE is returned. 1865 *--------------------------------------------------------------------- 1866 */ 1867 static int 1868 ParseEOF (opened) 1869 int opened; 1870 { 1871 IFile *ifile; /* the state on the top of the includes stack */ 1872 1873 if (Lst_IsEmpty (includes)) { 1874 return (DONE); 1875 } 1876 1877 ifile = (IFile *) Lst_DeQueue (includes); 1878 free ((Address) fname); 1879 fname = ifile->fname; 1880 lineno = ifile->lineno; 1881 if (opened && curFILE) 1882 (void) fclose (curFILE); 1883 if (curPTR) { 1884 free((Address) curPTR->str); 1885 free((Address) curPTR); 1886 } 1887 curFILE = ifile->F; 1888 curPTR = ifile->p; 1889 free ((Address)ifile); 1890 return (CONTINUE); 1891 } 1892 1893 /*- 1894 *--------------------------------------------------------------------- 1895 * ParseReadc -- 1896 * Read a character from the current file 1897 * 1898 * Results: 1899 * The character that was read 1900 * 1901 * Side Effects: 1902 *--------------------------------------------------------------------- 1903 */ 1904 static int 1905 ParseReadc() 1906 { 1907 if (curFILE) 1908 return fgetc(curFILE); 1909 1910 if (curPTR && *curPTR->ptr) 1911 return *curPTR->ptr++; 1912 return EOF; 1913 } 1914 1915 1916 /*- 1917 *--------------------------------------------------------------------- 1918 * ParseUnreadc -- 1919 * Put back a character to the current file 1920 * 1921 * Results: 1922 * None. 1923 * 1924 * Side Effects: 1925 *--------------------------------------------------------------------- 1926 */ 1927 static void 1928 ParseUnreadc(c) 1929 int c; 1930 { 1931 if (curFILE) { 1932 ungetc(c, curFILE); 1933 return; 1934 } 1935 if (curPTR) { 1936 *--(curPTR->ptr) = c; 1937 return; 1938 } 1939 } 1940 1941 1942 /* ParseSkipLine(): 1943 * Grab the next line 1944 */ 1945 static char * 1946 ParseSkipLine(skip) 1947 int skip; /* Skip lines that don't start with . */ 1948 { 1949 char *line; 1950 int c, lastc = '\0', lineLength; 1951 Buffer buf; 1952 1953 c = ParseReadc(); 1954 1955 if (skip) { 1956 /* 1957 * Skip lines until get to one that begins with a 1958 * special char. 1959 */ 1960 while ((c != '.') && (c != EOF)) { 1961 while (((c != '\n') || (lastc == '\\')) && (c != EOF)) 1962 { 1963 /* 1964 * Advance to next unescaped newline 1965 */ 1966 if ((lastc = c) == '\n') { 1967 lineno++; 1968 } 1969 c = ParseReadc(); 1970 } 1971 lineno++; 1972 1973 lastc = c; 1974 c = ParseReadc (); 1975 } 1976 } 1977 1978 if (c == EOF) { 1979 Parse_Error (PARSE_FATAL, "Unclosed conditional/for loop"); 1980 return ((char *)NULL); 1981 } 1982 1983 /* 1984 * Read the entire line into buf 1985 */ 1986 buf = Buf_Init (MAKE_BSIZE); 1987 if (c != '\n') { 1988 do { 1989 Buf_AddByte (buf, (Byte)c); 1990 c = ParseReadc(); 1991 } while ((c != '\n') && (c != EOF)); 1992 } 1993 lineno++; 1994 1995 Buf_AddByte (buf, (Byte)'\0'); 1996 line = (char *)Buf_GetAll (buf, &lineLength); 1997 Buf_Destroy (buf, FALSE); 1998 return line; 1999 } 2000 2001 2002 /*- 2003 *--------------------------------------------------------------------- 2004 * ParseReadLine -- 2005 * Read an entire line from the input file. Called only by Parse_File. 2006 * To facilitate escaped newlines and what have you, a character is 2007 * buffered in 'lastc', which is '\0' when no characters have been 2008 * read. When we break out of the loop, c holds the terminating 2009 * character and lastc holds a character that should be added to 2010 * the line (unless we don't read anything but a terminator). 2011 * 2012 * Results: 2013 * A line w/o its newline 2014 * 2015 * Side Effects: 2016 * Only those associated with reading a character 2017 *--------------------------------------------------------------------- 2018 */ 2019 static char * 2020 ParseReadLine () 2021 { 2022 Buffer buf; /* Buffer for current line */ 2023 register int c; /* the current character */ 2024 register int lastc; /* The most-recent character */ 2025 Boolean semiNL; /* treat semi-colons as newlines */ 2026 Boolean ignDepOp; /* TRUE if should ignore dependency operators 2027 * for the purposes of setting semiNL */ 2028 Boolean ignComment; /* TRUE if should ignore comments (in a 2029 * shell command */ 2030 char *line; /* Result */ 2031 int lineLength; /* Length of result */ 2032 2033 semiNL = FALSE; 2034 ignDepOp = FALSE; 2035 ignComment = FALSE; 2036 2037 /* 2038 * Handle special-characters at the beginning of the line. Either a 2039 * leading tab (shell command) or pound-sign (possible conditional) 2040 * forces us to ignore comments and dependency operators and treat 2041 * semi-colons as semi-colons (by leaving semiNL FALSE). This also 2042 * discards completely blank lines. 2043 */ 2044 for (;;) { 2045 c = ParseReadc(); 2046 2047 if (c == '\t') { 2048 ignComment = ignDepOp = TRUE; 2049 break; 2050 } else if (c == '\n') { 2051 lineno++; 2052 } else if (c == '#') { 2053 ParseUnreadc(c); 2054 break; 2055 } else { 2056 /* 2057 * Anything else breaks out without doing anything 2058 */ 2059 break; 2060 } 2061 } 2062 2063 if (c != EOF) { 2064 lastc = c; 2065 buf = Buf_Init(MAKE_BSIZE); 2066 2067 while (((c = ParseReadc ()) != '\n' || (lastc == '\\')) && 2068 (c != EOF)) 2069 { 2070 test_char: 2071 switch(c) { 2072 case '\n': 2073 /* 2074 * Escaped newline: read characters until a non-space or an 2075 * unescaped newline and replace them all by a single space. 2076 * This is done by storing the space over the backslash and 2077 * dropping through with the next nonspace. If it is a 2078 * semi-colon and semiNL is TRUE, it will be recognized as a 2079 * newline in the code below this... 2080 */ 2081 lineno++; 2082 lastc = ' '; 2083 while ((c = ParseReadc ()) == ' ' || c == '\t') { 2084 continue; 2085 } 2086 if (c == EOF || c == '\n') { 2087 goto line_read; 2088 } else { 2089 /* 2090 * Check for comments, semiNL's, etc. -- easier than 2091 * ParseUnreadc(c); continue; 2092 */ 2093 goto test_char; 2094 } 2095 /*NOTREACHED*/ 2096 break; 2097 2098 case ';': 2099 /* 2100 * Semi-colon: Need to see if it should be interpreted as a 2101 * newline 2102 */ 2103 if (semiNL) { 2104 /* 2105 * To make sure the command that may be following this 2106 * semi-colon begins with a tab, we push one back into the 2107 * input stream. This will overwrite the semi-colon in the 2108 * buffer. If there is no command following, this does no 2109 * harm, since the newline remains in the buffer and the 2110 * whole line is ignored. 2111 */ 2112 ParseUnreadc('\t'); 2113 goto line_read; 2114 } 2115 break; 2116 case '=': 2117 if (!semiNL) { 2118 /* 2119 * Haven't seen a dependency operator before this, so this 2120 * must be a variable assignment -- don't pay attention to 2121 * dependency operators after this. 2122 */ 2123 ignDepOp = TRUE; 2124 } else if (lastc == ':' || lastc == '!') { 2125 /* 2126 * Well, we've seen a dependency operator already, but it 2127 * was the previous character, so this is really just an 2128 * expanded variable assignment. Revert semi-colons to 2129 * being just semi-colons again and ignore any more 2130 * dependency operators. 2131 * 2132 * XXX: Note that a line like "foo : a:=b" will blow up, 2133 * but who'd write a line like that anyway? 2134 */ 2135 ignDepOp = TRUE; semiNL = FALSE; 2136 } 2137 break; 2138 case '#': 2139 if (!ignComment) { 2140 if (compatMake || (lastc != '\\')) { 2141 /* 2142 * If the character is a hash mark and it isn't escaped 2143 * (or we're being compatible), the thing is a comment. 2144 * Skip to the end of the line. 2145 */ 2146 do { 2147 c = ParseReadc(); 2148 } while ((c != '\n') && (c != EOF)); 2149 goto line_read; 2150 } else { 2151 /* 2152 * Don't add the backslash. Just let the # get copied 2153 * over. 2154 */ 2155 lastc = c; 2156 continue; 2157 } 2158 } 2159 break; 2160 case ':': 2161 case '!': 2162 if (!ignDepOp && (c == ':' || c == '!')) { 2163 /* 2164 * A semi-colon is recognized as a newline only on 2165 * dependency lines. Dependency lines are lines with a 2166 * colon or an exclamation point. Ergo... 2167 */ 2168 semiNL = TRUE; 2169 } 2170 break; 2171 } 2172 /* 2173 * Copy in the previous character and save this one in lastc. 2174 */ 2175 Buf_AddByte (buf, (Byte)lastc); 2176 lastc = c; 2177 2178 } 2179 line_read: 2180 lineno++; 2181 2182 if (lastc != '\0') { 2183 Buf_AddByte (buf, (Byte)lastc); 2184 } 2185 Buf_AddByte (buf, (Byte)'\0'); 2186 line = (char *)Buf_GetAll (buf, &lineLength); 2187 Buf_Destroy (buf, FALSE); 2188 2189 if (line[0] == '.') { 2190 /* 2191 * The line might be a conditional. Ask the conditional module 2192 * about it and act accordingly 2193 */ 2194 switch (Cond_Eval (line)) { 2195 case COND_SKIP: 2196 /* 2197 * Skip to next conditional that evaluates to COND_PARSE. 2198 */ 2199 do { 2200 free (line); 2201 line = ParseSkipLine(1); 2202 } while (line && Cond_Eval(line) != COND_PARSE); 2203 if (line == NULL) 2204 break; 2205 /*FALLTHRU*/ 2206 case COND_PARSE: 2207 free ((Address) line); 2208 line = ParseReadLine(); 2209 break; 2210 case COND_INVALID: 2211 if (For_Eval(line)) { 2212 int ok; 2213 free(line); 2214 do { 2215 /* 2216 * Skip after the matching end 2217 */ 2218 line = ParseSkipLine(0); 2219 if (line == NULL) { 2220 Parse_Error (PARSE_FATAL, 2221 "Unexpected end of file in for loop.\n"); 2222 break; 2223 } 2224 ok = For_Eval(line); 2225 free(line); 2226 } 2227 while (ok); 2228 if (line != NULL) 2229 For_Run(); 2230 line = ParseReadLine(); 2231 } 2232 break; 2233 } 2234 } 2235 return (line); 2236 2237 } else { 2238 /* 2239 * Hit end-of-file, so return a NULL line to indicate this. 2240 */ 2241 return((char *)NULL); 2242 } 2243 } 2244 2245 /*- 2246 *----------------------------------------------------------------------- 2247 * ParseFinishLine -- 2248 * Handle the end of a dependency group. 2249 * 2250 * Results: 2251 * Nothing. 2252 * 2253 * Side Effects: 2254 * inLine set FALSE. 'targets' list destroyed. 2255 * 2256 *----------------------------------------------------------------------- 2257 */ 2258 static void 2259 ParseFinishLine() 2260 { 2261 extern int Suff_EndTransform(); 2262 2263 if (inLine) { 2264 Lst_ForEach(targets, Suff_EndTransform, (ClientData)NULL); 2265 Lst_Destroy (targets, ParseHasCommands); 2266 inLine = FALSE; 2267 } 2268 } 2269 2270 2271 /*- 2272 *--------------------------------------------------------------------- 2273 * Parse_File -- 2274 * Parse a file into its component parts, incorporating it into the 2275 * current dependency graph. This is the main function and controls 2276 * almost every other function in this module 2277 * 2278 * Results: 2279 * None 2280 * 2281 * Side Effects: 2282 * Loads. Nodes are added to the list of all targets, nodes and links 2283 * are added to the dependency graph. etc. etc. etc. 2284 *--------------------------------------------------------------------- 2285 */ 2286 void 2287 Parse_File(name, stream) 2288 char *name; /* the name of the file being read */ 2289 FILE * stream; /* Stream open to makefile to parse */ 2290 { 2291 register char *cp, /* pointer into the line */ 2292 *line; /* the line we're working on */ 2293 2294 inLine = FALSE; 2295 fname = name; 2296 curFILE = stream; 2297 lineno = 0; 2298 fatals = 0; 2299 2300 do { 2301 while ((line = ParseReadLine ()) != NULL) { 2302 if (*line == '.') { 2303 /* 2304 * Lines that begin with the special character are either 2305 * include or undef directives. 2306 */ 2307 for (cp = line + 1; isspace (*cp); cp++) { 2308 continue; 2309 } 2310 if (strncmp (cp, "include", 7) == 0) { 2311 ParseDoInclude (cp + 7); 2312 goto nextLine; 2313 } else if (strncmp(cp, "undef", 5) == 0) { 2314 char *cp2; 2315 for (cp += 5; isspace(*cp); cp++) { 2316 continue; 2317 } 2318 2319 for (cp2 = cp; !isspace(*cp2) && (*cp2 != '\0'); cp2++) { 2320 continue; 2321 } 2322 2323 *cp2 = '\0'; 2324 2325 Var_Delete(cp, VAR_GLOBAL); 2326 goto nextLine; 2327 } 2328 } 2329 if (*line == '#') { 2330 /* If we're this far, the line must be a comment. */ 2331 goto nextLine; 2332 } 2333 2334 if (*line == '\t' 2335 #ifdef POSIX 2336 || *line == ' ' 2337 #endif 2338 ) 2339 { 2340 /* 2341 * If a line starts with a tab (or space in POSIX-land), it 2342 * can only hope to be a creation command. 2343 */ 2344 shellCommand: 2345 for (cp = line + 1; isspace (*cp); cp++) { 2346 continue; 2347 } 2348 if (*cp) { 2349 if (inLine) { 2350 /* 2351 * So long as it's not a blank line and we're actually 2352 * in a dependency spec, add the command to the list of 2353 * commands of all targets in the dependency spec 2354 */ 2355 Lst_ForEach (targets, ParseAddCmd, (ClientData)cp); 2356 continue; 2357 } else { 2358 Parse_Error (PARSE_FATAL, 2359 "Unassociated shell command \"%.20s\"", 2360 cp); 2361 } 2362 } 2363 #ifdef SYSVINCLUDE 2364 } else if (strncmp (line, "include", 7) == 0 && 2365 strchr(line, ':') == NULL) { 2366 /* 2367 * It's an S3/S5-style "include". 2368 */ 2369 ParseTraditionalInclude (line + 7); 2370 goto nextLine; 2371 #endif 2372 } else if (Parse_IsVar (line)) { 2373 ParseFinishLine(); 2374 Parse_DoVar (line, VAR_GLOBAL); 2375 } else { 2376 /* 2377 * We now know it's a dependency line so it needs to have all 2378 * variables expanded before being parsed. Tell the variable 2379 * module to complain if some variable is undefined... 2380 * To make life easier on novices, if the line is indented we 2381 * first make sure the line has a dependency operator in it. 2382 * If it doesn't have an operator and we're in a dependency 2383 * line's script, we assume it's actually a shell command 2384 * and add it to the current list of targets. 2385 * 2386 * Note that POSIX declares all lines that start with 2387 * whitespace are shell commands, so there's no need to check 2388 * here... 2389 */ 2390 Boolean nonSpace = FALSE; 2391 2392 cp = line; 2393 #ifndef POSIX 2394 if (line[0] == ' ') { 2395 while ((*cp != ':') && (*cp != '!') && (*cp != '\0')) { 2396 if (!isspace(*cp)) { 2397 nonSpace = TRUE; 2398 } 2399 cp++; 2400 } 2401 } 2402 2403 if (*cp == '\0') { 2404 if (inLine) { 2405 Parse_Error (PARSE_WARNING, 2406 "Shell command needs a leading tab"); 2407 goto shellCommand; 2408 } else if (nonSpace) { 2409 Parse_Error (PARSE_FATAL, "Missing operator"); 2410 } 2411 } else { 2412 #endif 2413 ParseFinishLine(); 2414 2415 cp = Var_Subst (NULL, line, VAR_CMD, TRUE); 2416 free (line); 2417 line = cp; 2418 2419 /* 2420 * Need a non-circular list for the target nodes 2421 */ 2422 targets = Lst_Init (FALSE); 2423 inLine = TRUE; 2424 2425 ParseDoDependency (line); 2426 #ifndef POSIX 2427 } 2428 #endif 2429 } 2430 2431 nextLine: 2432 2433 free (line); 2434 } 2435 /* 2436 * Reached EOF, but it may be just EOF of an include file... 2437 */ 2438 } while (ParseEOF(1) == CONTINUE); 2439 2440 /* 2441 * Make sure conditionals are clean 2442 */ 2443 Cond_End(); 2444 2445 if (fatals) { 2446 fprintf (stderr, "Fatal errors encountered -- cannot continue\n"); 2447 exit (1); 2448 } 2449 } 2450 2451 /*- 2452 *--------------------------------------------------------------------- 2453 * Parse_Init -- 2454 * initialize the parsing module 2455 * 2456 * Results: 2457 * none 2458 * 2459 * Side Effects: 2460 * the parseIncPath list is initialized... 2461 *--------------------------------------------------------------------- 2462 */ 2463 void 2464 Parse_Init () 2465 { 2466 char *cp = NULL, *start; 2467 /* avoid faults on read-only strings */ 2468 static char syspath[] = _PATH_DEFSYSPATH; 2469 2470 mainNode = NILGNODE; 2471 parseIncPath = Lst_Init (FALSE); 2472 sysIncPath = Lst_Init (FALSE); 2473 includes = Lst_Init (FALSE); 2474 2475 /* 2476 * Add the directories from the DEFSYSPATH (more than one may be given 2477 * as dir1:...:dirn) to the system include path. 2478 */ 2479 for (start = syspath; *start != '\0'; start = cp) { 2480 for (cp = start; *cp != '\0' && *cp != ':'; cp++) 2481 continue; 2482 if (*cp == '\0') { 2483 Dir_AddDir(sysIncPath, start); 2484 } else { 2485 *cp++ = '\0'; 2486 Dir_AddDir(sysIncPath, start); 2487 } 2488 } 2489 } 2490 2491 /*- 2492 *----------------------------------------------------------------------- 2493 * Parse_MainName -- 2494 * Return a Lst of the main target to create for main()'s sake. If 2495 * no such target exists, we Punt with an obnoxious error message. 2496 * 2497 * Results: 2498 * A Lst of the single node to create. 2499 * 2500 * Side Effects: 2501 * None. 2502 * 2503 *----------------------------------------------------------------------- 2504 */ 2505 Lst 2506 Parse_MainName() 2507 { 2508 Lst main; /* result list */ 2509 2510 main = Lst_Init (FALSE); 2511 2512 if (mainNode == NILGNODE) { 2513 Punt ("make: no target to make.\n"); 2514 /*NOTREACHED*/ 2515 } else if (mainNode->type & OP_DOUBLEDEP) { 2516 Lst_Concat(main, mainNode->cohorts, LST_CONCNEW); 2517 } 2518 (void) Lst_AtEnd (main, (ClientData)mainNode); 2519 return (main); 2520 } 2521