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