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