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