1 /* $OpenPackages$ */ 2 /* $OpenBSD: parse.c,v 1.66 2001/11/11 12:35:02 espie Exp $ */ 3 /* $NetBSD: parse.c,v 1.29 1997/03/10 21:20:04 christos Exp $ */ 4 5 /* 6 * Copyright (c) 1999 Marc Espie. 7 * 8 * Extensive code changes for the OpenBSD project. 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 * 19 * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD 23 * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 /* 32 * Copyright (c) 1988, 1989, 1990, 1993 33 * The Regents of the University of California. All rights reserved. 34 * Copyright (c) 1989 by Berkeley Softworks 35 * All rights reserved. 36 * 37 * This code is derived from software contributed to Berkeley by 38 * Adam de Boor. 39 * 40 * Redistribution and use in source and binary forms, with or without 41 * modification, are permitted provided that the following conditions 42 * are met: 43 * 1. Redistributions of source code must retain the above copyright 44 * notice, this list of conditions and the following disclaimer. 45 * 2. Redistributions in binary form must reproduce the above copyright 46 * notice, this list of conditions and the following disclaimer in the 47 * documentation and/or other materials provided with the distribution. 48 * 3. All advertising materials mentioning features or use of this software 49 * must display the following acknowledgement: 50 * This product includes software developed by the University of 51 * California, Berkeley and its contributors. 52 * 4. Neither the name of the University nor the names of its contributors 53 * may be used to endorse or promote products derived from this software 54 * without specific prior written permission. 55 * 56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 66 * SUCH DAMAGE. 67 */ 68 69 #include <assert.h> 70 #include <ctype.h> 71 #include <stdio.h> 72 #include <stdlib.h> 73 #include <string.h> 74 #include "config.h" 75 #include "defines.h" 76 #include "dir.h" 77 #include "job.h" 78 #include "buf.h" 79 #include "for.h" 80 #include "lowparse.h" 81 #include "arch.h" 82 #include "cond.h" 83 #include "suff.h" 84 #include "parse.h" 85 #include "var.h" 86 #include "targ.h" 87 #include "error.h" 88 #include "str.h" 89 #include "main.h" 90 #include "gnode.h" 91 #include "memory.h" 92 #include "extern.h" 93 #include "lst.h" 94 #include "parsevar.h" 95 #include "stats.h" 96 #include "garray.h" 97 98 99 static struct growableArray gsources, gtargets; 100 #define SOURCES_SIZE 128 101 #define TARGETS_SIZE 32 102 103 static LIST theParseIncPath;/* list of directories for "..." includes */ 104 static LIST theSysIncPath; /* list of directories for <...> includes */ 105 Lst sysIncPath = &theSysIncPath; 106 Lst parseIncPath = &theParseIncPath; 107 108 #ifdef CLEANUP 109 static LIST targCmds; /* command lines for targets */ 110 #endif 111 112 static GNode *mainNode; /* The main target to create. This is the 113 * first target on the first dependency 114 * line in the first makefile */ 115 /*- 116 * specType contains the SPECial TYPE of the current target. It is 117 * Not if the target is unspecial. If it *is* special, however, the children 118 * are linked as children of the parent but not vice versa. This variable is 119 * set in ParseDoDependency 120 */ 121 typedef enum { 122 Begin, /* .BEGIN */ 123 Default, /* .DEFAULT */ 124 End, /* .END */ 125 Ignore, /* .IGNORE */ 126 Includes, /* .INCLUDES */ 127 Interrupt, /* .INTERRUPT */ 128 Libs, /* .LIBS */ 129 MFlags, /* .MFLAGS or .MAKEFLAGS */ 130 Main, /* .MAIN and we don't have anything user-specified to 131 * make */ 132 NoExport, /* .NOEXPORT */ 133 NoPath, /* .NOPATH */ 134 Not, /* Not special */ 135 NotParallel, /* .NOTPARALELL */ 136 Null, /* .NULL */ 137 Order, /* .ORDER */ 138 Parallel, /* .PARALLEL */ 139 ExPath, /* .PATH */ 140 Phony, /* .PHONY */ 141 Precious, /* .PRECIOUS */ 142 ExShell, /* .SHELL */ 143 Silent, /* .SILENT */ 144 SingleShell, /* .SINGLESHELL */ 145 Suffixes, /* .SUFFIXES */ 146 Wait, /* .WAIT */ 147 Attribute /* Generic attribute */ 148 } ParseSpecial; 149 150 static ParseSpecial specType; 151 static int waiting; 152 153 /* 154 * Predecessor node for handling .ORDER. Initialized to NULL when .ORDER 155 * seen, then set to each successive source on the line. 156 */ 157 static GNode *predecessor; 158 159 /* 160 * The parseKeywords table is searched using binary search when deciding 161 * if a target or source is special. The 'spec' field is the ParseSpecial 162 * type of the keyword ("Not" if the keyword isn't special as a target) while 163 * the 'op' field is the operator to apply to the list of targets if the 164 * keyword is used as a source ("0" if the keyword isn't special as a source) 165 */ 166 static struct { 167 char *name; /* Name of keyword */ 168 ParseSpecial spec; /* Type when used as a target */ 169 int op; /* Operator when used as a source */ 170 } parseKeywords[] = { 171 { ".BEGIN", Begin, 0 }, 172 { ".DEFAULT", Default, 0 }, 173 { ".END", End, 0 }, 174 { ".EXEC", Attribute, OP_EXEC }, 175 { ".IGNORE", Ignore, OP_IGNORE }, 176 { ".INCLUDES", Includes, 0 }, 177 { ".INTERRUPT", Interrupt, 0 }, 178 { ".INVISIBLE", Attribute, OP_INVISIBLE }, 179 { ".JOIN", Attribute, OP_JOIN }, 180 { ".LIBS", Libs, 0 }, 181 { ".MADE", Attribute, OP_MADE }, 182 { ".MAIN", Main, 0 }, 183 { ".MAKE", Attribute, OP_MAKE }, 184 { ".MAKEFLAGS", MFlags, 0 }, 185 { ".MFLAGS", MFlags, 0 }, 186 #if 0 /* basic scaffolding for NOPATH, not working yet */ 187 { ".NOPATH", NoPath, OP_NOPATH }, 188 #endif 189 { ".NOTMAIN", Attribute, OP_NOTMAIN }, 190 { ".NOTPARALLEL", NotParallel, 0 }, 191 { ".NO_PARALLEL", NotParallel, 0 }, 192 { ".NULL", Null, 0 }, 193 { ".OPTIONAL", Attribute, OP_OPTIONAL }, 194 { ".ORDER", Order, 0 }, 195 { ".PARALLEL", Parallel, 0 }, 196 { ".PATH", ExPath, 0 }, 197 { ".PHONY", Phony, OP_PHONY }, 198 { ".PRECIOUS", Precious, OP_PRECIOUS }, 199 { ".RECURSIVE", Attribute, OP_MAKE }, 200 { ".SHELL", ExShell, 0 }, 201 { ".SILENT", Silent, OP_SILENT }, 202 { ".SINGLESHELL", SingleShell, 0 }, 203 { ".SUFFIXES", Suffixes, 0 }, 204 { ".USE", Attribute, OP_USE }, 205 { ".WAIT", Wait, 0 }, 206 }; 207 208 static int ParseFindKeyword(const char *); 209 static void ParseLinkSrc(GNode *, GNode *); 210 static int ParseDoOp(GNode *, int); 211 static int ParseAddDep(GNode *, GNode *); 212 static void ParseDoSrc(int, const char *); 213 static int ParseFindMain(void *, void *); 214 static void ParseAddDir(void *, void *); 215 static void ParseClearPath(void *); 216 static void ParseDoDependency(char *); 217 static void ParseAddCmd(void *, void *); 218 static void ParseHasCommands(void *); 219 static void ParseDoInclude(char *); 220 static void ParseTraditionalInclude(char *); 221 static void ParseConditionalInclude(char *); 222 static void ParseLookupIncludeFile(char *, char *, bool, bool); 223 #define ParseReadLoopLine(linebuf) Parse_ReadUnparsedLine(linebuf, "for loop") 224 static void ParseFinishDependency(void); 225 static bool ParseIsCond(Buffer, Buffer, char *); 226 static char *strip_comments(Buffer, const char *); 227 228 static void ParseDoCommands(const char *); 229 230 /*- 231 *---------------------------------------------------------------------- 232 * ParseFindKeyword -- 233 * Look in the table of keywords for one matching the given string. 234 * 235 * Results: 236 * The index of the keyword, or -1 if it isn't there. 237 *---------------------------------------------------------------------- 238 */ 239 static int 240 ParseFindKeyword(str) 241 const char *str; /* String to find */ 242 { 243 int start, 244 end, 245 cur; 246 int diff; 247 248 start = 0; 249 end = (sizeof(parseKeywords)/sizeof(parseKeywords[0])) - 1; 250 251 do { 252 cur = start + (end - start) / 2; 253 diff = strcmp(str, parseKeywords[cur].name); 254 255 if (diff == 0) { 256 return cur; 257 } else if (diff < 0) { 258 end = cur - 1; 259 } else { 260 start = cur + 1; 261 } 262 } while (start <= end); 263 return -1; 264 } 265 /*- 266 *--------------------------------------------------------------------- 267 * ParseLinkSrc -- 268 * Link the parent node to its new child. Used by 269 * ParseDoDependency. If the specType isn't 'Not', the parent 270 * isn't linked as a parent of the child. 271 * 272 * Side Effects: 273 * New elements are added to the parents list of cgn and the 274 * children list of cgn. the unmade field of pgn is updated 275 * to reflect the additional child. 276 *--------------------------------------------------------------------- 277 */ 278 static void 279 ParseLinkSrc(pgn, cgn) 280 GNode *pgn; /* The parent node */ 281 GNode *cgn; /* The child node */ 282 { 283 if (Lst_AddNew(&pgn->children, cgn)) { 284 if (specType == Not) 285 Lst_AtEnd(&cgn->parents, pgn); 286 pgn->unmade++; 287 } 288 } 289 290 /*- 291 *--------------------------------------------------------------------- 292 * ParseDoOp -- 293 * Apply the parsed operator to the given target node. Used in a 294 * Lst_Find call by ParseDoDependency once all targets have 295 * been found and their operator parsed. If the previous and new 296 * operators are incompatible, a major error is taken. 297 * 298 * Side Effects: 299 * The type field of the node is altered to reflect any new bits in 300 * the op. 301 *--------------------------------------------------------------------- 302 */ 303 static int 304 ParseDoOp(gn, op) 305 GNode *gn; /* The node to which the operator is to be 306 * applied */ 307 int op; /* The operator to apply */ 308 { 309 /* 310 * If the dependency mask of the operator and the node don't match and 311 * the node has actually had an operator applied to it before, and 312 * the operator actually has some dependency information in it, complain. 313 */ 314 if (((op & OP_OPMASK) != (gn->type & OP_OPMASK)) && 315 !OP_NOP(gn->type) && !OP_NOP(op)) { 316 Parse_Error(PARSE_FATAL, "Inconsistent operator for %s", gn->name); 317 return 0; 318 } 319 320 if (op == OP_DOUBLEDEP && ((gn->type & OP_OPMASK) == OP_DOUBLEDEP)) { 321 /* If the node was the object of a :: operator, we need to create a 322 * new instance of it for the children and commands on this dependency 323 * line. The new instance is placed on the 'cohorts' list of the 324 * initial one (note the initial one is not on its own cohorts list) 325 * and the new instance is linked to all parents of the initial 326 * instance. */ 327 GNode *cohort; 328 LstNode ln; 329 unsigned int i; 330 331 cohort = Targ_NewGN(gn->name); 332 /* Duplicate links to parents so graph traversal is simple. Perhaps 333 * some type bits should be duplicated? 334 * 335 * Make the cohort invisible as well to avoid duplicating it into 336 * other variables. True, parents of this target won't tend to do 337 * anything with their local variables, but better safe than 338 * sorry. */ 339 for (ln = Lst_First(&gn->parents); ln != NULL; ln = Lst_Adv(ln)) 340 ParseLinkSrc((GNode *)Lst_Datum(ln), cohort); 341 cohort->type = OP_DOUBLEDEP|OP_INVISIBLE; 342 Lst_AtEnd(&gn->cohorts, cohort); 343 344 /* Replace the node in the targets list with the new copy */ 345 for (i = 0; i < gtargets.n; i++) 346 if (gtargets.a[i] == gn) 347 break; 348 gtargets.a[i] = cohort; 349 gn = cohort; 350 } 351 /* We don't want to nuke any previous flags (whatever they were) so we 352 * just OR the new operator into the old. */ 353 gn->type |= op; 354 return 1; 355 } 356 357 /*- 358 *--------------------------------------------------------------------- 359 * ParseAddDep -- 360 * Check if the pair of GNodes given needs to be synchronized. 361 * This has to be when two nodes are on different sides of a 362 * .WAIT directive. 363 * 364 * Results: 365 * Returns 0 if the two targets need to be ordered, 1 otherwise. 366 * If it returns 0, the search can stop. 367 * 368 * Side Effects: 369 * A dependency can be added between the two nodes. 370 * 371 *--------------------------------------------------------------------- 372 */ 373 static int 374 ParseAddDep(p, s) 375 GNode *p; 376 GNode *s; 377 { 378 if (p->order < s->order) { 379 /* XXX: This can cause loops, and loops can cause unmade targets, 380 * but checking is tedious, and the debugging output can show the 381 * problem. */ 382 Lst_AtEnd(&p->successors, s); 383 Lst_AtEnd(&s->preds, p); 384 return 1; 385 } 386 else 387 return 0; 388 } 389 390 391 /*- 392 *--------------------------------------------------------------------- 393 * ParseDoSrc -- 394 * Given the name of a source, figure out if it is an attribute 395 * and apply it to the targets if it is. Else decide if there is 396 * some attribute which should be applied *to* the source because 397 * of some special target and apply it if so. Otherwise, make the 398 * source be a child of the targets in the list 'targets' 399 * 400 * Side Effects: 401 * Operator bits may be added to the list of targets or to the source. 402 * The targets may have a new source added to their lists of children. 403 *--------------------------------------------------------------------- 404 */ 405 static void 406 ParseDoSrc(tOp, src) 407 int tOp; /* operator (if any) from special targets */ 408 const char *src; /* name of the source to handle */ 409 410 { 411 GNode *gn = NULL; 412 413 if (*src == '.' && isupper(src[1])) { 414 int keywd = ParseFindKeyword(src); 415 if (keywd != -1) { 416 int op = parseKeywords[keywd].op; 417 if (op != 0) { 418 Array_Find(>argets, ParseDoOp, op); 419 return; 420 } 421 if (parseKeywords[keywd].spec == Wait) { 422 waiting++; 423 return; 424 } 425 } 426 } 427 428 switch (specType) { 429 case Main: 430 /* 431 * If we have noted the existence of a .MAIN, it means we need 432 * to add the sources of said target to the list of things 433 * to create. The string 'src' is likely to be freed, so we 434 * must make a new copy of it. Note that this will only be 435 * invoked if the user didn't specify a target on the command 436 * line. This is to allow #ifmake's to succeed, or something... 437 */ 438 Lst_AtEnd(create, estrdup(src)); 439 /* 440 * Add the name to the .TARGETS variable as well, so the user can 441 * employ that, if desired. 442 */ 443 Var_Append(".TARGETS", src, VAR_GLOBAL); 444 return; 445 446 case Order: 447 /* 448 * Create proper predecessor/successor links between the previous 449 * source and the current one. 450 */ 451 gn = Targ_FindNode(src, TARG_CREATE); 452 if (predecessor != NULL) { 453 Lst_AtEnd(&predecessor->successors, gn); 454 Lst_AtEnd(&gn->preds, predecessor); 455 } 456 /* 457 * The current source now becomes the predecessor for the next one. 458 */ 459 predecessor = gn; 460 break; 461 462 default: 463 /* 464 * If the source is not an attribute, we need to find/create 465 * a node for it. After that we can apply any operator to it 466 * from a special target or link it to its parents, as 467 * appropriate. 468 * 469 * In the case of a source that was the object of a :: operator, 470 * the attribute is applied to all of its instances (as kept in 471 * the 'cohorts' list of the node) or all the cohorts are linked 472 * to all the targets. 473 */ 474 gn = Targ_FindNode(src, TARG_CREATE); 475 if (tOp) { 476 gn->type |= tOp; 477 } else { 478 Array_ForEach(>argets, ParseLinkSrc, gn); 479 } 480 if ((gn->type & OP_OPMASK) == OP_DOUBLEDEP) { 481 GNode *cohort; 482 LstNode ln; 483 484 for (ln=Lst_First(&gn->cohorts); ln != NULL; ln = Lst_Adv(ln)){ 485 cohort = (GNode *)Lst_Datum(ln); 486 if (tOp) { 487 cohort->type |= tOp; 488 } else { 489 Array_ForEach(>argets, ParseLinkSrc, cohort); 490 } 491 } 492 } 493 break; 494 } 495 496 gn->order = waiting; 497 Array_AtEnd(&gsources, gn); 498 if (waiting) { 499 Array_Find(&gsources, ParseAddDep, gn); 500 } 501 } 502 503 /*- 504 *----------------------------------------------------------------------- 505 * ParseFindMain -- 506 * Find a real target in the list and set it to be the main one. 507 * Called by ParseDoDependency when a main target hasn't been found 508 * yet. 509 * 510 * Results: 511 * 1 if main not found yet, 0 if it is. 512 * 513 * Side Effects: 514 * mainNode is changed and Targ_SetMain is called. 515 *----------------------------------------------------------------------- 516 */ 517 static int 518 ParseFindMain(gnp, dummy) 519 void *gnp; /* Node to examine */ 520 void *dummy UNUSED; 521 { 522 GNode *gn = (GNode *)gnp; 523 if ((gn->type & OP_NOTARGET) == 0) { 524 mainNode = gn; 525 Targ_SetMain(gn); 526 return 0; 527 } else { 528 return 1; 529 } 530 } 531 532 /*- 533 *----------------------------------------------------------------------- 534 * ParseAddDir -- 535 * Front-end for Dir_AddDir to make sure Lst_ForEach keeps going 536 * 537 * Side Effects: 538 * See Dir_AddDir. 539 *----------------------------------------------------------------------- 540 */ 541 static void 542 ParseAddDir(path, name) 543 void *path; 544 void *name; 545 { 546 Dir_AddDir((Lst)path, (char *)name); 547 } 548 549 /*- 550 *----------------------------------------------------------------------- 551 * ParseClearPath -- 552 * Reinit path to an empty path 553 *----------------------------------------------------------------------- 554 */ 555 static void 556 ParseClearPath(p) 557 void *p; 558 { 559 Lst path = (Lst)p; 560 561 Lst_Destroy(path, Dir_Destroy); 562 Lst_Init(path); 563 } 564 565 /*- 566 *--------------------------------------------------------------------- 567 * ParseDoDependency -- 568 * Parse the dependency line in line. 569 * 570 * Side Effects: 571 * The nodes of the sources are linked as children to the nodes of the 572 * targets. Some nodes may be created. 573 * 574 * We parse a dependency line by first extracting words from the line and 575 * finding nodes in the list of all targets with that name. This is done 576 * until a character is encountered which is an operator character. Currently 577 * these are only ! and :. At this point the operator is parsed and the 578 * pointer into the line advanced until the first source is encountered. 579 * The parsed operator is applied to each node in the 'targets' list, 580 * which is where the nodes found for the targets are kept, by means of 581 * the ParseDoOp function. 582 * The sources are read in much the same way as the targets were except 583 * that now they are expanded using the wildcarding scheme of the C-Shell 584 * and all instances of the resulting words in the list of all targets 585 * are found. Each of the resulting nodes is then linked to each of the 586 * targets as one of its children. 587 * Certain targets are handled specially. These are the ones detailed 588 * by the specType variable. 589 * The storing of transformation rules is also taken care of here. 590 * A target is recognized as a transformation rule by calling 591 * Suff_IsTransform. If it is a transformation rule, its node is gotten 592 * from the suffix module via Suff_AddTransform rather than the standard 593 * Targ_FindNode in the target module. 594 *--------------------------------------------------------------------- 595 */ 596 static void 597 ParseDoDependency(line) 598 char *line; /* the line to parse */ 599 { 600 char *cp; /* our current position */ 601 GNode *gn; /* a general purpose temporary node */ 602 int op; /* the operator on the line */ 603 char savec; /* a place to save a character */ 604 LIST paths; /* List of search paths to alter when parsing 605 * a list of .PATH targets */ 606 int tOp; /* operator from special target */ 607 tOp = 0; 608 609 specType = Not; 610 waiting = 0; 611 Lst_Init(&paths); 612 613 Array_Reset(&gsources); 614 615 do { 616 for (cp = line; *cp && !isspace(*cp) && *cp != '(';) 617 if (*cp == '$') 618 /* Must be a dynamic source (would have been expanded 619 * otherwise), so call the Var module to parse the puppy 620 * so we can safely advance beyond it...There should be 621 * no errors in this, as they would have been discovered 622 * in the initial Var_Subst and we wouldn't be here. */ 623 cp += Var_ParseSkip(cp, NULL, NULL); 624 else { 625 /* We don't want to end a word on ':' or '!' if there is a 626 * better match later on in the string. By "better" I mean 627 * one that is followed by whitespace. This allows the user 628 * to have targets like: 629 * fie::fi:fo: fum 630 * where "fie::fi:fo" is the target. In real life this is used 631 * for perl5 library man pages where "::" separates an object 632 * from its class. Ie: "File::Spec::Unix". This behaviour 633 * is also consistent with other versions of make. */ 634 if (*cp == '!' || *cp == ':') { 635 char *p = cp + 1; 636 637 if (*cp == ':' && *p == ':') 638 p++; 639 640 /* Found the best match already. */ 641 if (isspace(*p) || *p == '\0') 642 break; 643 644 do { 645 p += strcspn(p, "!:"); 646 if (*p == '\0') 647 break; 648 p++; 649 } while (!isspace(*p)); 650 651 /* No better match later on... */ 652 if (*p == '\0') 653 break; 654 655 } 656 cp++; 657 } 658 if (*cp == '(') { 659 LIST temp; 660 Lst_Init(&temp); 661 /* Archives must be handled specially to make sure the OP_ARCHV 662 * flag is set in their 'type' field, for one thing, and because 663 * things like "archive(file1.o file2.o file3.o)" are permissible. 664 * Arch_ParseArchive will set 'line' to be the first non-blank 665 * after the archive-spec. It creates/finds nodes for the members 666 * and places them on the given list, returning true if all 667 * went well and false if there was an error in the 668 * specification. On error, line should remain untouched. */ 669 if (!Arch_ParseArchive(&line, &temp, NULL)) { 670 Parse_Error(PARSE_FATAL, 671 "Error in archive specification: \"%s\"", line); 672 return; 673 } else { 674 AppendList2Array(&temp, >argets); 675 Lst_Destroy(&temp, NOFREE); 676 continue; 677 } 678 } 679 savec = *cp; 680 681 if (*cp == '\0') { 682 /* Ending a dependency line without an operator is a Bozo no-no */ 683 Parse_Error(PARSE_FATAL, "Need an operator"); 684 return; 685 } 686 *cp = '\0'; 687 /* Have a word in line. See if it's a special target and set 688 * specType to match it. */ 689 if (*line == '.' && isupper(line[1])) { 690 /* See if the target is a special target that must have it 691 * or its sources handled specially. */ 692 int keywd = ParseFindKeyword(line); 693 if (keywd != -1) { 694 if (specType == ExPath && parseKeywords[keywd].spec != ExPath) { 695 Parse_Error(PARSE_FATAL, "Mismatched special targets"); 696 return; 697 } 698 699 specType = parseKeywords[keywd].spec; 700 tOp = parseKeywords[keywd].op; 701 702 /* 703 * Certain special targets have special semantics: 704 * .PATH Have to set the dirSearchPath 705 * variable too 706 * .MAIN Its sources are only used if 707 * nothing has been specified to 708 * create. 709 * .DEFAULT Need to create a node to hang 710 * commands on, but we don't want 711 * it in the graph, nor do we want 712 * it to be the Main Target, so we 713 * create it, set OP_NOTMAIN and 714 * add it to the list, setting 715 * DEFAULT to the new node for 716 * later use. We claim the node is 717 * A transformation rule to make 718 * life easier later, when we'll 719 * use Make_HandleUse to actually 720 * apply the .DEFAULT commands. 721 * .PHONY The list of targets 722 * .NOPATH Don't search for file in the path 723 * .BEGIN 724 * .END 725 * .INTERRUPT Are not to be considered the 726 * main target. 727 * .NOTPARALLEL Make only one target at a time. 728 * .SINGLESHELL Create a shell for each command. 729 * .ORDER Must set initial predecessor to NULL 730 */ 731 switch (specType) { 732 case ExPath: 733 Lst_AtEnd(&paths, dirSearchPath); 734 break; 735 case Main: 736 if (!Lst_IsEmpty(create)) { 737 specType = Not; 738 } 739 break; 740 case Begin: 741 case End: 742 case Interrupt: 743 gn = Targ_FindNode(line, TARG_CREATE); 744 gn->type |= OP_NOTMAIN; 745 Array_AtEnd(>argets, gn); 746 break; 747 case Default: 748 gn = Targ_NewGN(".DEFAULT"); 749 gn->type |= OP_NOTMAIN|OP_TRANSFORM; 750 Array_AtEnd(>argets, gn); 751 DEFAULT = gn; 752 break; 753 case NotParallel: 754 { 755 extern int maxJobs; 756 757 maxJobs = 1; 758 break; 759 } 760 case SingleShell: 761 compatMake = 1; 762 break; 763 case Order: 764 predecessor = NULL; 765 break; 766 default: 767 break; 768 } 769 } else if (strncmp(line, ".PATH", 5) == 0) { 770 /* 771 * .PATH<suffix> has to be handled specially. 772 * Call on the suffix module to give us a path to 773 * modify. 774 */ 775 Lst path; 776 777 specType = ExPath; 778 path = Suff_GetPath(&line[5]); 779 if (path == NULL) { 780 Parse_Error(PARSE_FATAL, 781 "Suffix '%s' not defined (yet)", 782 &line[5]); 783 return; 784 } else { 785 Lst_AtEnd(&paths, path); 786 } 787 } 788 } 789 790 /* 791 * Have word in line. Get or create its node and stick it at 792 * the end of the targets list 793 */ 794 if (specType == Not && *line != '\0') { 795 char *targName; 796 797 if (Dir_HasWildcards(line)) { 798 /* 799 * Targets are to be sought only in the current directory, 800 * so create an empty path for the thing. Note we need to 801 * use Dir_Destroy in the destruction of the path as the 802 * Dir module could have added a directory to the path... 803 */ 804 LIST emptyPath; 805 LIST curTargs; /* list of target names to be found 806 * and added to the targets list */ 807 808 Lst_Init(&emptyPath); 809 Lst_Init(&curTargs); 810 Dir_Expand(line, &emptyPath, &curTargs); 811 Lst_Destroy(&emptyPath, Dir_Destroy); 812 while ((targName = (char *)Lst_DeQueue(&curTargs)) != NULL) { 813 if (!Suff_IsTransform(targName)) 814 gn = Targ_FindNode(targName, TARG_CREATE); 815 else 816 gn = Suff_AddTransform(targName); 817 818 if (gn != NULL) 819 Array_AtEnd(>argets, gn); 820 } 821 Lst_Destroy(&curTargs, NOFREE); 822 } else { 823 if (!Suff_IsTransform(line)) 824 gn = Targ_FindNode(line, TARG_CREATE); 825 else 826 gn = Suff_AddTransform(line); 827 828 if (gn != NULL) 829 Array_AtEnd(>argets, gn); 830 /* Don't need the list of target names anymore... */ 831 } 832 } else if (specType == ExPath && *line != '.' && *line != '\0') 833 Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line); 834 835 *cp = savec; 836 /* 837 * If it is a special type and not .PATH, it's the only target we 838 * allow on this line... 839 */ 840 if (specType != Not && specType != ExPath) { 841 bool warn = false; 842 843 while (*cp != '!' && *cp != ':' && *cp) { 844 if (*cp != ' ' && *cp != '\t') { 845 warn = true; 846 } 847 cp++; 848 } 849 if (warn) { 850 Parse_Error(PARSE_WARNING, "Extra target ignored"); 851 } 852 } else { 853 while (*cp && isspace(*cp)) { 854 cp++; 855 } 856 } 857 line = cp; 858 } while (*line != '!' && *line != ':' && *line); 859 860 if (!Array_IsEmpty(>argets)) { 861 switch (specType) { 862 default: 863 Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored"); 864 break; 865 case Default: 866 case Begin: 867 case End: 868 case Interrupt: 869 /* These four create nodes on which to hang commands, so 870 * targets shouldn't be empty... */ 871 case Not: 872 /* Nothing special here -- targets can be empty if it wants. */ 873 break; 874 } 875 } 876 877 /* Have now parsed all the target names. Must parse the operator next. The 878 * result is left in op . */ 879 if (*cp == '!') { 880 op = OP_FORCE; 881 } else if (*cp == ':') { 882 if (cp[1] == ':') { 883 op = OP_DOUBLEDEP; 884 cp++; 885 } else { 886 op = OP_DEPENDS; 887 } 888 } else { 889 Parse_Error(PARSE_FATAL, "Missing dependency operator"); 890 return; 891 } 892 893 cp++; /* Advance beyond operator */ 894 895 Array_Find(>argets, ParseDoOp, op); 896 897 /* 898 * Get to the first source 899 */ 900 while (*cp && isspace(*cp)) { 901 cp++; 902 } 903 line = cp; 904 905 /* 906 * Several special targets take different actions if present with no 907 * sources: 908 * a .SUFFIXES line with no sources clears out all old suffixes 909 * a .PRECIOUS line makes all targets precious 910 * a .IGNORE line ignores errors for all targets 911 * a .SILENT line creates silence when making all targets 912 * a .PATH removes all directories from the search path(s). 913 */ 914 if (!*line) { 915 switch (specType) { 916 case Suffixes: 917 Suff_ClearSuffixes(); 918 break; 919 case Precious: 920 allPrecious = true; 921 break; 922 case Ignore: 923 ignoreErrors = true; 924 break; 925 case Silent: 926 beSilent = true; 927 break; 928 case ExPath: 929 Lst_Every(&paths, ParseClearPath); 930 break; 931 default: 932 break; 933 } 934 } else if (specType == MFlags) { 935 /* 936 * Call on functions in main.c to deal with these arguments and 937 * set the initial character to a null-character so the loop to 938 * get sources won't get anything 939 */ 940 Main_ParseArgLine(line); 941 *line = '\0'; 942 } else if (specType == ExShell) { 943 if (!Job_ParseShell(line)) { 944 Parse_Error(PARSE_FATAL, "improper shell specification"); 945 return; 946 } 947 *line = '\0'; 948 } else if (specType == NotParallel || specType == SingleShell) { 949 *line = '\0'; 950 } 951 952 /* 953 * NOW GO FOR THE SOURCES 954 */ 955 if (specType == Suffixes || specType == ExPath || 956 specType == Includes || specType == Libs || 957 specType == Null) { 958 while (*line) { 959 /* 960 * If the target was one that doesn't take files as its sources 961 * but takes something like suffixes, we take each 962 * space-separated word on the line as a something and deal 963 * with it accordingly. 964 * 965 * If the target was .SUFFIXES, we take each source as a 966 * suffix and add it to the list of suffixes maintained by the 967 * Suff module. 968 * 969 * If the target was a .PATH, we add the source as a directory 970 * to search on the search path. 971 * 972 * If it was .INCLUDES, the source is taken to be the suffix of 973 * files which will be #included and whose search path should 974 * be present in the .INCLUDES variable. 975 * 976 * If it was .LIBS, the source is taken to be the suffix of 977 * files which are considered libraries and whose search path 978 * should be present in the .LIBS variable. 979 * 980 * If it was .NULL, the source is the suffix to use when a file 981 * has no valid suffix. 982 */ 983 char savec; 984 while (*cp && !isspace(*cp)) { 985 cp++; 986 } 987 savec = *cp; 988 *cp = '\0'; 989 switch (specType) { 990 case Suffixes: 991 Suff_AddSuffix(line); 992 break; 993 case ExPath: 994 Lst_ForEach(&paths, ParseAddDir, line); 995 break; 996 case Includes: 997 Suff_AddInclude(line); 998 break; 999 case Libs: 1000 Suff_AddLib(line); 1001 break; 1002 case Null: 1003 Suff_SetNull(line); 1004 break; 1005 default: 1006 break; 1007 } 1008 *cp = savec; 1009 if (savec != '\0') { 1010 cp++; 1011 } 1012 while (*cp && isspace(*cp)) { 1013 cp++; 1014 } 1015 line = cp; 1016 } 1017 Lst_Destroy(&paths, NOFREE); 1018 } else { 1019 while (*line) { 1020 /* 1021 * The targets take real sources, so we must beware of archive 1022 * specifications (i.e. things with left parentheses in them) 1023 * and handle them accordingly. 1024 */ 1025 while (*cp && !isspace(*cp)) { 1026 if (*cp == '(' && cp > line && cp[-1] != '$') { 1027 /* 1028 * Only stop for a left parenthesis if it isn't at the 1029 * start of a word (that'll be for variable changes 1030 * later) and isn't preceded by a dollar sign (a dynamic 1031 * source). 1032 */ 1033 break; 1034 } else { 1035 cp++; 1036 } 1037 } 1038 1039 if (*cp == '(') { 1040 GNode *gn; 1041 LIST sources; /* list of archive source names after 1042 * expansion */ 1043 1044 Lst_Init(&sources); 1045 if (!Arch_ParseArchive(&line, &sources, NULL)) { 1046 Parse_Error(PARSE_FATAL, 1047 "Error in source archive spec \"%s\"", line); 1048 return; 1049 } 1050 1051 while ((gn = (GNode *)Lst_DeQueue(&sources)) != NULL) 1052 ParseDoSrc(tOp, gn->name); 1053 cp = line; 1054 } else { 1055 if (*cp) { 1056 *cp = '\0'; 1057 cp += 1; 1058 } 1059 1060 ParseDoSrc(tOp, line); 1061 } 1062 while (*cp && isspace(*cp)) { 1063 cp++; 1064 } 1065 line = cp; 1066 } 1067 } 1068 1069 if (mainNode == NULL) { 1070 /* If we have yet to decide on a main target to make, in the 1071 * absence of any user input, we want the first target on 1072 * the first dependency line that is actually a real target 1073 * (i.e. isn't a .USE or .EXEC rule) to be made. */ 1074 Array_Find(>argets, ParseFindMain, NULL); 1075 } 1076 1077 /* Finally, destroy the list of sources. */ 1078 } 1079 1080 /*- 1081 * ParseAddCmd -- 1082 * Lst_ForEach function to add a command line to all targets 1083 * 1084 * Side Effects: 1085 * A new element is added to the commands list of the node. 1086 */ 1087 static void 1088 ParseAddCmd(gnp, cmd) 1089 void *gnp; /* the node to which the command is to be added */ 1090 void *cmd; /* the command to add */ 1091 { 1092 GNode *gn = (GNode *)gnp; 1093 /* if target already supplied, ignore commands */ 1094 if (!(gn->type & OP_HAS_COMMANDS)) { 1095 Lst_AtEnd(&gn->commands, cmd); 1096 if (!gn->lineno) { 1097 gn->lineno = Parse_Getlineno(); 1098 gn->fname = Parse_Getfilename(); 1099 } 1100 } 1101 } 1102 1103 /*- 1104 *----------------------------------------------------------------------- 1105 * ParseHasCommands -- 1106 * Callback procedure for Parse_File when destroying the list of 1107 * targets on the last dependency line. Marks a target as already 1108 * having commands if it does, to keep from having shell commands 1109 * on multiple dependency lines. 1110 * 1111 * Side Effects: 1112 * OP_HAS_COMMANDS may be set for the target. 1113 *----------------------------------------------------------------------- 1114 */ 1115 static void 1116 ParseHasCommands(gnp) 1117 void *gnp; /* Node to examine */ 1118 { 1119 GNode *gn = (GNode *)gnp; 1120 if (!Lst_IsEmpty(&gn->commands)) { 1121 gn->type |= OP_HAS_COMMANDS; 1122 } 1123 } 1124 1125 /*- 1126 *----------------------------------------------------------------------- 1127 * Parse_AddIncludeDir -- 1128 * Add a directory to the path searched for included makefiles 1129 * bracketed by double-quotes. Used by functions in main.c 1130 *----------------------------------------------------------------------- 1131 */ 1132 void 1133 Parse_AddIncludeDir(dir) 1134 const char *dir; /* The name of the directory to add */ 1135 { 1136 Dir_AddDir(parseIncPath, dir); 1137 } 1138 1139 /*- 1140 *--------------------------------------------------------------------- 1141 * ParseDoInclude -- 1142 * Push to another file. 1143 * 1144 * The input is the line minus the #include. A file spec is a string 1145 * enclosed in <> or "". The former is looked for only in sysIncPath. 1146 * The latter in . and the directories specified by -I command line 1147 * options 1148 * 1149 * Side Effects: 1150 * old parse context is pushed on the stack, new file becomes 1151 * current context. 1152 *--------------------------------------------------------------------- 1153 */ 1154 static void 1155 ParseDoInclude(file) 1156 char *file; /* file specification */ 1157 { 1158 char endc; /* the character which ends the file spec */ 1159 char *cp; /* current position in file spec */ 1160 bool isSystem; /* true if makefile is a system makefile */ 1161 1162 /* Skip to delimiter character so we know where to look. */ 1163 while (*file == ' ' || *file == '\t') 1164 file++; 1165 1166 if (*file != '"' && *file != '<') { 1167 Parse_Error(PARSE_FATAL, 1168 ".include filename must be delimited by '\"' or '<'"); 1169 return; 1170 } 1171 1172 /* Set the search path on which to find the include file based on the 1173 * characters which bracket its name. Angle-brackets imply it's 1174 * a system Makefile while double-quotes imply it's a user makefile */ 1175 if (*file == '<') { 1176 isSystem = true; 1177 endc = '>'; 1178 } else { 1179 isSystem = false; 1180 endc = '"'; 1181 } 1182 1183 /* Skip to matching delimiter. */ 1184 for (cp = ++file; *cp != endc; cp++) { 1185 if (*cp == '\0') { 1186 Parse_Error(PARSE_FATAL, 1187 "Unclosed %cinclude filename. '%c' expected", 1188 '.', endc); 1189 return; 1190 } 1191 } 1192 ParseLookupIncludeFile(file, cp, isSystem, true); 1193 } 1194 1195 /*- 1196 *--------------------------------------------------------------------- 1197 * ParseTraditionalInclude -- 1198 * Push to another file. 1199 * 1200 * The input is the line minus the "include". The file name is 1201 * the string following the "include". 1202 * 1203 * Side Effects: 1204 * old parse context is pushed on the stack, new file becomes 1205 * current context. 1206 * 1207 * XXX May wish to support multiple files and wildcards ? 1208 *--------------------------------------------------------------------- 1209 */ 1210 static void 1211 ParseTraditionalInclude(file) 1212 char *file; /* file specification */ 1213 { 1214 char *cp; /* current position in file spec */ 1215 1216 /* Skip over whitespace. */ 1217 while (isspace(*file)) 1218 file++; 1219 if (*file == '\0') { 1220 Parse_Error(PARSE_FATAL, 1221 "Filename missing from \"include\""); 1222 return; 1223 } 1224 /* Skip to end of line or next whitespace. */ 1225 for (cp = file; *cp != '\0' && !isspace(*cp);) 1226 cp++; 1227 1228 ParseLookupIncludeFile(file, cp, true, true); 1229 } 1230 1231 /*- 1232 *--------------------------------------------------------------------- 1233 * ParseConditionalInclude -- 1234 * May push to another file. 1235 * 1236 * No error if the file does not exist. 1237 * See ParseTraditionalInclude otherwise. 1238 *--------------------------------------------------------------------- 1239 */ 1240 static void 1241 ParseConditionalInclude(file) 1242 char *file; /* file specification */ 1243 { 1244 char *cp; /* current position in file spec */ 1245 1246 /* Skip over whitespace. */ 1247 while (isspace(*file)) 1248 file++; 1249 if (*file == '\0') { 1250 Parse_Error(PARSE_FATAL, 1251 "Filename missing from \"include\""); 1252 return; 1253 } 1254 /* Skip to end of line or next whitespace. */ 1255 for (cp = file; *cp != '\0' && !isspace(*cp);) 1256 cp++; 1257 1258 ParseLookupIncludeFile(file, cp, true, false); 1259 } 1260 1261 /* Common part to lookup and read an include file. */ 1262 static void 1263 ParseLookupIncludeFile(spec, endSpec, isSystem, errIfNotFound) 1264 char *spec; 1265 char *endSpec; 1266 bool isSystem; 1267 bool errIfNotFound; 1268 { 1269 char *file; 1270 char *fullname; 1271 char endc; 1272 1273 /* Substitute for any variables in the file name before trying to 1274 * find the thing. */ 1275 endc = *endSpec; 1276 *endSpec = '\0'; 1277 file = Var_Subst(spec, NULL, false); 1278 *endSpec = endc; 1279 1280 /* Now that we know the file name and its search path, we attempt to 1281 * find the durn thing. NULL indicates the file still hasn't been 1282 * found. */ 1283 fullname = NULL; 1284 1285 /* Handle non-system non-absolute files... */ 1286 if (!isSystem && file[0] != '/') { 1287 /* ... by first searching relative to the including file's 1288 * location. We don't want to cd there, of course, so we 1289 * just tack on the old file's leading path components 1290 * and call Dir_FindFile to see if we can locate the beast. */ 1291 char *slash; 1292 const char *fname; 1293 1294 fname = Parse_Getfilename(); 1295 1296 slash = strrchr(fname, '/'); 1297 if (slash != NULL) { 1298 char *newName; 1299 1300 newName = Str_concati(fname, slash, file, strchr(file, '\0'), '/'); 1301 fullname = Dir_FindFile(newName, parseIncPath); 1302 if (fullname == NULL) 1303 fullname = Dir_FindFile(newName, dirSearchPath); 1304 free(newName); 1305 } 1306 } 1307 1308 /* Now look first on the -I search path, then on the .PATH 1309 * search path, if not found in a -I directory. 1310 * XXX: Suffix specific? */ 1311 if (fullname == NULL) 1312 fullname = Dir_FindFile(file, parseIncPath); 1313 if (fullname == NULL) 1314 fullname = Dir_FindFile(file, dirSearchPath); 1315 1316 /* Still haven't found the makefile. Look for it on the system 1317 * path as a last resort. */ 1318 if (fullname == NULL) 1319 fullname = Dir_FindFile(file, sysIncPath); 1320 1321 if (fullname == NULL && errIfNotFound) 1322 Parse_Error(PARSE_FATAL, "Could not find %s", file); 1323 1324 1325 free(file); 1326 1327 if (fullname != NULL) { 1328 FILE *f; 1329 1330 f = fopen(fullname, "r"); 1331 if (f == NULL && errIfNotFound) { 1332 Parse_Error(PARSE_FATAL, "Cannot open %s", fullname); 1333 } else { 1334 /* Once we find the absolute path to the file, we push the current 1335 * stream to the includes stack, and start reading from the new 1336 * file. We set up the file name to be its absolute name so that 1337 * error messages are informative. */ 1338 Parse_FromFile(fullname, f); 1339 } 1340 } 1341 } 1342 1343 1344 1345 1346 /* Strip comments from the line. May return either a copy of the line, or 1347 * the line itself. */ 1348 static char * 1349 strip_comments(copy, line) 1350 Buffer copy; 1351 const char *line; 1352 { 1353 const char *comment; 1354 const char *p; 1355 1356 comment = strchr(line, '#'); 1357 assert(comment != line); 1358 if (comment == NULL) 1359 return (char *)line; 1360 else { 1361 Buf_Reset(copy); 1362 1363 for (p = line; *p != '\0'; p++) { 1364 if (*p == '\\') { 1365 if (p[1] == '#') { 1366 Buf_Addi(copy, line, p); 1367 Buf_AddChar(copy, '#'); 1368 line = p+2; 1369 } 1370 if (p[1] != '\0') 1371 p++; 1372 } else if (*p == '#') 1373 break; 1374 } 1375 Buf_Addi(copy, line, p); 1376 Buf_KillTrailingSpaces(copy); 1377 return Buf_Retrieve(copy); 1378 } 1379 } 1380 1381 static bool 1382 ParseIsCond(linebuf, copy, line) 1383 Buffer linebuf; 1384 Buffer copy; 1385 char *line; 1386 { 1387 1388 char *stripped; 1389 1390 while (*line != '\0' && isspace(*line)) 1391 line++; 1392 1393 /* The line might be a conditional. Ask the conditional module 1394 * about it and act accordingly. */ 1395 switch (Cond_Eval(line)) { 1396 case COND_SKIP: 1397 /* Skip to next conditional that evaluates to COND_PARSE. */ 1398 do { 1399 line = Parse_ReadNextConditionalLine(linebuf); 1400 if (line != NULL) { 1401 while (*line != '\0' && isspace(*line)) 1402 line++; 1403 stripped = strip_comments(copy, line); 1404 } 1405 } while (line != NULL && Cond_Eval(stripped) != COND_PARSE); 1406 /* FALLTHROUGH */ 1407 case COND_PARSE: 1408 return true; 1409 default: 1410 break; 1411 } 1412 1413 { 1414 For *loop; 1415 1416 loop = For_Eval(line); 1417 if (loop != NULL) { 1418 bool ok; 1419 do { 1420 /* Find the matching endfor. */ 1421 line = ParseReadLoopLine(linebuf); 1422 if (line == NULL) { 1423 Parse_Error(PARSE_FATAL, 1424 "Unexpected end of file in for loop.\n"); 1425 return false; 1426 } 1427 ok = For_Accumulate(loop, line); 1428 } while (ok); 1429 For_Run(loop); 1430 return true; 1431 } 1432 } 1433 1434 if (strncmp(line, "include", 7) == 0) { 1435 ParseDoInclude(line + 7); 1436 return true; 1437 } else if (strncmp(line, "undef", 5) == 0) { 1438 char *cp; 1439 1440 line+=5; 1441 while (*line != '\0' && isspace(*line)) 1442 line++; 1443 for (cp = line; !isspace(*cp) && *cp != '\0';) 1444 cp++; 1445 *cp = '\0'; 1446 Var_Delete(line); 1447 return true; 1448 } 1449 return false; 1450 } 1451 1452 /*- 1453 *----------------------------------------------------------------------- 1454 * ParseFinishDependency -- 1455 * Handle the end of a dependency group. 1456 * 1457 * Side Effects: 1458 * 'targets' list destroyed. 1459 * 1460 *----------------------------------------------------------------------- 1461 */ 1462 static void 1463 ParseFinishDependency() 1464 { 1465 Array_Every(>argets, Suff_EndTransform); 1466 Array_Every(>argets, ParseHasCommands); 1467 Array_Reset(>argets); 1468 } 1469 1470 static void 1471 ParseDoCommands(line) 1472 const char *line; 1473 { 1474 /* add the command to the list of 1475 * commands of all targets in the dependency spec */ 1476 char *cmd = estrdup(line); 1477 1478 Array_ForEach(>argets, ParseAddCmd, cmd); 1479 #ifdef CLEANUP 1480 Lst_AtEnd(&targCmds, cmd); 1481 #endif 1482 } 1483 1484 void 1485 Parse_File(name, stream) 1486 const char *name; /* the name of the file being read */ 1487 FILE *stream; /* Stream open to makefile to parse */ 1488 { 1489 char *cp, /* pointer into the line */ 1490 *line; /* the line we're working on */ 1491 bool inDependency; /* true if currently in a dependency 1492 * line or its commands */ 1493 1494 BUFFER buf; 1495 BUFFER copy; 1496 1497 Buf_Init(&buf, MAKE_BSIZE); 1498 Buf_Init(©, MAKE_BSIZE); 1499 inDependency = false; 1500 Parse_FromFile(name, stream); 1501 1502 do { 1503 while ((line = Parse_ReadNormalLine(&buf)) != NULL) { 1504 if (*line == '\t') { 1505 if (inDependency) 1506 ParseDoCommands(line+1); 1507 else 1508 Parse_Error(PARSE_FATAL, 1509 "Unassociated shell command \"%s\"", 1510 line); 1511 } else { 1512 char *stripped; 1513 stripped = strip_comments(©, line); 1514 if (*stripped == '.' && ParseIsCond(&buf, ©, stripped+1)) 1515 ; 1516 else if (FEATURES(FEATURE_SYSVINCLUDE) && 1517 strncmp(stripped, "include", 7) == 0 && 1518 isspace(stripped[7]) && 1519 strchr(stripped, ':') == NULL) { 1520 /* It's an S3/S5-style "include". */ 1521 ParseTraditionalInclude(stripped + 7); 1522 } else if (FEATURES(FEATURE_CONDINCLUDE) && 1523 (*stripped == '-' || *stripped == 's') && 1524 strncmp(stripped+1, "include", 7) == 0 && 1525 isspace(stripped[8]) && 1526 strchr(stripped, ':') == NULL) { 1527 ParseConditionalInclude(stripped+8); 1528 } else { 1529 char *dep; 1530 1531 if (inDependency) 1532 ParseFinishDependency(); 1533 if (Parse_DoVar(stripped, VAR_GLOBAL)) 1534 inDependency = false; 1535 else { 1536 size_t pos; 1537 char *end; 1538 1539 /* Need a new list for the target nodes. */ 1540 Array_Reset(>argets); 1541 inDependency = true; 1542 1543 dep = NULL; 1544 /* First we need to find eventual dependencies */ 1545 pos = strcspn(stripped, ":!"); 1546 /* go over :!, and find ; */ 1547 if (stripped[pos] != '\0' && 1548 (end = strchr(stripped+pos+1, ';')) != NULL) { 1549 if (line != stripped) 1550 /* find matching ; in original... The 1551 * original might be slightly longer. */ 1552 dep = strchr(line+(end-stripped), ';'); 1553 else 1554 dep = end; 1555 /* kill end of line. */ 1556 *end = '\0'; 1557 } 1558 /* We now know it's a dependency line so it needs to 1559 * have all variables expanded before being parsed. 1560 * Tell the variable module to complain if some 1561 * variable is undefined... */ 1562 cp = Var_Subst(stripped, NULL, true); 1563 ParseDoDependency(cp); 1564 free(cp); 1565 1566 /* Parse dependency if it's not empty. */ 1567 if (dep != NULL) { 1568 do { 1569 dep++; 1570 } while (isspace(*dep)); 1571 if (*dep != '\0') 1572 ParseDoCommands(dep); 1573 } 1574 } 1575 } 1576 } 1577 } 1578 } while (Parse_NextFile()); 1579 1580 if (inDependency) 1581 ParseFinishDependency(); 1582 /* Make sure conditionals are clean. */ 1583 Cond_End(); 1584 1585 Parse_ReportErrors(); 1586 Buf_Destroy(&buf); 1587 Buf_Destroy(©); 1588 } 1589 1590 void 1591 Parse_Init() 1592 { 1593 mainNode = NULL; 1594 Static_Lst_Init(parseIncPath); 1595 Static_Lst_Init(sysIncPath); 1596 Array_Init(&gsources, SOURCES_SIZE); 1597 Array_Init(>argets, TARGETS_SIZE); 1598 1599 LowParse_Init(); 1600 #ifdef CLEANUP 1601 Static_Lst_Init(&targCmds); 1602 #endif 1603 } 1604 1605 #ifdef CLEANUP 1606 void 1607 Parse_End() 1608 { 1609 Lst_Destroy(&targCmds, (SimpleProc)free); 1610 Lst_Destroy(sysIncPath, Dir_Destroy); 1611 Lst_Destroy(parseIncPath, Dir_Destroy); 1612 LowParse_End(); 1613 } 1614 #endif 1615 1616 1617 void 1618 Parse_MainName(listmain) 1619 Lst listmain; /* result list */ 1620 { 1621 1622 if (mainNode == NULL) { 1623 Punt("no target to make."); 1624 /*NOTREACHED*/ 1625 } else if (mainNode->type & OP_DOUBLEDEP) { 1626 Lst_AtEnd(listmain, mainNode); 1627 Lst_Concat(listmain, &mainNode->cohorts); 1628 } 1629 else 1630 Lst_AtEnd(listmain, mainNode); 1631 } 1632 1633