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