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