1 /* $OpenBSD: parse.c,v 1.110 2013/11/22 15:47:35 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 = (GNode *)gnp; 482 if ((gn->type & OP_NOTARGET) == 0 && gn->special == SPECIAL_NONE) { 483 mainNode = gn; 484 return 0; 485 } else { 486 return 1; 487 } 488 } 489 490 /*- 491 *----------------------------------------------------------------------- 492 * ParseClearPath -- 493 * Reinit path to an empty path 494 *----------------------------------------------------------------------- 495 */ 496 static void 497 ParseClearPath(void *p) 498 { 499 Lst path = (Lst)p; 500 501 Lst_Destroy(path, Dir_Destroy); 502 Lst_Init(path); 503 } 504 505 static void 506 add_target_node(const char *line, const char *end) 507 { 508 GNode *gn; 509 510 gn = Suff_ParseAsTransform(line, end); 511 512 if (gn == NULL) { 513 gn = Targ_FindNodei(line, end, TARG_CREATE); 514 gn->type &= ~OP_DUMMY; 515 } 516 517 Array_AtEnd(>argets, gn); 518 } 519 520 static void 521 add_target_nodes(const char *line, const char *end) 522 { 523 524 if (Dir_HasWildcardsi(line, end)) { 525 /* 526 * Targets are to be sought only in the current directory, 527 * so create an empty path for the thing. Note we need to 528 * use Dir_Destroy in the destruction of the path as the 529 * Dir module could have added a directory to the path... 530 */ 531 char *targName; 532 LIST emptyPath; 533 LIST curTargs; 534 535 Lst_Init(&emptyPath); 536 Lst_Init(&curTargs); 537 Dir_Expandi(line, end, &emptyPath, &curTargs); 538 Lst_Destroy(&emptyPath, Dir_Destroy); 539 while ((targName = (char *)Lst_DeQueue(&curTargs)) != NULL) { 540 add_target_node(targName, targName + strlen(targName)); 541 } 542 Lst_Destroy(&curTargs, NOFREE); 543 } else { 544 add_target_node(line, end); 545 } 546 } 547 548 /* special target line check: a proper delimiter is a ':' or '!', but 549 * we don't want to end a target on such a character if there is a better 550 * match later on. 551 * By "better" I mean one that is followed by whitespace. This allows the 552 * user to have targets like: 553 * fie::fi:fo: fum 554 * where "fie::fi:fo" is the target. In real life this is used for perl5 555 * library man pages where "::" separates an object from its class. Ie: 556 * "File::Spec::Unix". 557 * This behaviour is also consistent with other versions of make. 558 */ 559 static bool 560 found_delimiter(const char *s) 561 { 562 if (*s == '!' || *s == ':') { 563 const char *p = s + 1; 564 565 if (*s == ':' && *p == ':') 566 p++; 567 568 /* Found the best match already. */ 569 if (ISSPACE(*p) || *p == '\0') 570 return true; 571 572 do { 573 p += strcspn(p, "!:"); 574 if (*p == '\0') 575 break; 576 p++; 577 } while (!ISSPACE(*p)); 578 579 /* No better match later on... */ 580 if (*p == '\0') 581 return true; 582 } 583 return false; 584 } 585 586 static const char * 587 parse_do_targets(Lst paths, unsigned int *op, const char *line) 588 { 589 const char *cp; 590 591 do { 592 for (cp = line; *cp && !ISSPACE(*cp) && *cp != '(';) { 593 if (*cp == '$') 594 /* Must be a dynamic source (would have been 595 * expanded otherwise), so call the Var module 596 * to parse the puppy so we can safely advance 597 * beyond it...There should be no errors in 598 * this, as they would have been discovered in 599 * the initial Var_Subst and we wouldn't be 600 * here. */ 601 Var_ParseSkip(&cp, NULL); 602 else { 603 if (found_delimiter(cp)) 604 break; 605 cp++; 606 } 607 } 608 609 if (*cp == '(') { 610 LIST temp; 611 Lst_Init(&temp); 612 /* Archives must be handled specially to make sure the 613 * OP_ARCHV flag is set in their 'type' field, for one 614 * thing, and because things like "archive(file1.o 615 * file2.o file3.o)" are permissible. 616 * Arch_ParseArchive will set 'line' to be the first 617 * non-blank after the archive-spec. It creates/finds 618 * nodes for the members and places them on the given 619 * list, returning true if all went well and false if 620 * there was an error in the specification. On error, 621 * line should remain untouched. */ 622 if (!Arch_ParseArchive(&line, &temp, NULL)) { 623 Parse_Error(PARSE_FATAL, 624 "Error in archive specification: \"%s\"", 625 line); 626 return NULL; 627 } else { 628 AppendList2Array(&temp, >argets); 629 Lst_Destroy(&temp, NOFREE); 630 cp = line; 631 continue; 632 } 633 } 634 if (*cp == '\0') { 635 /* Ending a dependency line without an operator is a 636 * Bozo no-no */ 637 /* Deeper check for cvs conflicts */ 638 if (gtargets.n > 0 && 639 (strcmp(gtargets.a[0]->name, "<<<<<<<") == 0 || 640 strcmp(gtargets.a[0]->name, ">>>>>>>") == 0)) { 641 Parse_Error(PARSE_FATAL, 642 "Need an operator (likely from a cvs update conflict)"); 643 } else { 644 Parse_Error(PARSE_FATAL, 645 "Need an operator in '%s'", line); 646 } 647 return NULL; 648 } 649 /* 650 * Have word in line. Get or create its nodes and stick it at 651 * the end of the targets list 652 */ 653 if (*line != '\0') 654 add_target_nodes(line, cp); 655 656 while (ISSPACE(*cp)) 657 cp++; 658 line = cp; 659 } while (*line != '!' && *line != ':' && *line); 660 *op = handle_special_targets(paths); 661 return cp; 662 } 663 664 static void 665 dump_targets() 666 { 667 size_t i; 668 for (i = 0; i < gtargets.n; i++) 669 fprintf(stderr, "%s", gtargets.a[i]->name); 670 fprintf(stderr, "\n"); 671 } 672 673 static unsigned int 674 handle_special_targets(Lst paths) 675 { 676 size_t i; 677 int seen_path = 0; 678 int seen_special = 0; 679 int seen_normal = 0; 680 int type; 681 682 for (i = 0; i < gtargets.n; i++) { 683 type = gtargets.a[i]->special; 684 if ((type & SPECIAL_MASK) == SPECIAL_PATH) { 685 seen_path++; 686 Lst_AtEnd(paths, find_suffix_path(gtargets.a[i])); 687 } else if ((type & SPECIAL_TARGET) != 0) 688 seen_special++; 689 else 690 seen_normal++; 691 } 692 if ((seen_path != 0) + (seen_special != 0) + (seen_normal != 0) > 1) { 693 Parse_Error(PARSE_FATAL, "Wrong mix of special targets"); 694 dump_targets(); 695 specType = SPECIAL_ERROR; 696 return 0; 697 } 698 if (seen_normal != 0) { 699 specType = SPECIAL_NONE; 700 return 0; 701 } else if (seen_path != 0) { 702 specType = SPECIAL_PATH; 703 return 0; 704 } else if (seen_special == 0) { 705 specType = SPECIAL_NONE; 706 return 0; 707 } else if (seen_special != 1) { 708 Parse_Error(PARSE_FATAL, 709 "Mixing special targets is not allowed"); 710 dump_targets(); 711 return 0; 712 } else if (seen_special == 1) { 713 specType = gtargets.a[0]->special & SPECIAL_MASK; 714 switch (specType) { 715 case SPECIAL_MAIN: 716 if (!Lst_IsEmpty(create)) { 717 specType = SPECIAL_NONE; 718 } 719 break; 720 case SPECIAL_NOTPARALLEL: 721 { 722 extern int maxJobs; 723 724 maxJobs = 1; 725 compatMake = 1; 726 break; 727 } 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 unsigned int 743 parse_operator(const char **pos) 744 { 745 const char *cp = *pos; 746 unsigned 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 unsigned 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 unsigned 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 return; 864 } 865 866 /* 867 * NOW GO FOR THE SOURCES 868 */ 869 if (specType == SPECIAL_SUFFIXES || specType == SPECIAL_PATH || 870 specType == SPECIAL_NOTHING) { 871 while (*line) { 872 /* 873 * If the target was one that doesn't take files as its 874 * sources but takes something like suffixes, we take each 875 * space-separated word on the line as a something and deal 876 * with it accordingly. 877 * 878 * If the target was .SUFFIXES, we take each source as a 879 * suffix and add it to the list of suffixes maintained by 880 * the Suff module. 881 * 882 * If the target was a .PATH, we add the source as a 883 * directory to search on the search path. 884 * 885 * If it was .INCLUDES, the source is taken to be the 886 * suffix of files which will be #included and whose search 887 * path should be present in the .INCLUDES variable. 888 * 889 * If it was .LIBS, the source is taken to be the suffix of 890 * files which are considered libraries and whose search 891 * path should be present in the .LIBS variable. 892 * 893 * If it was .NULL, the source is the suffix to use when a 894 * file has no valid suffix. 895 */ 896 while (*cp && !ISSPACE(*cp)) 897 cp++; 898 switch (specType) { 899 case SPECIAL_SUFFIXES: 900 Suff_AddSuffixi(line, cp); 901 break; 902 case SPECIAL_PATH: 903 { 904 LstNode ln; 905 906 for (ln = Lst_First(&paths); ln != NULL; 907 ln = Lst_Adv(ln)) 908 Dir_AddDiri((Lst)Lst_Datum(ln), line, cp); 909 break; 910 } 911 default: 912 break; 913 } 914 if (*cp != '\0') 915 cp++; 916 while (ISSPACE(*cp)) 917 cp++; 918 line = cp; 919 } 920 Lst_Destroy(&paths, NOFREE); 921 } else { 922 while (*line) { 923 /* 924 * The targets take real sources, so we must beware of 925 * archive specifications (i.e. things with left 926 * parentheses in them) and handle them accordingly. 927 */ 928 while (*cp && !ISSPACE(*cp)) { 929 if (*cp == '(' && cp > line && cp[-1] != '$') { 930 /* 931 * Only stop for a left parenthesis if 932 * it isn't at the start of a word 933 * (that'll be for variable changes 934 * later) and isn't preceded by a 935 * dollar sign (a dynamic source). 936 */ 937 break; 938 } else { 939 cp++; 940 } 941 } 942 943 if (*cp == '(') { 944 GNode *gn; 945 LIST sources; /* list of archive source 946 * names after expansion */ 947 948 Lst_Init(&sources); 949 if (!Arch_ParseArchive(&line, &sources, NULL)) { 950 Parse_Error(PARSE_FATAL, 951 "Error in source archive spec \"%s\"", 952 line); 953 return; 954 } 955 956 while ((gn = (GNode *)Lst_DeQueue(&sources)) != 957 NULL) 958 ParseDoSrc(>argets, &gsources, tOp, 959 gn->name, NULL); 960 cp = line; 961 } else { 962 const char *endSrc = cp; 963 964 ParseDoSrc(>argets, &gsources, tOp, line, 965 endSrc); 966 if (*cp) 967 cp++; 968 } 969 while (ISSPACE(*cp)) 970 cp++; 971 line = cp; 972 } 973 } 974 975 if (mainNode == NULL) { 976 /* If we have yet to decide on a main target to make, in the 977 * absence of any user input, we want the first target on 978 * the first dependency line that is actually a real target 979 * (i.e. isn't a .USE or .EXEC rule) to be made. */ 980 Array_Find(>argets, ParseFindMain, NULL); 981 } 982 } 983 984 /*- 985 * ParseAddCmd -- 986 * Lst_ForEach function to add a command line to all targets 987 * 988 * The new command may be added to the commands list of the node. 989 * 990 * If the target already had commands, we ignore the new ones, but 991 * we note that we got double commands (in case we actually get to run 992 * that ambiguous target). 993 * 994 * Note this does not apply to :: dependency lines, since those 995 * will generate fresh cloned nodes and add them to the cohorts 996 * field of the main node. 997 */ 998 static void 999 ParseAddCmd(void *gnp, void *cmd) 1000 { 1001 GNode *gn = (GNode *)gnp; 1002 1003 if (!(gn->type & OP_HAS_COMMANDS)) 1004 Lst_AtEnd(&gn->commands, cmd); 1005 else 1006 gn->type |= OP_DOUBLE; 1007 } 1008 1009 /*- 1010 *----------------------------------------------------------------------- 1011 * ParseHasCommands -- 1012 * Record that the target gained commands through OP_HAS_COMMANDS, 1013 * so that double command lists may be ignored. 1014 *----------------------------------------------------------------------- 1015 */ 1016 static void 1017 ParseHasCommands(void *gnp) 1018 { 1019 GNode *gn = (GNode *)gnp; 1020 gn->type |= OP_HAS_COMMANDS; 1021 1022 } 1023 1024 1025 /* Strip comments from line. Build a copy in buffer if necessary, */ 1026 static char * 1027 strip_comments(Buffer copy, const char *line) 1028 { 1029 const char *comment; 1030 const char *p; 1031 1032 comment = strchr(line, '#'); 1033 assert(comment != line); 1034 if (comment == NULL) 1035 return (char *)line; 1036 else { 1037 Buf_Reset(copy); 1038 1039 for (p = line; *p != '\0'; p++) { 1040 if (*p == '\\') { 1041 if (p[1] == '#') { 1042 Buf_Addi(copy, line, p); 1043 Buf_AddChar(copy, '#'); 1044 line = p+2; 1045 } 1046 if (p[1] != '\0') 1047 p++; 1048 } else if (*p == '#') 1049 break; 1050 } 1051 Buf_Addi(copy, line, p); 1052 return Buf_Retrieve(copy); 1053 } 1054 } 1055 1056 1057 1058 /*** 1059 *** Support for various include constructs 1060 ***/ 1061 1062 1063 void 1064 Parse_AddIncludeDir(const char *dir) 1065 { 1066 Dir_AddDir(userIncludePath, dir); 1067 } 1068 1069 static char * 1070 resolve_include_filename(const char *file, bool isSystem) 1071 { 1072 char *fullname; 1073 1074 /* Look up system files on the system path first */ 1075 if (isSystem) { 1076 fullname = Dir_FindFileNoDot(file, systemIncludePath); 1077 if (fullname) 1078 return fullname; 1079 } 1080 1081 /* Handle non-system non-absolute files... */ 1082 if (!isSystem && file[0] != '/') { 1083 /* ... by looking first under the same directory as the 1084 * current file */ 1085 char *slash = NULL; 1086 const char *fname; 1087 1088 fname = Parse_Getfilename(); 1089 1090 if (fname != NULL) 1091 slash = strrchr(fname, '/'); 1092 1093 if (slash != NULL) { 1094 char *newName; 1095 1096 newName = Str_concati(fname, slash, file, 1097 strchr(file, '\0'), '/'); 1098 fullname = Dir_FindFile(newName, userIncludePath); 1099 if (fullname == NULL) 1100 fullname = Dir_FindFile(newName, defaultPath); 1101 free(newName); 1102 if (fullname) 1103 return fullname; 1104 } 1105 } 1106 1107 /* Now look first on the -I search path, then on the .PATH 1108 * search path, if not found in a -I directory. 1109 * XXX: Suffix specific? */ 1110 fullname = Dir_FindFile(file, userIncludePath); 1111 if (fullname) 1112 return fullname; 1113 fullname = Dir_FindFile(file, defaultPath); 1114 if (fullname) 1115 return fullname; 1116 1117 /* Still haven't found the makefile. Look for it on the system 1118 * path as a last resort (if we haven't already). */ 1119 if (isSystem) 1120 return NULL; 1121 else 1122 return Dir_FindFile(file, systemIncludePath); 1123 } 1124 1125 static void 1126 handle_include_file(const char *name, const char *ename, bool isSystem, 1127 bool errIfNotFound) 1128 { 1129 char *file; 1130 char *fullname; 1131 1132 /* Substitute for any variables in the file name before trying to 1133 * find the thing. */ 1134 file = Var_Substi(name, ename, NULL, false); 1135 1136 fullname = resolve_include_filename(file, isSystem); 1137 if (fullname == NULL && errIfNotFound) 1138 Parse_Error(PARSE_FATAL, "Could not find %s", file); 1139 free(file); 1140 1141 1142 if (fullname != NULL) { 1143 FILE *f; 1144 1145 f = fopen(fullname, "r"); 1146 if (f == NULL && errIfNotFound) 1147 Parse_Error(PARSE_FATAL, "Cannot open %s", fullname); 1148 else 1149 Parse_FromFile(fullname, f); 1150 } 1151 } 1152 1153 /* .include <file> (system) or .include "file" (normal) */ 1154 static bool 1155 lookup_bsd_include(const char *file) 1156 { 1157 char endc; 1158 const char *efile; 1159 bool isSystem; 1160 1161 /* find starting delimiter */ 1162 while (ISSPACE(*file)) 1163 file++; 1164 1165 /* determine type of file */ 1166 if (*file == '<') { 1167 isSystem = true; 1168 endc = '>'; 1169 } else if (*file == '"') { 1170 isSystem = false; 1171 endc = '"'; 1172 } else { 1173 Parse_Error(PARSE_WARNING, 1174 ".include filename must be delimited by '\"' or '<'"); 1175 return false; 1176 } 1177 1178 /* delimit file name between file and efile */ 1179 for (efile = ++file; *efile != endc; efile++) { 1180 if (*efile == '\0') { 1181 Parse_Error(PARSE_WARNING, 1182 "Unclosed .include filename. '%c' expected", endc); 1183 return false; 1184 } 1185 } 1186 handle_include_file(file, efile, isSystem, true); 1187 return true; 1188 } 1189 1190 1191 static void 1192 lookup_sysv_style_include(const char *file, const char *directive, 1193 bool errIfMissing) 1194 { 1195 const char *efile; 1196 1197 /* find beginning of name */ 1198 while (ISSPACE(*file)) 1199 file++; 1200 if (*file == '\0') { 1201 Parse_Error(PARSE_FATAL, "Filename missing from \"%s\"", 1202 directive); 1203 return; 1204 } 1205 /* sys5 delimits file up to next blank character or end of line */ 1206 for (efile = file; *efile != '\0' && !ISSPACE(*efile);) 1207 efile++; 1208 1209 handle_include_file(file, efile, true, errIfMissing); 1210 } 1211 1212 1213 /* system V construct: include file */ 1214 static void 1215 lookup_sysv_include(const char *file, const char *directive) 1216 { 1217 lookup_sysv_style_include(file, directive, true); 1218 } 1219 1220 1221 /* sinclude file and -include file */ 1222 static void 1223 lookup_conditional_include(const char *file, const char *directive) 1224 { 1225 lookup_sysv_style_include(file, directive, false); 1226 } 1227 1228 1229 /*** 1230 *** BSD-specific . constructs 1231 *** They all follow the same pattern: 1232 *** if the syntax matches BSD stuff, then we're committed to handle 1233 *** them and report fatal errors (like, include file not existing) 1234 *** otherwise, we return false, and hope somebody else will handle it. 1235 ***/ 1236 1237 static bool 1238 handle_poison(const char *line) 1239 { 1240 const char *p = line; 1241 int type = POISON_NORMAL; 1242 bool not = false; 1243 bool paren_to_match = false; 1244 const char *name, *ename; 1245 1246 while (ISSPACE(*p)) 1247 p++; 1248 if (*p == '!') { 1249 not = true; 1250 p++; 1251 } 1252 while (ISSPACE(*p)) 1253 p++; 1254 if (strncmp(p, "defined", 7) == 0) { 1255 type = POISON_DEFINED; 1256 p += 7; 1257 } else if (strncmp(p, "empty", 5) == 0) { 1258 type = POISON_EMPTY; 1259 p += 5; 1260 } 1261 while (ISSPACE(*p)) 1262 p++; 1263 if (*p == '(') { 1264 paren_to_match = true; 1265 p++; 1266 } 1267 while (ISSPACE(*p)) 1268 p++; 1269 name = ename = p; 1270 while (*p != '\0' && !ISSPACE(*p)) { 1271 if (*p == ')' && paren_to_match) { 1272 paren_to_match = false; 1273 p++; 1274 break; 1275 } 1276 p++; 1277 ename = p; 1278 } 1279 while (ISSPACE(*p)) 1280 p++; 1281 switch(type) { 1282 case POISON_NORMAL: 1283 case POISON_EMPTY: 1284 if (not) 1285 type = POISON_INVALID; 1286 break; 1287 case POISON_DEFINED: 1288 if (not) 1289 type = POISON_NOT_DEFINED; 1290 else 1291 type = POISON_INVALID; 1292 break; 1293 } 1294 if ((*p != '\0' && *p != '#') || type == POISON_INVALID) { 1295 Parse_Error(PARSE_WARNING, "Invalid syntax for .poison: %s", 1296 line); 1297 return false; 1298 } else { 1299 Var_MarkPoisoned(name, ename, type); 1300 return true; 1301 } 1302 } 1303 1304 1305 static bool 1306 handle_for_loop(Buffer linebuf, const char *line) 1307 { 1308 For *loop; 1309 1310 loop = For_Eval(line); 1311 if (loop != NULL) { 1312 bool ok; 1313 do { 1314 /* Find the matching endfor. */ 1315 line = ParseReadLoopLine(linebuf); 1316 if (line == NULL) { 1317 Parse_Error(PARSE_FATAL, 1318 "Unexpected end of file in for loop.\n"); 1319 return false; 1320 } 1321 ok = For_Accumulate(loop, line); 1322 } while (ok); 1323 For_Run(loop); 1324 return true; 1325 } else 1326 return false; 1327 } 1328 1329 static bool 1330 handle_undef(const char *line) 1331 { 1332 const char *eline; 1333 1334 while (ISSPACE(*line)) 1335 line++; 1336 for (eline = line; !ISSPACE(*eline) && *eline != '\0';) 1337 eline++; 1338 Var_Deletei(line, eline); 1339 return true; 1340 } 1341 1342 /* global hub for the construct */ 1343 static bool 1344 handle_bsd_command(Buffer linebuf, Buffer copy, const char *line) 1345 { 1346 char *stripped; 1347 1348 while (ISSPACE(*line)) 1349 line++; 1350 1351 /* delegate basic classification to the conditional module */ 1352 switch (Cond_Eval(line)) { 1353 case COND_SKIP: 1354 /* Skip to next conditional that evaluates to COND_PARSE. */ 1355 do { 1356 line = Parse_ReadNextConditionalLine(linebuf); 1357 if (line != NULL) { 1358 while (ISSPACE(*line)) 1359 line++; 1360 stripped = strip_comments(copy, line); 1361 } 1362 } while (line != NULL && Cond_Eval(stripped) != COND_PARSE); 1363 /* FALLTHROUGH */ 1364 case COND_PARSE: 1365 return true; 1366 case COND_ISFOR: 1367 return handle_for_loop(linebuf, line + 3); 1368 case COND_ISINCLUDE: 1369 return lookup_bsd_include(line + 7); 1370 case COND_ISPOISON: 1371 return handle_poison(line + 6); 1372 case COND_ISUNDEF: 1373 return handle_undef(line + 5); 1374 default: 1375 break; 1376 } 1377 1378 return false; 1379 } 1380 1381 /*** 1382 *** handle a group of commands 1383 ***/ 1384 1385 static void 1386 build_target_group(struct growableArray *targets) 1387 { 1388 unsigned int i; 1389 LstNode ln; 1390 bool seen_target = false; 1391 1392 if (targets->n == 1) 1393 return; 1394 if (targets->a[0]->groupling != NULL) 1395 return; 1396 /* XXX */ 1397 if (targets->a[0]->type & OP_TRANSFORM) 1398 return; 1399 for (ln = Lst_First(&targets->a[0]->commands); ln != NULL; 1400 ln = Lst_Adv(ln)) { 1401 struct command *cmd = Lst_Datum(ln); 1402 if (Var_Check_for_target(cmd->string)) { 1403 seen_target = true; 1404 break; 1405 } 1406 } 1407 if (DEBUG(TARGGROUP)) { 1408 fprintf(stderr, 1409 seen_target ? "No target group at %lu: ": 1410 "Target group at %lu:", Parse_Getlineno()); 1411 for (i = 0; i < targets->n; i++) 1412 fprintf(stderr, " %s", targets->a[i]->name); 1413 fprintf(stderr, "\n"); 1414 } 1415 if (seen_target) 1416 return; 1417 1418 for (i = 0; i < targets->n; i++) { 1419 targets->a[i]->groupling = targets->a[(i+1)%targets->n]; 1420 } 1421 } 1422 1423 static void 1424 finish_commands(struct growableArray *targets) 1425 { 1426 build_target_group(targets); 1427 Array_Every(targets, ParseHasCommands); 1428 } 1429 1430 static void 1431 parse_commands(struct growableArray *targets, const char *line) 1432 { 1433 /* add the command to the list of 1434 * commands of all targets in the dependency spec */ 1435 1436 struct command *cmd; 1437 size_t len = strlen(line); 1438 1439 cmd = emalloc(sizeof(struct command) + len); 1440 memcpy(&cmd->string, line, len+1); 1441 Parse_FillLocation(&cmd->location); 1442 1443 Array_ForEach(targets, ParseAddCmd, cmd); 1444 } 1445 1446 static bool 1447 parse_as_special_line(Buffer buf, Buffer copy, const char *line) 1448 { 1449 if (*line == '.' && handle_bsd_command(buf, copy, line+1)) 1450 return true; 1451 if (FEATURES(FEATURE_SYSVINCLUDE) && 1452 strncmp(line, "include", 7) == 0 && 1453 ISSPACE(line[7]) && 1454 strchr(line, ':') == NULL) { 1455 /* It's an S3/S5-style "include". */ 1456 lookup_sysv_include(line + 7, "include"); 1457 return true; 1458 } 1459 if (FEATURES(FEATURE_CONDINCLUDE) && 1460 strncmp(line, "sinclude", 8) == 0 && 1461 ISSPACE(line[8]) && 1462 strchr(line, ':') == NULL) { 1463 lookup_conditional_include(line+8, "sinclude"); 1464 return true; 1465 } 1466 if (FEATURES(FEATURE_CONDINCLUDE) && 1467 strncmp(line, "-include", 8) == 0 && 1468 ISSPACE(line[8]) && 1469 strchr(line, ':') == NULL) { 1470 lookup_conditional_include(line+8, "-include"); 1471 return true; 1472 } 1473 return false; 1474 } 1475 1476 static void 1477 parse_target_line(struct growableArray *targets, const char *line, 1478 const char *stripped, bool *pcommands_seen) 1479 { 1480 size_t pos; 1481 char *end; 1482 char *cp; 1483 char *cmd; 1484 1485 /* let's start a new set of commands */ 1486 Array_Reset(targets); 1487 1488 /* XXX this is a dirty heuristic to handle target: dep ; commands */ 1489 cmd = NULL; 1490 /* First we need to find eventual dependencies */ 1491 pos = strcspn(stripped, ":!"); 1492 /* go over :!, and find ; */ 1493 if (stripped[pos] != '\0' && 1494 (end = strchr(stripped+pos+1, ';')) != NULL) { 1495 if (line != stripped) 1496 /* find matching ; in original... The 1497 * original might be slightly longer. */ 1498 cmd = strchr(line+(end-stripped), ';'); 1499 else 1500 cmd = end; 1501 /* kill end of line. */ 1502 *end = '\0'; 1503 } 1504 /* We now know it's a dependency line so it needs to 1505 * have all variables expanded before being parsed. 1506 */ 1507 cp = Var_Subst(stripped, NULL, false); 1508 ParseDoDependency(cp); 1509 free(cp); 1510 1511 /* Parse command if it's not empty. */ 1512 if (cmd != NULL) { 1513 do { 1514 cmd++; 1515 } while (ISSPACE(*cmd)); 1516 if (*cmd != '\0') { 1517 parse_commands(targets, cmd); 1518 *pcommands_seen = true; 1519 } 1520 } 1521 } 1522 1523 void 1524 Parse_File(const char *filename, FILE *stream) 1525 { 1526 char *line; 1527 bool expectingCommands = false; 1528 bool commands_seen = false; 1529 1530 /* somewhat permanent spaces to shave time */ 1531 BUFFER buf; 1532 BUFFER copy; 1533 1534 Buf_Init(&buf, MAKE_BSIZE); 1535 Buf_Init(©, MAKE_BSIZE); 1536 1537 Parse_FromFile(filename, stream); 1538 do { 1539 while ((line = Parse_ReadNormalLine(&buf)) != NULL) { 1540 if (*line == '\t') { 1541 if (expectingCommands) { 1542 commands_seen = true; 1543 parse_commands(>argets, line+1); 1544 } else 1545 Parse_Error(PARSE_FATAL, 1546 "Unassociated shell command \"%s\"", 1547 line); 1548 } else { 1549 const char *stripped = strip_comments(©, 1550 line); 1551 if (!parse_as_special_line(&buf, ©, 1552 stripped)) { 1553 if (commands_seen) 1554 finish_commands(>argets); 1555 commands_seen = false; 1556 Array_Reset(>argets); 1557 if (Parse_As_Var_Assignment(stripped)) 1558 expectingCommands = false; 1559 else { 1560 parse_target_line(>argets, 1561 line, stripped, 1562 &commands_seen); 1563 expectingCommands = true; 1564 } 1565 } 1566 } 1567 } 1568 } while (Parse_NextFile()); 1569 1570 if (commands_seen) 1571 finish_commands(>argets); 1572 /* Make sure conditionals are clean. */ 1573 Cond_End(); 1574 1575 Parse_ReportErrors(); 1576 Buf_Destroy(&buf); 1577 Buf_Destroy(©); 1578 } 1579 1580 void 1581 Parse_Init(void) 1582 { 1583 mainNode = NULL; 1584 Static_Lst_Init(userIncludePath); 1585 Static_Lst_Init(systemIncludePath); 1586 Array_Init(>argets, TARGETS_SIZE); 1587 Array_Init(&gsources, SOURCES_SIZE); 1588 create_special_nodes(); 1589 } 1590 1591 void 1592 Parse_MainName(Lst listmain) /* result list */ 1593 { 1594 if (mainNode == NULL) { 1595 Punt("no target to make."); 1596 /*NOTREACHED*/ 1597 } else if (mainNode->type & OP_DOUBLEDEP) { 1598 Lst_AtEnd(listmain, mainNode); 1599 Lst_Concat(listmain, &mainNode->cohorts); 1600 } 1601 else 1602 Lst_AtEnd(listmain, mainNode); 1603 } 1604