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