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