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