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