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