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