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