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