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