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