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