parse.c revision 145683
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 145683 2005-04-29 15:15:28Z 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 "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 Warn, /* .WARN */ 178 Attribute /* Generic attribute */ 179} ParseSpecial; 180 181static ParseSpecial specType; 182static int waiting; 183 184/* 185 * Predecessor node for handling .ORDER. Initialized to NULL when .ORDER 186 * seen, then set to each successive source on the line. 187 */ 188static GNode *predecessor; 189 190/* 191 * The parseKeywords table is searched using binary search when deciding 192 * if a target or source is special. The 'spec' field is the ParseSpecial 193 * type of the keyword ("Not" if the keyword isn't special as a target) while 194 * the 'op' field is the operator to apply to the list of targets if the 195 * keyword is used as a source ("0" if the keyword isn't special as a source) 196 */ 197static const struct keyword { 198 const char *name; /* Name of keyword */ 199 ParseSpecial spec; /* Type when used as a target */ 200 int op; /* Operator when used as a source */ 201} parseKeywords[] = { 202 /* KEYWORD-START-TAG */ 203 { ".BEGIN", Begin, 0 }, 204 { ".DEFAULT", Default, 0 }, 205 { ".END", End, 0 }, 206 { ".EXEC", Attribute, OP_EXEC }, 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 maxJobs = 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 { 1174 /* list of sources in order */ 1175 Lst curSrcs = Lst_Initializer(curSrc); 1176 1177 while (*line) { 1178 /* 1179 * The targets take real sources, so we must beware of 1180 * archive specifications (i.e. things with left 1181 * parentheses in them) and handle them accordingly. 1182 */ 1183 while (*cp && !isspace((unsigned char)*cp)) { 1184 if (*cp == '(' && cp > line && cp[-1] != '$') { 1185 /* 1186 * Only stop for a left parenthesis if 1187 * it isn't at the start of a word 1188 * (that'll be for variable changes 1189 * later) and isn't preceded by a dollar 1190 * sign (a dynamic source). 1191 */ 1192 break; 1193 } else { 1194 cp++; 1195 } 1196 } 1197 1198 if (*cp == '(') { 1199 GNode *gnp; 1200 1201 /* list of archive source names after exp. */ 1202 Lst sources = Lst_Initializer(sources); 1203 1204 if (Arch_ParseArchive(&line, &sources, 1205 VAR_CMD) != SUCCESS) { 1206 Parse_Error(PARSE_FATAL, "Error in " 1207 "source archive spec \"%s\"", line); 1208 return; 1209 } 1210 1211 while (!Lst_IsEmpty(&sources)) { 1212 gnp = Lst_DeQueue(&sources); 1213 ParseDoSrc(tOp, gnp->name, &curSrcs); 1214 } 1215 cp = line; 1216 } else { 1217 if (*cp) { 1218 *cp = '\0'; 1219 cp += 1; 1220 } 1221 1222 ParseDoSrc(tOp, line, &curSrcs); 1223 } 1224 while (*cp && isspace((unsigned char)*cp)) { 1225 cp++; 1226 } 1227 line = cp; 1228 } 1229 Lst_Destroy(&curSrcs, NOFREE); 1230 } 1231 1232 if (mainNode == NULL) { 1233 /* 1234 * If we have yet to decide on a main target to make, in the 1235 * absence of any user input, we want the first target on 1236 * the first dependency line that is actually a real target 1237 * (i.e. isn't a .USE or .EXEC rule) to be made. 1238 */ 1239 LST_FOREACH(ln, &targets) { 1240 gn = Lst_Datum(ln); 1241 if ((gn->type & (OP_NOTMAIN | OP_USE | 1242 OP_EXEC | OP_TRANSFORM)) == 0) { 1243 mainNode = gn; 1244 Targ_SetMain(gn); 1245 break; 1246 } 1247 } 1248 } 1249} 1250 1251/*- 1252 *--------------------------------------------------------------------- 1253 * Parse_IsVar -- 1254 * Return TRUE if the passed line is a variable assignment. A variable 1255 * assignment consists of a single word followed by optional whitespace 1256 * followed by either a += or an = operator. 1257 * This function is used both by the Parse_File function and main when 1258 * parsing the command-line arguments. 1259 * 1260 * Results: 1261 * TRUE if it is. FALSE if it ain't 1262 * 1263 * Side Effects: 1264 * none 1265 *--------------------------------------------------------------------- 1266 */ 1267Boolean 1268Parse_IsVar(char *line) 1269{ 1270 Boolean wasSpace = FALSE; /* set TRUE if found a space */ 1271 Boolean haveName = FALSE; /* Set TRUE if have a variable name */ 1272 1273 int level = 0; 1274#define ISEQOPERATOR(c) \ 1275 ((c) == '+' || (c) == ':' || (c) == '?' || (c) == '!') 1276 1277 /* 1278 * Skip to variable name 1279 */ 1280 for (; *line == ' ' || *line == '\t'; line++) 1281 continue; 1282 1283 for (; *line != '=' || level != 0; line++) { 1284 switch (*line) { 1285 case '\0': 1286 /* 1287 * end-of-line -- can't be a variable assignment. 1288 */ 1289 return (FALSE); 1290 1291 case ' ': 1292 case '\t': 1293 /* 1294 * there can be as much white space as desired so long 1295 * as there is only one word before the operator 1296 */ 1297 wasSpace = TRUE; 1298 break; 1299 1300 case '(': 1301 case '{': 1302 level++; 1303 break; 1304 1305 case '}': 1306 case ')': 1307 level--; 1308 break; 1309 1310 default: 1311 if (wasSpace && haveName) { 1312 if (ISEQOPERATOR(*line)) { 1313 /* 1314 * We must have a finished word 1315 */ 1316 if (level != 0) 1317 return (FALSE); 1318 1319 /* 1320 * When an = operator [+?!:] is found, 1321 * the next character must be an = or 1322 * it ain't a valid assignment. 1323 */ 1324 if (line[1] == '=') 1325 return (haveName); 1326#ifdef SUNSHCMD 1327 /* 1328 * This is a shell command 1329 */ 1330 if (strncmp(line, ":sh", 3) == 0) 1331 return (haveName); 1332#endif 1333 } 1334 /* 1335 * This is the start of another word, so not 1336 * assignment. 1337 */ 1338 return (FALSE); 1339 1340 } else { 1341 haveName = TRUE; 1342 wasSpace = FALSE; 1343 } 1344 break; 1345 } 1346 } 1347 1348 return (haveName); 1349} 1350 1351/*- 1352 *--------------------------------------------------------------------- 1353 * Parse_DoVar -- 1354 * Take the variable assignment in the passed line and do it in the 1355 * global context. 1356 * 1357 * Note: There is a lexical ambiguity with assignment modifier characters 1358 * in variable names. This routine interprets the character before the = 1359 * as a modifier. Therefore, an assignment like 1360 * C++=/usr/bin/CC 1361 * is interpreted as "C+ +=" instead of "C++ =". 1362 * 1363 * Results: 1364 * none 1365 * 1366 * Side Effects: 1367 * the variable structure of the given variable name is altered in the 1368 * global context. 1369 *--------------------------------------------------------------------- 1370 */ 1371void 1372Parse_DoVar(char *line, GNode *ctxt) 1373{ 1374 char *cp; /* pointer into line */ 1375 enum { 1376 VAR_SUBST, 1377 VAR_APPEND, 1378 VAR_SHELL, 1379 VAR_NORMAL 1380 } type; /* Type of assignment */ 1381 char *opc; /* ptr to operator character to 1382 * null-terminate the variable name */ 1383 1384 /* 1385 * Avoid clobbered variable warnings by forcing the compiler 1386 * to ``unregister'' variables 1387 */ 1388#if __GNUC__ 1389 (void)&cp; 1390 (void)&line; 1391#endif 1392 1393 /* 1394 * Skip to variable name 1395 */ 1396 while (*line == ' ' || *line == '\t') { 1397 line++; 1398 } 1399 1400 /* 1401 * Skip to operator character, nulling out whitespace as we go 1402 */ 1403 for (cp = line + 1; *cp != '='; cp++) { 1404 if (isspace((unsigned char)*cp)) { 1405 *cp = '\0'; 1406 } 1407 } 1408 opc = cp - 1; /* operator is the previous character */ 1409 *cp++ = '\0'; /* nuke the = */ 1410 1411 /* 1412 * Check operator type 1413 */ 1414 switch (*opc) { 1415 case '+': 1416 type = VAR_APPEND; 1417 *opc = '\0'; 1418 break; 1419 1420 case '?': 1421 /* 1422 * If the variable already has a value, we don't do anything. 1423 */ 1424 *opc = '\0'; 1425 if (Var_Exists(line, ctxt)) { 1426 return; 1427 } else { 1428 type = VAR_NORMAL; 1429 } 1430 break; 1431 1432 case ':': 1433 type = VAR_SUBST; 1434 *opc = '\0'; 1435 break; 1436 1437 case '!': 1438 type = VAR_SHELL; 1439 *opc = '\0'; 1440 break; 1441 1442 default: 1443#ifdef SUNSHCMD 1444 while (*opc != ':') { 1445 if (opc == line) 1446 break; 1447 else 1448 --opc; 1449 } 1450 1451 if (strncmp(opc, ":sh", 3) == 0) { 1452 type = VAR_SHELL; 1453 *opc = '\0'; 1454 break; 1455 } 1456#endif 1457 type = VAR_NORMAL; 1458 break; 1459 } 1460 1461 while (isspace((unsigned char)*cp)) { 1462 cp++; 1463 } 1464 1465 if (type == VAR_APPEND) { 1466 Var_Append(line, cp, ctxt); 1467 1468 } else if (type == VAR_SUBST) { 1469 /* 1470 * Allow variables in the old value to be undefined, but leave 1471 * their invocation alone -- this is done by forcing oldVars 1472 * to be false. 1473 * XXX: This can cause recursive variables, but that's not 1474 * hard to do, and this allows someone to do something like 1475 * 1476 * CFLAGS = $(.INCLUDES) 1477 * CFLAGS := -I.. $(CFLAGS) 1478 * 1479 * And not get an error. 1480 */ 1481 Boolean oldOldVars = oldVars; 1482 1483 oldVars = FALSE; 1484 1485 /* 1486 * make sure that we set the variable the first time to nothing 1487 * so that it gets substituted! 1488 */ 1489 if (!Var_Exists(line, ctxt)) 1490 Var_Set(line, "", ctxt); 1491 1492 cp = Buf_Peel(Var_Subst(NULL, cp, ctxt, FALSE)); 1493 1494 oldVars = oldOldVars; 1495 1496 Var_Set(line, cp, ctxt); 1497 free(cp); 1498 1499 } else if (type == VAR_SHELL) { 1500 /* 1501 * TRUE if the command needs to be freed, i.e. 1502 * if any variable expansion was performed 1503 */ 1504 Boolean freeCmd = FALSE; 1505 Buffer *buf; 1506 const char *error; 1507 1508 if (strchr(cp, '$') != NULL) { 1509 /* 1510 * There's a dollar sign in the command, so perform 1511 * variable expansion on the whole thing. The 1512 * resulting string will need freeing when we're done, 1513 * so set freeCmd to TRUE. 1514 */ 1515 cp = Buf_Peel(Var_Subst(NULL, cp, VAR_CMD, TRUE)); 1516 freeCmd = TRUE; 1517 } 1518 1519 buf = Cmd_Exec(cp, &error); 1520 Var_Set(line, Buf_Data(buf), ctxt); 1521 Buf_Destroy(buf, TRUE); 1522 1523 if (error) 1524 Parse_Error(PARSE_WARNING, error, cp); 1525 1526 if (freeCmd) 1527 free(cp); 1528 1529 } else { 1530 /* 1531 * Normal assignment -- just do it. 1532 */ 1533 Var_Set(line, cp, ctxt); 1534 } 1535} 1536 1537/*- 1538 *----------------------------------------------------------------------- 1539 * ParseHasCommands -- 1540 * Callback procedure for Parse_File when destroying the list of 1541 * targets on the last dependency line. Marks a target as already 1542 * having commands if it does, to keep from having shell commands 1543 * on multiple dependency lines. 1544 * 1545 * Results: 1546 * None 1547 * 1548 * Side Effects: 1549 * OP_HAS_COMMANDS may be set for the target. 1550 * 1551 *----------------------------------------------------------------------- 1552 */ 1553static void 1554ParseHasCommands(void *gnp) 1555{ 1556 GNode *gn = gnp; 1557 1558 if (!Lst_IsEmpty(&gn->commands)) { 1559 gn->type |= OP_HAS_COMMANDS; 1560 } 1561} 1562 1563/*- 1564 *----------------------------------------------------------------------- 1565 * Parse_AddIncludeDir -- 1566 * Add a directory to the path searched for included makefiles 1567 * bracketed by double-quotes. Used by functions in main.c 1568 * 1569 * Results: 1570 * None. 1571 * 1572 * Side Effects: 1573 * The directory is appended to the list. 1574 * 1575 *----------------------------------------------------------------------- 1576 */ 1577void 1578Parse_AddIncludeDir(char *dir) 1579{ 1580 1581 Path_AddDir(&parseIncPath, dir); 1582} 1583 1584/*- 1585 *--------------------------------------------------------------------- 1586 * Parse_FromString -- 1587 * Start Parsing from the given string 1588 * 1589 * Results: 1590 * None 1591 * 1592 * Side Effects: 1593 * A structure is added to the includes Lst and readProc, curFile.lineno, 1594 * curFile.fname and curFile.F are altered for the new file 1595 *--------------------------------------------------------------------- 1596 */ 1597void 1598Parse_FromString(char *str, int lineno) 1599{ 1600 1601 DEBUGF(FOR, ("%s\n---- at line %d\n", str, lineno)); 1602 1603 ParsePushInput(estrdup(CURFILE->fname), NULL, str, lineno); 1604} 1605 1606#ifdef SYSVINCLUDE 1607/*- 1608 *--------------------------------------------------------------------- 1609 * ParseTraditionalInclude -- 1610 * Push to another file. 1611 * 1612 * The input is the line minus the "include". The file name is 1613 * the string following the "include". 1614 * 1615 * Results: 1616 * None 1617 * 1618 * Side Effects: 1619 * A structure is added to the includes Lst and readProc, curFile.lineno, 1620 * curFile.fname and curFile.F are altered for the new file 1621 *--------------------------------------------------------------------- 1622 */ 1623static void 1624ParseTraditionalInclude(char *file) 1625{ 1626 char *fullname; /* full pathname of file */ 1627 char *cp; /* current position in file spec */ 1628 1629 /* 1630 * Skip over whitespace 1631 */ 1632 while (*file == ' ' || *file == '\t') { 1633 file++; 1634 } 1635 1636 if (*file == '\0') { 1637 Parse_Error(PARSE_FATAL, "Filename missing from \"include\""); 1638 return; 1639 } 1640 1641 /* 1642 * Skip to end of line or next whitespace 1643 */ 1644 for (cp = file; *cp && *cp != '\n' && *cp != '\t' && *cp != ' '; cp++) { 1645 continue; 1646 } 1647 1648 *cp = '\0'; 1649 1650 /* 1651 * Substitute for any variables in the file name before trying to 1652 * find the thing. 1653 */ 1654 file = Buf_Peel(Var_Subst(NULL, file, VAR_CMD, FALSE)); 1655 1656 /* 1657 * Now we know the file's name, we attempt to find the durn thing. 1658 * Search for it first on the -I search path, then on the .PATH 1659 * search path, if not found in a -I directory. 1660 */ 1661 fullname = Path_FindFile(file, &parseIncPath); 1662 if (fullname == NULL) { 1663 fullname = Path_FindFile(file, &dirSearchPath); 1664 } 1665 1666 if (fullname == NULL) { 1667 /* 1668 * Still haven't found the makefile. Look for it on the system 1669 * path as a last resort. 1670 */ 1671 fullname = Path_FindFile(file, &sysIncPath); 1672 } 1673 1674 if (fullname == NULL) { 1675 Parse_Error(PARSE_FATAL, "Could not find %s", file); 1676 /* XXXHB free(file) */ 1677 return; 1678 } 1679 1680 /* XXXHB free(file) */ 1681 1682 /* 1683 * We set up the name of the file to be the absolute 1684 * name of the include file so error messages refer to the right 1685 * place. 1686 */ 1687 ParsePushInput(fullname, NULL, NULL, 0); 1688} 1689#endif 1690 1691/*- 1692 *--------------------------------------------------------------------- 1693 * ParseReadc -- 1694 * Read a character from the current file 1695 * 1696 * Results: 1697 * The character that was read 1698 * 1699 * Side Effects: 1700 *--------------------------------------------------------------------- 1701 */ 1702static int 1703ParseReadc(void) 1704{ 1705 1706 if (CURFILE->F != NULL) 1707 return (fgetc(CURFILE->F)); 1708 1709 if (CURFILE->str != NULL && *CURFILE->ptr != '\0') 1710 return (*CURFILE->ptr++); 1711 1712 return (EOF); 1713} 1714 1715 1716/*- 1717 *--------------------------------------------------------------------- 1718 * ParseUnreadc -- 1719 * Put back a character to the current file 1720 * 1721 * Results: 1722 * None. 1723 * 1724 * Side Effects: 1725 *--------------------------------------------------------------------- 1726 */ 1727static void 1728ParseUnreadc(int c) 1729{ 1730 1731 if (CURFILE->F != NULL) { 1732 ungetc(c, CURFILE->F); 1733 return; 1734 } 1735 if (CURFILE->str != NULL) { 1736 *--(CURFILE->ptr) = c; 1737 return; 1738 } 1739} 1740 1741/* ParseSkipLine(): 1742 * Grab the next line unless it begins with a dot (`.') and we're told to 1743 * ignore such lines. 1744 */ 1745static char * 1746ParseSkipLine(int skip, int keep_newline) 1747{ 1748 char *line; 1749 int c, lastc; 1750 Buffer *buf; 1751 1752 buf = Buf_Init(MAKE_BSIZE); 1753 1754 do { 1755 Buf_Clear(buf); 1756 lastc = '\0'; 1757 1758 while (((c = ParseReadc()) != '\n' || lastc == '\\') 1759 && c != EOF) { 1760 if (skip && c == '#' && lastc != '\\') { 1761 /* 1762 * let a comment be terminated even by an 1763 * escaped \n. This is consistent to comment 1764 * handling in ParseReadLine 1765 */ 1766 while ((c = ParseReadc()) != '\n' && c != EOF) 1767 ; 1768 break; 1769 } 1770 if (c == '\n') { 1771 if (keep_newline) 1772 Buf_AddByte(buf, (Byte)c); 1773 else 1774 Buf_ReplaceLastByte(buf, (Byte)' '); 1775 CURFILE->lineno++; 1776 1777 while ((c = ParseReadc()) == ' ' || c == '\t') 1778 continue; 1779 1780 if (c == EOF) 1781 break; 1782 } 1783 1784 Buf_AddByte(buf, (Byte)c); 1785 lastc = c; 1786 } 1787 1788 if (c == EOF) { 1789 Parse_Error(PARSE_FATAL, 1790 "Unclosed conditional/for loop"); 1791 Buf_Destroy(buf, TRUE); 1792 return (NULL); 1793 } 1794 1795 CURFILE->lineno++; 1796 Buf_AddByte(buf, (Byte)'\0'); 1797 line = Buf_Data(buf); 1798 } while (skip == 1 && line[0] != '.'); 1799 1800 Buf_Destroy(buf, FALSE); 1801 return (line); 1802} 1803 1804/*- 1805 *--------------------------------------------------------------------- 1806 * ParseReadLine -- 1807 * Read an entire line from the input file. Called only by Parse_File. 1808 * To facilitate escaped newlines and what have you, a character is 1809 * buffered in 'lastc', which is '\0' when no characters have been 1810 * read. When we break out of the loop, c holds the terminating 1811 * character and lastc holds a character that should be added to 1812 * the line (unless we don't read anything but a terminator). 1813 * 1814 * Results: 1815 * A line w/o its newline 1816 * 1817 * Side Effects: 1818 * Only those associated with reading a character 1819 *--------------------------------------------------------------------- 1820 */ 1821static char * 1822ParseReadLine(void) 1823{ 1824 Buffer *buf; /* Buffer for current line */ 1825 int c; /* the current character */ 1826 int lastc; /* The most-recent character */ 1827 Boolean semiNL; /* treat semi-colons as newlines */ 1828 Boolean ignDepOp; /* TRUE if should ignore dependency operators 1829 * for the purposes of setting semiNL */ 1830 Boolean ignComment; /* TRUE if should ignore comments (in a 1831 * shell command */ 1832 char *line; /* Result */ 1833 char *ep; /* to strip trailing blanks */ 1834 1835 again: 1836 semiNL = FALSE; 1837 ignDepOp = FALSE; 1838 ignComment = FALSE; 1839 1840 lastc = '\0'; 1841 1842 /* 1843 * Handle tab at the beginning of the line. A leading tab (shell 1844 * command) forces us to ignore comments and dependency operators and 1845 * treat semi-colons as semi-colons (by leaving semiNL FALSE). 1846 * This also discards completely blank lines. 1847 */ 1848 for (;;) { 1849 c = ParseReadc(); 1850 if (c == EOF) { 1851 if (ParsePopInput() == DONE) { 1852 /* End of all inputs - return NULL */ 1853 return (NULL); 1854 } 1855 continue; 1856 } 1857 1858 if (c == '\t') { 1859 ignComment = ignDepOp = TRUE; 1860 lastc = c; 1861 break; 1862 } 1863 if (c != '\n') { 1864 ParseUnreadc(c); 1865 break; 1866 } 1867 CURFILE->lineno++; 1868 } 1869 1870 buf = Buf_Init(MAKE_BSIZE); 1871 1872 while (((c = ParseReadc()) != '\n' || lastc == '\\') && c != EOF) { 1873 test_char: 1874 switch (c) { 1875 case '\n': 1876 /* 1877 * Escaped newline: read characters until a 1878 * non-space or an unescaped newline and 1879 * replace them all by a single space. This is 1880 * done by storing the space over the backslash 1881 * and dropping through with the next nonspace. 1882 * If it is a semi-colon and semiNL is TRUE, 1883 * it will be recognized as a newline in the 1884 * code below this... 1885 */ 1886 CURFILE->lineno++; 1887 lastc = ' '; 1888 while ((c = ParseReadc()) == ' ' || c == '\t') { 1889 continue; 1890 } 1891 if (c == EOF || c == '\n') { 1892 goto line_read; 1893 } else { 1894 /* 1895 * Check for comments, semiNL's, etc. -- 1896 * easier than ParseUnreadc(c); 1897 * continue; 1898 */ 1899 goto test_char; 1900 } 1901 /*NOTREACHED*/ 1902 break; 1903 1904 case ';': 1905 /* 1906 * Semi-colon: Need to see if it should be 1907 * interpreted as a newline 1908 */ 1909 if (semiNL) { 1910 /* 1911 * To make sure the command that may 1912 * be following this semi-colon begins 1913 * with a tab, we push one back into the 1914 * input stream. This will overwrite the 1915 * semi-colon in the buffer. If there is 1916 * no command following, this does no 1917 * harm, since the newline remains in 1918 * the buffer and the 1919 * whole line is ignored. 1920 */ 1921 ParseUnreadc('\t'); 1922 goto line_read; 1923 } 1924 break; 1925 case '=': 1926 if (!semiNL) { 1927 /* 1928 * Haven't seen a dependency operator 1929 * before this, so this must be a 1930 * variable assignment -- don't pay 1931 * attention to dependency operators 1932 * after this. 1933 */ 1934 ignDepOp = TRUE; 1935 } else if (lastc == ':' || lastc == '!') { 1936 /* 1937 * Well, we've seen a dependency 1938 * operator already, but it was the 1939 * previous character, so this is really 1940 * just an expanded variable assignment. 1941 * Revert semi-colons to being just 1942 * semi-colons again and ignore any more 1943 * dependency operators. 1944 * 1945 * XXX: Note that a line like 1946 * "foo : a:=b" will blow up, but who'd 1947 * write a line like that anyway? 1948 */ 1949 ignDepOp = TRUE; 1950 semiNL = FALSE; 1951 } 1952 break; 1953 case '#': 1954 if (!ignComment) { 1955 if (lastc != '\\') { 1956 /* 1957 * If the character is a hash 1958 * mark and it isn't escaped 1959 * (or we're being compatible), 1960 * the thing is a comment. 1961 * Skip to the end of the line. 1962 */ 1963 do { 1964 c = ParseReadc(); 1965 } while (c != '\n' && c != EOF); 1966 goto line_read; 1967 } else { 1968 /* 1969 * Don't add the backslash. 1970 * Just let the # get copied 1971 * over. 1972 */ 1973 lastc = c; 1974 continue; 1975 } 1976 } 1977 break; 1978 1979 case ':': 1980 case '!': 1981 if (!ignDepOp) { 1982 /* 1983 * A semi-colon is recognized as a 1984 * newline only on dependency lines. 1985 * Dependency lines are lines with a 1986 * colon or an exclamation point. 1987 * Ergo... 1988 */ 1989 semiNL = TRUE; 1990 } 1991 break; 1992 1993 default: 1994 break; 1995 } 1996 /* 1997 * Copy in the previous character (there may be none if this 1998 * was the first character) and save this one in 1999 * lastc. 2000 */ 2001 if (lastc != '\0') 2002 Buf_AddByte(buf, (Byte)lastc); 2003 lastc = c; 2004 } 2005 line_read: 2006 CURFILE->lineno++; 2007 2008 if (lastc != '\0') { 2009 Buf_AddByte(buf, (Byte)lastc); 2010 } 2011 Buf_AddByte(buf, (Byte)'\0'); 2012 line = Buf_Peel(buf); 2013 2014 /* 2015 * Strip trailing blanks and tabs from the line. 2016 * Do not strip a blank or tab that is preceded by 2017 * a '\' 2018 */ 2019 ep = line; 2020 while (*ep) 2021 ++ep; 2022 while (ep > line + 1 && (ep[-1] == ' ' || ep[-1] == '\t')) { 2023 if (ep > line + 1 && ep[-2] == '\\') 2024 break; 2025 --ep; 2026 } 2027 *ep = 0; 2028 2029 if (line[0] == '\0') { 2030 /* empty line - just ignore */ 2031 free(line); 2032 goto again; 2033 } 2034 2035 return (line); 2036} 2037 2038/*- 2039 *----------------------------------------------------------------------- 2040 * ParseFinishLine -- 2041 * Handle the end of a dependency group. 2042 * 2043 * Results: 2044 * Nothing. 2045 * 2046 * Side Effects: 2047 * inLine set FALSE. 'targets' list destroyed. 2048 * 2049 *----------------------------------------------------------------------- 2050 */ 2051static void 2052ParseFinishLine(void) 2053{ 2054 const LstNode *ln; 2055 2056 if (inLine) { 2057 LST_FOREACH(ln, &targets) { 2058 if (((const GNode *)Lst_Datum(ln))->type & OP_TRANSFORM) 2059 Suff_EndTransform(Lst_Datum(ln)); 2060 } 2061 Lst_Destroy(&targets, ParseHasCommands); 2062 inLine = FALSE; 2063 } 2064} 2065 2066/** 2067 * parse_include 2068 * Parse an .include directive and push the file onto the input stack. 2069 * The input is the line minus the .include. A file spec is a string 2070 * enclosed in <> or "". The former is looked for only in sysIncPath. 2071 * The latter in . and the directories specified by -I command line 2072 * options 2073 */ 2074static void 2075parse_include(char *file, int code __unused, int lineno __unused) 2076{ 2077 char *fullname; /* full pathname of file */ 2078 char endc; /* the character which ends the file spec */ 2079 char *cp; /* current position in file spec */ 2080 Boolean isSystem; /* TRUE if makefile is a system makefile */ 2081 char *prefEnd, *Fname; 2082 char *newName; 2083 2084 /* 2085 * Skip to delimiter character so we know where to look 2086 */ 2087 while (*file == ' ' || *file == '\t') { 2088 file++; 2089 } 2090 2091 if (*file != '"' && *file != '<') { 2092 Parse_Error(PARSE_FATAL, 2093 ".include filename must be delimited by '\"' or '<'"); 2094 return; 2095 } 2096 2097 /* 2098 * Set the search path on which to find the include file based on the 2099 * characters which bracket its name. Angle-brackets imply it's 2100 * a system Makefile while double-quotes imply it's a user makefile 2101 */ 2102 if (*file == '<') { 2103 isSystem = TRUE; 2104 endc = '>'; 2105 } else { 2106 isSystem = FALSE; 2107 endc = '"'; 2108 } 2109 2110 /* 2111 * Skip to matching delimiter 2112 */ 2113 for (cp = ++file; *cp != endc; cp++) { 2114 if (*cp == '\0') { 2115 Parse_Error(PARSE_FATAL, 2116 "Unclosed .include filename. '%c' expected", endc); 2117 return; 2118 } 2119 } 2120 *cp = '\0'; 2121 2122 /* 2123 * Substitute for any variables in the file name before trying to 2124 * find the thing. 2125 */ 2126 file = Buf_Peel(Var_Subst(NULL, file, VAR_CMD, FALSE)); 2127 2128 /* 2129 * Now we know the file's name and its search path, we attempt to 2130 * find the durn thing. A return of NULL indicates the file don't 2131 * exist. 2132 */ 2133 if (!isSystem) { 2134 /* 2135 * Include files contained in double-quotes are first searched 2136 * for relative to the including file's location. We don't want 2137 * to cd there, of course, so we just tack on the old file's 2138 * leading path components and call Dir_FindFile to see if 2139 * we can locate the beast. 2140 */ 2141 2142 /* Make a temporary copy of this, to be safe. */ 2143 Fname = estrdup(CURFILE->fname); 2144 2145 prefEnd = strrchr(Fname, '/'); 2146 if (prefEnd != NULL) { 2147 *prefEnd = '\0'; 2148 if (file[0] == '/') 2149 newName = estrdup(file); 2150 else 2151 newName = str_concat(Fname, file, STR_ADDSLASH); 2152 fullname = Path_FindFile(newName, &parseIncPath); 2153 if (fullname == NULL) { 2154 fullname = Path_FindFile(newName, 2155 &dirSearchPath); 2156 } 2157 free(newName); 2158 *prefEnd = '/'; 2159 } else { 2160 fullname = NULL; 2161 } 2162 free(Fname); 2163 } else { 2164 fullname = NULL; 2165 } 2166 2167 if (fullname == NULL) { 2168 /* 2169 * System makefile or makefile wasn't found in same directory as 2170 * included makefile. Search for it first on the -I search path, 2171 * then on the .PATH search path, if not found in a -I 2172 * directory. 2173 * XXX: Suffix specific? 2174 */ 2175 fullname = Path_FindFile(file, &parseIncPath); 2176 if (fullname == NULL) { 2177 fullname = Path_FindFile(file, &dirSearchPath); 2178 } 2179 } 2180 2181 if (fullname == NULL) { 2182 /* 2183 * Still haven't found the makefile. Look for it on the system 2184 * path as a last resort. 2185 */ 2186 fullname = Path_FindFile(file, &sysIncPath); 2187 } 2188 2189 if (fullname == NULL) { 2190 *cp = endc; 2191 Parse_Error(PARSE_FATAL, "Could not find %s", file); 2192 free(file); 2193 return; 2194 } 2195 free(file); 2196 2197 /* 2198 * We set up the name of the file to be the absolute 2199 * name of the include file so error messages refer to the right 2200 * place. 2201 */ 2202 ParsePushInput(fullname, NULL, NULL, 0); 2203} 2204 2205/** 2206 * parse_message 2207 * Parse a .warning or .error directive 2208 * 2209 * The input is the line minus the ".error"/".warning". We substitute 2210 * variables, print the message and exit(1) (for .error) or just print 2211 * a warning if the directive is malformed. 2212 */ 2213static void 2214parse_message(char *line, int iserror, int lineno __unused) 2215{ 2216 2217 if (!isspace((u_char)*line)) { 2218 Parse_Error(PARSE_WARNING, "invalid syntax: .%s%s", 2219 iserror ? "error" : "warning", line); 2220 return; 2221 } 2222 2223 while (isspace((u_char)*line)) 2224 line++; 2225 2226 line = Buf_Peel(Var_Subst(NULL, line, VAR_GLOBAL, FALSE)); 2227 Parse_Error(iserror ? PARSE_FATAL : PARSE_WARNING, "%s", line); 2228 free(line); 2229 2230 if (iserror) { 2231 /* Terminate immediately. */ 2232 exit(1); 2233 } 2234} 2235 2236/** 2237 * parse_undef 2238 * Parse an .undef directive. 2239 */ 2240static void 2241parse_undef(char *line, int code __unused, int lineno __unused) 2242{ 2243 char *cp; 2244 2245 while (isspace((u_char)*line)) 2246 line++; 2247 2248 for (cp = line; !isspace((u_char)*cp) && *cp != '\0'; cp++) { 2249 ; 2250 } 2251 *cp = '\0'; 2252 2253 cp = Buf_Peel(Var_Subst(NULL, line, VAR_CMD, FALSE)); 2254 Var_Delete(cp, VAR_GLOBAL); 2255 free(cp); 2256} 2257 2258/** 2259 * parse_for 2260 * Parse a .for directive. 2261 */ 2262static void 2263parse_for(char *line, int code __unused, int lineno) 2264{ 2265 2266 if (!For_For(line)) { 2267 /* syntax error */ 2268 return; 2269 } 2270 line = NULL; 2271 2272 /* 2273 * Skip after the matching endfor. 2274 */ 2275 do { 2276 free(line); 2277 line = ParseSkipLine(0, 1); 2278 if (line == NULL) { 2279 Parse_Error(PARSE_FATAL, 2280 "Unexpected end of file in for loop.\n"); 2281 return; 2282 } 2283 } while (For_Eval(line)); 2284 free(line); 2285 2286 /* execute */ 2287 For_Run(lineno); 2288} 2289 2290/** 2291 * parse_endfor 2292 * Parse endfor. This may only happen if there was no matching .for. 2293 */ 2294static void 2295parse_endfor(char *line __unused, int code __unused, int lineno __unused) 2296{ 2297 2298 Parse_Error(PARSE_FATAL, "for-less endfor"); 2299} 2300 2301/** 2302 * parse_directive 2303 * Got a line starting with a '.'. Check if this is a directive 2304 * and parse it. 2305 * 2306 * return: 2307 * TRUE if line was a directive, FALSE otherwise. 2308 */ 2309static Boolean 2310parse_directive(char *line) 2311{ 2312 char *start; 2313 char *cp; 2314 int dir; 2315 2316 /* 2317 * Get the keyword: 2318 * .[[:space:]]*\([[:alpha:]][[:alnum:]_]*\).* 2319 * \1 is the keyword. 2320 */ 2321 for (start = line; isspace((u_char)*start); start++) { 2322 ; 2323 } 2324 2325 if (!isalpha((u_char)*start)) { 2326 return (FALSE); 2327 } 2328 2329 cp = start + 1; 2330 while (isalnum((u_char)*cp) || *cp == '_') { 2331 cp++; 2332 } 2333 2334 dir = directive_hash(start, cp - start); 2335 if (dir < 0 || dir >= (int)NDIRECTS || 2336 (size_t)(cp - start) != strlen(directives[dir].name) || 2337 strncmp(start, directives[dir].name, cp - start) != 0) { 2338 /* not actually matched */ 2339 return (FALSE); 2340 } 2341 2342 if (!skipLine || directives[dir].skip_flag) 2343 (*directives[dir].func)(cp, directives[dir].code, 2344 CURFILE->lineno); 2345 return (TRUE); 2346} 2347 2348/*- 2349 *--------------------------------------------------------------------- 2350 * Parse_File -- 2351 * Parse a file into its component parts, incorporating it into the 2352 * current dependency graph. This is the main function and controls 2353 * almost every other function in this module 2354 * 2355 * Results: 2356 * None 2357 * 2358 * Side Effects: 2359 * Loads. Nodes are added to the list of all targets, nodes and links 2360 * are added to the dependency graph. etc. etc. etc. 2361 *--------------------------------------------------------------------- 2362 */ 2363void 2364Parse_File(const char *name, FILE *stream) 2365{ 2366 char *cp; /* pointer into the line */ 2367 char *line; /* the line we're working on */ 2368 2369 inLine = FALSE; 2370 fatals = 0; 2371 2372 ParsePushInput(estrdup(name), stream, NULL, 0); 2373 2374 while ((line = ParseReadLine()) != NULL) { 2375 if (*line == '.' && parse_directive(line + 1)) { 2376 /* directive consumed */ 2377 goto nextLine; 2378 } 2379 if (skipLine || *line == '#') { 2380 /* Skipping .if block or comment. */ 2381 goto nextLine; 2382 } 2383 2384 if (*line == '\t') { 2385 /* 2386 * If a line starts with a tab, it can only 2387 * hope to be a creation command. 2388 */ 2389 for (cp = line + 1; isspace((unsigned char)*cp); cp++) { 2390 continue; 2391 } 2392 if (*cp) { 2393 if (inLine) { 2394 LstNode *ln; 2395 GNode *gn; 2396 2397 /* 2398 * So long as it's not a blank 2399 * line and we're actually in a 2400 * dependency spec, add the 2401 * command to the list of 2402 * commands of all targets in 2403 * the dependency spec. 2404 */ 2405 LST_FOREACH(ln, &targets) { 2406 gn = Lst_Datum(ln); 2407 2408 /* 2409 * if target already 2410 * supplied, ignore 2411 * commands 2412 */ 2413 if (!(gn->type & OP_HAS_COMMANDS)) 2414 Lst_AtEnd(&gn->commands, cp); 2415 else 2416 Parse_Error(PARSE_WARNING, "duplicate script " 2417 "for target \"%s\" ignored", gn->name); 2418 } 2419 continue; 2420 } else { 2421 Parse_Error(PARSE_FATAL, 2422 "Unassociated shell command \"%s\"", 2423 cp); 2424 } 2425 } 2426#ifdef SYSVINCLUDE 2427 } else if (strncmp(line, "include", 7) == 0 && 2428 isspace((unsigned char)line[7]) && 2429 strchr(line, ':') == NULL) { 2430 /* 2431 * It's an S3/S5-style "include". 2432 */ 2433 ParseTraditionalInclude(line + 7); 2434 goto nextLine; 2435#endif 2436 } else if (Parse_IsVar(line)) { 2437 ParseFinishLine(); 2438 Parse_DoVar(line, VAR_GLOBAL); 2439 2440 } else { 2441 /* 2442 * We now know it's a dependency line so it 2443 * needs to have all variables expanded before 2444 * being parsed. Tell the variable module to 2445 * complain if some variable is undefined... 2446 * To make life easier on novices, if the line 2447 * is indented we first make sure the line has 2448 * a dependency operator in it. If it doesn't 2449 * have an operator and we're in a dependency 2450 * line's script, we assume it's actually a 2451 * shell command and add it to the current 2452 * list of targets. XXX this comment seems wrong. 2453 */ 2454 cp = line; 2455 if (isspace((unsigned char)line[0])) { 2456 while (*cp != '\0' && 2457 isspace((unsigned char)*cp)) { 2458 cp++; 2459 } 2460 if (*cp == '\0') { 2461 goto nextLine; 2462 } 2463 } 2464 2465 ParseFinishLine(); 2466 2467 cp = Buf_Peel(Var_Subst(NULL, line, VAR_CMD, TRUE)); 2468 2469 free(line); 2470 line = cp; 2471 2472 /* 2473 * Need a non-circular list for the target nodes 2474 */ 2475 Lst_Destroy(&targets, NOFREE); 2476 inLine = TRUE; 2477 2478 ParseDoDependency(line); 2479 } 2480 2481 nextLine: 2482 free(line); 2483 } 2484 2485 ParseFinishLine(); 2486 2487 /* 2488 * Make sure conditionals are clean 2489 */ 2490 Cond_End(); 2491 2492 if (fatals) 2493 errx(1, "fatal errors encountered -- cannot continue"); 2494} 2495 2496/*- 2497 *----------------------------------------------------------------------- 2498 * Parse_MainName -- 2499 * Return a Lst of the main target to create for main()'s sake. If 2500 * no such target exists, we Punt with an obnoxious error message. 2501 * 2502 * Results: 2503 * A Lst of the single node to create. 2504 * 2505 * Side Effects: 2506 * None. 2507 * 2508 *----------------------------------------------------------------------- 2509 */ 2510void 2511Parse_MainName(Lst *listmain) 2512{ 2513 2514 if (mainNode == NULL) { 2515 Punt("no target to make."); 2516 /*NOTREACHED*/ 2517 } else if (mainNode->type & OP_DOUBLEDEP) { 2518 Lst_AtEnd(listmain, mainNode); 2519 Lst_Concat(listmain, &mainNode->cohorts, LST_CONCNEW); 2520 } else 2521 Lst_AtEnd(listmain, mainNode); 2522} 2523