parse.c revision 146140
1/*-
2 * Copyright (c) 1988, 1989, 1990, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 * Copyright (c) 1989 by Berkeley Softworks
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor.
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 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *	This product includes software developed by the University of
21 *	California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 *    may be used to endorse or promote products derived from this software
24 *    without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * @(#)parse.c	8.3 (Berkeley) 3/19/94
39 */
40
41#include <sys/cdefs.h>
42__FBSDID("$FreeBSD: head/usr.bin/make/parse.c 146140 2005-05-12 14:16:44Z harti $");
43
44/*-
45 * parse.c --
46 *	Functions to parse a makefile.
47 *
48 *	Most important structures are kept in Lsts. Directories for
49 *	the #include "..." function are kept in the 'parseIncPath' Lst, while
50 *	those for the #include <...> are kept in the 'sysIncPath' Lst. The
51 *	targets currently being defined are kept in the 'targets' Lst.
52 *
53 * Interface:
54 *
55 *	Parse_File	Function used to parse a makefile. It must
56 *			be given the name of the file, which should
57 *			already have been opened, and a function
58 *			to call to read a character from the file.
59 *
60 *	Parse_IsVar	Returns TRUE if the given line is a
61 *			variable assignment. Used by MainParseArgs
62 *			to determine if an argument is a target
63 *			or a variable assignment. Used internally
64 *			for pretty much the same thing...
65 *
66 *	Parse_Error	Function called when an error occurs in
67 *			parsing. Used by the variable and
68 *			conditional modules.
69 *
70 *	Parse_MainName	Returns a Lst of the main target to create.
71 */
72
73#include <assert.h>
74#include <ctype.h>
75#include <stdarg.h>
76#include <string.h>
77#include <stdlib.h>
78#include <err.h>
79
80#include "arch.h"
81#include "buf.h"
82#include "cond.h"
83#include "config.h"
84#include "dir.h"
85#include "for.h"
86#include "globals.h"
87#include "GNode.h"
88#include "hash_tables.h"
89#include "job.h"
90#include "make.h"
91#include "parse.h"
92#include "pathnames.h"
93#include "str.h"
94#include "suff.h"
95#include "targ.h"
96#include "util.h"
97#include "var.h"
98
99/*
100 * These values are returned by ParsePopInput to tell Parse_File whether to
101 * CONTINUE parsing, i.e. it had only reached the end of an include file,
102 * or if it's DONE.
103 */
104#define	CONTINUE	1
105#define	DONE		0
106
107/* targets we're working on */
108static Lst targets = Lst_Initializer(targets);
109
110/* true if currently in a dependency line or its commands */
111static Boolean inLine;
112
113static int fatals = 0;
114
115/*
116 * The main target to create. This is the first target on the
117 * first dependency line in the first makefile.
118 */
119static GNode *mainNode;
120
121/*
122 * Definitions for handling #include specifications
123 */
124struct IFile {
125	char	*fname;		/* name of previous file */
126	int	lineno;		/* saved line number */
127	FILE	*F;		/* the open stream */
128	char	*str;		/* the string when parsing a string */
129	char	*ptr;		/* the current pointer when parsing a string */
130	TAILQ_ENTRY(IFile) link;/* stack the files */
131};
132
133/* stack of IFiles generated by * #includes */
134static TAILQ_HEAD(, IFile) includes = TAILQ_HEAD_INITIALIZER(includes);
135
136/* access current file */
137#define	CURFILE	(TAILQ_FIRST(&includes))
138
139/* list of directories for "..." includes */
140struct Path parseIncPath = TAILQ_HEAD_INITIALIZER(parseIncPath);
141
142/* list of directories for <...> includes */
143struct Path sysIncPath = TAILQ_HEAD_INITIALIZER(sysIncPath);
144
145/*
146 * specType contains the SPECial TYPE of the current target. It is
147 * Not if the target is unspecial. If it *is* special, however, the children
148 * are linked as children of the parent but not vice versa. This variable is
149 * set in ParseDoDependency
150 */
151typedef enum {
152	Begin,		/* .BEGIN */
153	Default,	/* .DEFAULT */
154	End,		/* .END */
155	ExportVar,	/* .EXPORTVAR */
156	Ignore,		/* .IGNORE */
157	Includes,	/* .INCLUDES */
158	Interrupt,	/* .INTERRUPT */
159	Libs,		/* .LIBS */
160	MFlags,		/* .MFLAGS or .MAKEFLAGS */
161	Main,		/* .MAIN and we don't have anyth. user-spec. to make */
162	Not,		/* Not special */
163	NotParallel,	/* .NOTPARALELL */
164	Null,		/* .NULL */
165	Order,		/* .ORDER */
166	Parallel,	/* .PARALLEL */
167	ExPath,		/* .PATH */
168	Phony,		/* .PHONY */
169	Posix,		/* .POSIX */
170	Precious,	/* .PRECIOUS */
171	ExShell,	/* .SHELL */
172	Silent,		/* .SILENT */
173	SingleShell,	/* .SINGLESHELL */
174	Suffixes,	/* .SUFFIXES */
175	Wait,		/* .WAIT */
176	Warn,		/* .WARN */
177	Attribute	/* Generic attribute */
178} ParseSpecial;
179
180static ParseSpecial specType;
181static int waiting;
182
183/*
184 * Predecessor node for handling .ORDER. Initialized to NULL when .ORDER
185 * seen, then set to each successive source on the line.
186 */
187static GNode *predecessor;
188
189/*
190 * The parseKeywords table is searched using binary search when deciding
191 * if a target or source is special. The 'spec' field is the ParseSpecial
192 * type of the keyword ("Not" if the keyword isn't special as a target) while
193 * the 'op' field is the operator to apply to the list of targets if the
194 * keyword is used as a source ("0" if the keyword isn't special as a source)
195 */
196static const struct keyword {
197	const char	*name;	/* Name of keyword */
198	ParseSpecial	spec;	/* Type when used as a target */
199	int		op;	/* Operator when used as a source */
200} parseKeywords[] = {
201	/* KEYWORD-START-TAG */
202	{ ".BEGIN",		Begin,		0 },
203	{ ".DEFAULT",		Default,	0 },
204	{ ".END",		End,		0 },
205	{ ".EXEC",		Attribute,	OP_EXEC },
206	{ ".EXPORTVAR",		ExportVar,	0 },
207	{ ".IGNORE",		Ignore,		OP_IGNORE },
208	{ ".INCLUDES",		Includes,	0 },
209	{ ".INTERRUPT",		Interrupt,	0 },
210	{ ".INVISIBLE",		Attribute,	OP_INVISIBLE },
211	{ ".JOIN",		Attribute,	OP_JOIN },
212	{ ".LIBS",		Libs,		0 },
213	{ ".MAIN",		Main,		0 },
214	{ ".MAKE",		Attribute,	OP_MAKE },
215	{ ".MAKEFLAGS",		MFlags,		0 },
216	{ ".MFLAGS",		MFlags,		0 },
217	{ ".NOTMAIN",		Attribute,	OP_NOTMAIN },
218	{ ".NOTPARALLEL",	NotParallel,	0 },
219	{ ".NO_PARALLEL",	NotParallel,	0 },
220	{ ".NULL",		Null,		0 },
221	{ ".OPTIONAL",		Attribute,	OP_OPTIONAL },
222	{ ".ORDER",		Order,		0 },
223	{ ".PARALLEL",		Parallel,	0 },
224	{ ".PATH",		ExPath,		0 },
225	{ ".PHONY",		Phony,		OP_PHONY },
226	{ ".POSIX",		Posix,		0 },
227	{ ".PRECIOUS",		Precious,	OP_PRECIOUS },
228	{ ".RECURSIVE",		Attribute,	OP_MAKE },
229	{ ".SHELL",		ExShell,	0 },
230	{ ".SILENT",		Silent,		OP_SILENT },
231	{ ".SINGLESHELL",	SingleShell,	0 },
232	{ ".SUFFIXES",		Suffixes,	0 },
233	{ ".USE",		Attribute,	OP_USE },
234	{ ".WAIT",		Wait,		0 },
235	{ ".WARN",		Warn,		0 },
236	/* KEYWORD-END-TAG */
237};
238#define	NKEYWORDS	(sizeof(parseKeywords) / sizeof(parseKeywords[0]))
239
240static void parse_include(char *, int, int);
241static void parse_message(char *, int, int);
242static void parse_undef(char *, int, int);
243static void parse_for(char *, int, int);
244static void parse_endfor(char *, int, int);
245
246static const struct directive {
247	const char	*name;
248	int		code;
249	Boolean		skip_flag;	/* execute even when skipped */
250	void		(*func)(char *, int, int);
251} directives[] = {
252	/* DIRECTIVES-START-TAG */
253	{ "elif",	COND_ELIF,	TRUE,	Cond_If },
254	{ "elifdef",	COND_ELIFDEF,	TRUE,	Cond_If },
255	{ "elifmake",	COND_ELIFMAKE,	TRUE,	Cond_If },
256	{ "elifndef",	COND_ELIFNDEF,	TRUE,	Cond_If },
257	{ "elifnmake",	COND_ELIFNMAKE,	TRUE,	Cond_If },
258	{ "else",	COND_ELSE,	TRUE,	Cond_Else },
259	{ "endfor",	0,		FALSE,	parse_endfor },
260	{ "endif",	COND_ENDIF,	TRUE,	Cond_Endif },
261	{ "error",	1,		FALSE,	parse_message },
262	{ "for",	0,		FALSE,	parse_for },
263	{ "if",		COND_IF,	TRUE,	Cond_If },
264	{ "ifdef",	COND_IFDEF,	TRUE,	Cond_If },
265	{ "ifmake",	COND_IFMAKE,	TRUE,	Cond_If },
266	{ "ifndef",	COND_IFNDEF,	TRUE,	Cond_If },
267	{ "ifnmake",	COND_IFNMAKE,	TRUE,	Cond_If },
268	{ "include",	0,		FALSE,	parse_include },
269	{ "undef",	0,		FALSE,	parse_undef },
270	{ "warning",	0,		FALSE,	parse_message },
271	/* DIRECTIVES-END-TAG */
272};
273#define	NDIRECTS	(sizeof(directives) / sizeof(directives[0]))
274
275/*-
276 * ParseFindKeyword
277 *	Look in the table of keywords for one matching the given string.
278 *
279 * Results:
280 *	The pointer to keyword table entry or NULL.
281 */
282static const struct keyword *
283ParseFindKeyword(const char *str)
284{
285	int kw;
286
287	kw = keyword_hash(str, strlen(str));
288	if (kw < 0 || kw >= (int)NKEYWORDS ||
289	    strcmp(str, parseKeywords[kw].name) != 0)
290		return (NULL);
291	return (&parseKeywords[kw]);
292}
293
294/*-
295 * Parse_Error  --
296 *	Error message abort function for parsing. Prints out the context
297 *	of the error (line number and file) as well as the message with
298 *	two optional arguments.
299 *
300 * Results:
301 *	None
302 *
303 * Side Effects:
304 *	"fatals" is incremented if the level is PARSE_FATAL.
305 */
306/* VARARGS */
307void
308Parse_Error(int type, const char *fmt, ...)
309{
310	va_list ap;
311
312	va_start(ap, fmt);
313	if (CURFILE != NULL)
314		fprintf(stderr, "\"%s\", line %d: ",
315		    CURFILE->fname, CURFILE->lineno);
316	if (type == PARSE_WARNING)
317		fprintf(stderr, "warning: ");
318	vfprintf(stderr, fmt, ap);
319	va_end(ap);
320	fprintf(stderr, "\n");
321	fflush(stderr);
322	if (type == PARSE_FATAL)
323		fatals += 1;
324}
325
326/**
327 * ParsePushInput
328 *
329 * Push a new input source onto the input stack. If ptr is NULL
330 * the fullname is used to fopen the file. If it is not NULL,
331 * ptr is assumed to point to the string to be parsed. If opening the
332 * file fails, the fullname is freed.
333 */
334static void
335ParsePushInput(char *fullname, FILE *fp, char *ptr, int lineno)
336{
337	struct IFile *nf;
338
339	nf = emalloc(sizeof(*nf));
340	nf->fname = fullname;
341	nf->lineno = lineno;
342
343	if (ptr == NULL) {
344		/* the input source is a file */
345		if ((nf->F = fp) == NULL) {
346			nf->F = fopen(fullname, "r");
347			if (nf->F == NULL) {
348				Parse_Error(PARSE_FATAL, "Cannot open %s",
349				    fullname);
350				free(fullname);
351				free(nf);
352				return;
353			}
354		}
355		nf->str = nf->ptr = NULL;
356		Var_Append(".MAKEFILE_LIST", fullname, VAR_GLOBAL);
357	} else {
358		nf->str = nf->ptr = ptr;
359		nf->F = NULL;
360	}
361	TAILQ_INSERT_HEAD(&includes, nf, link);
362}
363
364/**
365 * ParsePopInput
366 *	Called when EOF is reached in the current file. If we were reading
367 *	an include file, the includes stack is popped and things set up
368 *	to go back to reading the previous file at the previous location.
369 *
370 * Results:
371 *	CONTINUE if there's more to do. DONE if not.
372 *
373 * Side Effects:
374 *	The old curFile.F is closed. The includes list is shortened.
375 *	curFile.lineno, curFile.F, and curFile.fname are changed if
376 *	CONTINUE is returned.
377 */
378static int
379ParsePopInput(void)
380{
381	struct IFile *ifile;	/* the state on the top of the includes stack */
382
383	assert(!TAILQ_EMPTY(&includes));
384
385	ifile = TAILQ_FIRST(&includes);
386	TAILQ_REMOVE(&includes, ifile, link);
387
388	free(ifile->fname);
389	if (ifile->F != NULL) {
390		fclose(ifile->F);
391		Var_Append(".MAKEFILE_LIST", "..", VAR_GLOBAL);
392	}
393	if (ifile->str != NULL) {
394		free(ifile->str);
395	}
396	free(ifile);
397
398	return (TAILQ_EMPTY(&includes) ? DONE : CONTINUE);
399}
400
401/**
402 * parse_warn
403 *	Parse the .WARN pseudo-target.
404 */
405static void
406parse_warn(char *line)
407{
408	char **argv;
409	int argc;
410	int i;
411
412	argv = brk_string(line, &argc, TRUE);
413
414	for (i = 1; i < argc; i++)
415		Main_ParseWarn(argv[i], 0);
416}
417
418/*-
419 *---------------------------------------------------------------------
420 * ParseLinkSrc  --
421 *	Link the parent nodes to their new child. Used by
422 *	ParseDoDependency. If the specType isn't 'Not', the parent
423 *	isn't linked as a parent of the child.
424 *
425 * Side Effects:
426 *	New elements are added to the parents lists of cgn and the
427 *	children list of cgn. the unmade field of pgn is updated
428 *	to reflect the additional child.
429 *---------------------------------------------------------------------
430 */
431static void
432ParseLinkSrc(Lst *parents, GNode *cgn)
433{
434	LstNode	*ln;
435	GNode *pgn;
436
437	LST_FOREACH(ln, parents) {
438		pgn = Lst_Datum(ln);
439		if (Lst_Member(&pgn->children, cgn) == NULL) {
440			Lst_AtEnd(&pgn->children, cgn);
441			if (specType == Not) {
442				Lst_AtEnd(&cgn->parents, pgn);
443			}
444			pgn->unmade += 1;
445		}
446	}
447}
448
449/*-
450 *---------------------------------------------------------------------
451 * ParseDoOp  --
452 *	Apply the parsed operator to all target nodes. Used in
453 *	ParseDoDependency once all targets have been found and their
454 *	operator parsed. If the previous and new operators are incompatible,
455 *	a major error is taken.
456 *
457 * Side Effects:
458 *	The type field of the node is altered to reflect any new bits in
459 *	the op.
460 *---------------------------------------------------------------------
461 */
462static void
463ParseDoOp(int op)
464{
465	GNode	*cohort;
466	LstNode	*ln;
467	GNode	*gn;
468
469	LST_FOREACH(ln, &targets) {
470		gn = Lst_Datum(ln);
471
472		/*
473		 * If the dependency mask of the operator and the node don't
474		 * match and the node has actually had an operator applied to
475		 * it before, and the operator actually has some dependency
476		 * information in it, complain.
477		 */
478		if ((op & OP_OPMASK) != (gn->type & OP_OPMASK) &&
479		    !OP_NOP(gn->type) && !OP_NOP(op)) {
480			Parse_Error(PARSE_FATAL, "Inconsistent operator for %s",
481			    gn->name);
482			return;
483		}
484
485		if (op == OP_DOUBLEDEP &&
486		    (gn->type & OP_OPMASK) == OP_DOUBLEDEP) {
487			/*
488			 * If the node was the object of a :: operator, we need
489			 * to create a new instance of it for the children and
490			 * commands on this dependency line. The new instance
491			 * is placed on the 'cohorts' list of the initial one
492			 * (note the initial one is not on its own cohorts list)
493			 * and the new instance is linked to all parents of the
494			 * initial instance.
495			 */
496			cohort = Targ_NewGN(gn->name);
497
498			/*
499			 * Duplicate links to parents so graph traversal is
500			 * simple. Perhaps some type bits should be duplicated?
501			 *
502			 * Make the cohort invisible as well to avoid
503			 * duplicating it into other variables. True, parents
504			 * of this target won't tend to do anything with their
505			 * local variables, but better safe than sorry.
506			 */
507			ParseLinkSrc(&gn->parents, cohort);
508			cohort->type = OP_DOUBLEDEP|OP_INVISIBLE;
509			Lst_AtEnd(&gn->cohorts, cohort);
510
511			/*
512			 * Replace the node in the targets list with the
513			 * new copy
514			 */
515			Lst_Replace(ln, cohort);
516			gn = cohort;
517		}
518		/*
519		 * We don't want to nuke any previous flags (whatever they were)
520		 * so we just OR the new operator into the old
521		 */
522		gn->type |= op;
523	}
524}
525
526/*-
527 *---------------------------------------------------------------------
528 * ParseDoSrc  --
529 *	Given the name of a source, figure out if it is an attribute
530 *	and apply it to the targets if it is. Else decide if there is
531 *	some attribute which should be applied *to* the source because
532 *	of some special target and apply it if so. Otherwise, make the
533 *	source be a child of the targets in the list 'targets'
534 *
535 * Results:
536 *	None
537 *
538 * Side Effects:
539 *	Operator bits may be added to the list of targets or to the source.
540 *	The targets may have a new source added to their lists of children.
541 *---------------------------------------------------------------------
542 */
543static void
544ParseDoSrc(int tOp, char *src, Lst *allsrc)
545{
546	GNode	*gn = NULL;
547	const struct keyword *kw;
548
549	if (src[0] == '.' && isupper ((unsigned char)src[1])) {
550		if ((kw = ParseFindKeyword(src)) != NULL) {
551			if (kw->op != 0) {
552				ParseDoOp(kw->op);
553				return;
554			}
555			if (kw->spec == Wait) {
556				waiting++;
557				return;
558			}
559		}
560	}
561
562	switch (specType) {
563	  case Main:
564		/*
565		 * If we have noted the existence of a .MAIN, it means we need
566		 * to add the sources of said target to the list of things
567		 * to create. The string 'src' is likely to be free, so we
568		 * must make a new copy of it. Note that this will only be
569		 * invoked if the user didn't specify a target on the command
570		 * line. This is to allow #ifmake's to succeed, or something...
571		 */
572		Lst_AtEnd(&create, estrdup(src));
573		/*
574		 * Add the name to the .TARGETS variable as well, so the user
575		 * can employ that, if desired.
576		 */
577		Var_Append(".TARGETS", src, VAR_GLOBAL);
578		return;
579
580	  case Order:
581		/*
582		 * Create proper predecessor/successor links between the
583		 * previous source and the current one.
584		 */
585		gn = Targ_FindNode(src, TARG_CREATE);
586		if (predecessor != NULL) {
587			Lst_AtEnd(&predecessor->successors, gn);
588			Lst_AtEnd(&gn->preds, predecessor);
589		}
590		/*
591		 * The current source now becomes the predecessor for the next
592		 * one.
593		 */
594		predecessor = gn;
595		break;
596
597	  default:
598		/*
599		 * If the source is not an attribute, we need to find/create
600		 * a node for it. After that we can apply any operator to it
601		 * from a special target or link it to its parents, as
602		 * appropriate.
603		 *
604		 * In the case of a source that was the object of a :: operator,
605		 * the attribute is applied to all of its instances (as kept in
606		 * the 'cohorts' list of the node) or all the cohorts are linked
607		 * to all the targets.
608		 */
609		gn = Targ_FindNode(src, TARG_CREATE);
610		if (tOp) {
611			gn->type |= tOp;
612		} else {
613			ParseLinkSrc(&targets, gn);
614		}
615		if ((gn->type & OP_OPMASK) == OP_DOUBLEDEP) {
616			GNode	*cohort;
617			LstNode	*ln;
618
619			for (ln = Lst_First(&gn->cohorts); ln != NULL;
620			    ln = Lst_Succ(ln)) {
621				cohort = Lst_Datum(ln);
622				if (tOp) {
623					cohort->type |= tOp;
624				} else {
625					ParseLinkSrc(&targets, cohort);
626				}
627			}
628		}
629		break;
630	}
631
632	gn->order = waiting;
633	Lst_AtEnd(allsrc, gn);
634	if (waiting) {
635		LstNode	*ln;
636		GNode	*p;
637
638		/*
639		 * Check if GNodes needs to be synchronized.
640		 * This has to be when two nodes are on different sides of a
641		 * .WAIT directive.
642		 */
643		LST_FOREACH(ln, allsrc) {
644			p = Lst_Datum(ln);
645
646			if (p->order >= gn->order)
647				break;
648			/*
649			 * XXX: This can cause loops, and loops can cause
650			 * unmade targets, but checking is tedious, and the
651			 * debugging output can show the problem
652			 */
653			Lst_AtEnd(&p->successors, gn);
654			Lst_AtEnd(&gn->preds, p);
655		}
656	}
657}
658
659
660/*-
661 *---------------------------------------------------------------------
662 * ParseDoDependency  --
663 *	Parse the dependency line in line.
664 *
665 * Results:
666 *	None
667 *
668 * Side Effects:
669 *	The nodes of the sources are linked as children to the nodes of the
670 *	targets. Some nodes may be created.
671 *
672 *	We parse a dependency line by first extracting words from the line and
673 * finding nodes in the list of all targets with that name. This is done
674 * until a character is encountered which is an operator character. Currently
675 * these are only ! and :. At this point the operator is parsed and the
676 * pointer into the line advanced until the first source is encountered.
677 *	The parsed operator is applied to each node in the 'targets' list,
678 * which is where the nodes found for the targets are kept, by means of
679 * the ParseDoOp function.
680 *	The sources are read in much the same way as the targets were except
681 * that now they are expanded using the wildcarding scheme of the C-Shell
682 * and all instances of the resulting words in the list of all targets
683 * are found. Each of the resulting nodes is then linked to each of the
684 * targets as one of its children.
685 *	Certain targets are handled specially. These are the ones detailed
686 * by the specType variable.
687 *	The storing of transformation rules is also taken care of here.
688 * A target is recognized as a transformation rule by calling
689 * Suff_IsTransform. If it is a transformation rule, its node is gotten
690 * from the suffix module via Suff_AddTransform rather than the standard
691 * Targ_FindNode in the target module.
692 *---------------------------------------------------------------------
693 */
694static void
695ParseDoDependency(char *line)
696{
697	char	*cp;	/* our current position */
698	GNode	*gn;	/* a general purpose temporary node */
699	int	op;	/* the operator on the line */
700	char	savec;	/* a place to save a character */
701	Lst	paths;	/* Search paths to alter when parsing .PATH targets */
702	int	tOp;	/* operator from special target */
703	LstNode	*ln;
704	const struct keyword *kw;
705
706	tOp = 0;
707
708	specType = Not;
709	waiting = 0;
710	Lst_Init(&paths);
711
712	do {
713		for (cp = line;
714		    *cp && !isspace((unsigned char)*cp) && *cp != '(';
715		    cp++) {
716			if (*cp == '$') {
717				/*
718				 * Must be a dynamic source (would have been
719				 * expanded otherwise), so call the Var module
720				 * to parse the puppy so we can safely advance
721				 * beyond it...There should be no errors in this
722				 * as they would have been discovered in the
723				 * initial Var_Subst and we wouldn't be here.
724				 */
725				size_t	length = 0;
726				Boolean	freeIt;
727				char	*result;
728
729				result = Var_Parse(cp, VAR_CMD, TRUE,
730				    &length, &freeIt);
731
732				if (freeIt) {
733					free(result);
734				}
735				cp += length - 1;
736
737			} else if (*cp == '!' || *cp == ':') {
738				/*
739				 * We don't want to end a word on ':' or '!' if
740				 * there is a better match later on in the
741				 * string (greedy matching).
742				 * This allows the user to have targets like:
743				 *    fie::fi:fo: fum
744				 *    foo::bar:
745				 * where "fie::fi:fo" and "foo::bar" are the
746				 * targets. In real life this is used for perl5
747				 * library man pages where "::" separates an
748				 * object from its class. Ie:
749				 * "File::Spec::Unix". This behaviour is also
750				 * consistent with other versions of make.
751				 */
752				char *p = cp + 1;
753
754				if (*cp == ':' && *p == ':')
755					p++;
756
757				/* Found the best match already. */
758				if (*p == '\0' || isspace(*p))
759					break;
760
761				p += strcspn(p, "!:");
762
763				/* No better match later on... */
764				if (*p == '\0')
765					break;
766			}
767			continue;
768		}
769		if (*cp == '(') {
770			/*
771			 * Archives must be handled specially to make sure the
772			 * OP_ARCHV flag is set in their 'type' field, for one
773			 * thing, and because things like "archive(file1.o
774			 * file2.o file3.o)" are permissible. Arch_ParseArchive
775			 * will set 'line' to be the first non-blank after the
776			 * archive-spec. It creates/finds nodes for the members
777			 * and places them on the given list, returning SUCCESS
778			 * if all went well and FAILURE if there was an error in
779			 * the specification. On error, line should remain
780			 * untouched.
781			 */
782			if (Arch_ParseArchive(&line, &targets, VAR_CMD) !=
783			    SUCCESS) {
784				Parse_Error(PARSE_FATAL,
785				    "Error in archive specification: \"%s\"",
786				    line);
787				return;
788			} else {
789				cp = line;
790				continue;
791			}
792		}
793		savec = *cp;
794
795		if (!*cp) {
796			/*
797			 * Ending a dependency line without an operator is a				 * Bozo no-no. As a heuristic, this is also often
798			 * triggered by undetected conflicts from cvs/rcs
799			 * merges.
800			 */
801			if (strncmp(line, "<<<<<<", 6) == 0 ||
802			    strncmp(line, "======", 6) == 0 ||
803			    strncmp(line, ">>>>>>", 6) == 0) {
804				Parse_Error(PARSE_FATAL, "Makefile appears to "
805				    "contain unresolved cvs/rcs/??? merge "
806				    "conflicts");
807			} else
808				Parse_Error(PARSE_FATAL, "Need an operator");
809			return;
810		}
811		*cp = '\0';
812		/*
813		 * Have a word in line. See if it's a special target and set
814		 * specType to match it.
815		 */
816		if (*line == '.' && isupper((unsigned char)line[1])) {
817			/*
818			 * See if the target is a special target that must have
819			 * it or its sources handled specially.
820			 */
821			if ((kw = ParseFindKeyword(line)) != NULL) {
822				if (specType == ExPath && kw->spec != ExPath) {
823					Parse_Error(PARSE_FATAL,
824					    "Mismatched special targets");
825					return;
826				}
827
828				specType = kw->spec;
829				tOp = kw->op;
830
831				/*
832				 * Certain special targets have special
833				 * semantics:
834				 *  .PATH	Have to set the dirSearchPath
835				 *		variable too
836				 *  .MAIN	Its sources are only used if
837				 *		nothing has been specified to
838				 *		create.
839				 *  .DEFAULT    Need to create a node to hang
840				 *		commands on, but we don't want
841				 *		it in the graph, nor do we want
842				 *		it to be the Main Target, so we
843				 *		create it, set OP_NOTMAIN and
844				 *		add it to the list, setting
845				 *		DEFAULT to the new node for
846				 *		later use. We claim the node is
847				 *		A transformation rule to make
848				 *		life easier later, when we'll
849				 *		use Make_HandleUse to actually
850				 *		apply the .DEFAULT commands.
851				 *  .PHONY	The list of targets
852				 *  .BEGIN
853				 *  .END
854				 *  .INTERRUPT	Are not to be considered the
855				 *		main target.
856				 *  .NOTPARALLEL Make only one target at a time.
857				 *  .SINGLESHELL Create a shell for each
858				 *		command.
859				 *  .ORDER	Must set initial predecessor
860				 *		to NULL
861				 */
862				switch (specType) {
863				  case ExPath:
864					Lst_AtEnd(&paths, &dirSearchPath);
865					break;
866				  case Main:
867					if (!Lst_IsEmpty(&create)) {
868						specType = Not;
869					}
870					break;
871				  case Begin:
872				  case End:
873				  case Interrupt:
874					gn = Targ_FindNode(line, TARG_CREATE);
875					gn->type |= OP_NOTMAIN;
876					Lst_AtEnd(&targets, gn);
877					break;
878				  case Default:
879					gn = Targ_NewGN(".DEFAULT");
880					gn->type |= (OP_NOTMAIN|OP_TRANSFORM);
881					Lst_AtEnd(&targets, gn);
882					DEFAULT = gn;
883					break;
884				  case NotParallel:
885					jobLimit = 1;
886					break;
887				  case SingleShell:
888					compatMake = 1;
889					break;
890				  case Order:
891					predecessor = NULL;
892					break;
893				  default:
894					break;
895				}
896
897			} else if (strncmp(line, ".PATH", 5) == 0) {
898				/*
899				 * .PATH<suffix> has to be handled specially.
900				 * Call on the suffix module to give us a path
901				 * to modify.
902				 */
903				struct Path *path;
904
905				specType = ExPath;
906				path = Suff_GetPath(&line[5]);
907				if (path == NULL) {
908					Parse_Error(PARSE_FATAL, "Suffix '%s' "
909					    "not defined (yet)", &line[5]);
910					return;
911				} else
912					Lst_AtEnd(&paths, path);
913			}
914		}
915
916		/*
917		 * Have word in line. Get or create its node and stick it at
918		 * the end of the targets list
919		 */
920		if (specType == Not && *line != '\0') {
921
922			/* target names to be found and added to targets list */
923			Lst curTargs = Lst_Initializer(curTargs);
924
925			if (Dir_HasWildcards(line)) {
926				/*
927				 * Targets are to be sought only in the current
928				 * directory, so create an empty path for the
929				 * thing. Note we need to use Path_Clear in the
930				 * destruction of the path as the Dir module
931				 * could have added a directory to the path...
932				 */
933				struct Path emptyPath =
934				    TAILQ_HEAD_INITIALIZER(emptyPath);
935
936				Path_Expand(line, &emptyPath, &curTargs);
937				Path_Clear(&emptyPath);
938
939			} else {
940				/*
941				 * No wildcards, but we want to avoid code
942				 * duplication, so create a list with the word
943				 * on it.
944				 */
945				Lst_AtEnd(&curTargs, line);
946			}
947
948			while (!Lst_IsEmpty(&curTargs)) {
949				char	*targName = Lst_DeQueue(&curTargs);
950
951				if (!Suff_IsTransform (targName)) {
952					gn = Targ_FindNode(targName,
953					    TARG_CREATE);
954				} else {
955					gn = Suff_AddTransform(targName);
956				}
957
958				Lst_AtEnd(&targets, gn);
959			}
960		} else if (specType == ExPath && *line != '.' && *line != '\0'){
961			Parse_Error(PARSE_WARNING, "Extra target (%s) ignored",
962			    line);
963		}
964
965		*cp = savec;
966		/*
967		 * If it is a special type and not .PATH, it's the only
968		 * target we allow on this line...
969		 */
970		if (specType != Not && specType != ExPath) {
971			Boolean warnFlag = FALSE;
972
973			while (*cp != '!' && *cp != ':' && *cp) {
974				if (*cp != ' ' && *cp != '\t') {
975					warnFlag = TRUE;
976				}
977				cp++;
978			}
979			if (warnFlag) {
980				Parse_Error(PARSE_WARNING,
981				    "Extra target ignored");
982			}
983		} else {
984			while (*cp && isspace((unsigned char)*cp)) {
985				cp++;
986			}
987		}
988		line = cp;
989	} while (*line != '!' && *line != ':' && *line);
990
991	if (!Lst_IsEmpty(&targets)) {
992		switch (specType) {
993		  default:
994			Parse_Error(PARSE_WARNING, "Special and mundane "
995			    "targets don't mix. Mundane ones ignored");
996			break;
997		  case Default:
998		  case Begin:
999		  case End:
1000		  case Interrupt:
1001			/*
1002			 * These four create nodes on which to hang commands, so
1003			 * targets shouldn't be empty...
1004			 */
1005		  case Not:
1006			/*
1007			 * Nothing special here -- targets can be empty if it
1008			 * wants.
1009			 */
1010			break;
1011		}
1012	}
1013
1014	/*
1015	 * Have now parsed all the target names. Must parse the operator next.
1016	 * The result is left in op.
1017	 */
1018	if (*cp == '!') {
1019		op = OP_FORCE;
1020	} else if (*cp == ':') {
1021		if (cp[1] == ':') {
1022			op = OP_DOUBLEDEP;
1023			cp++;
1024		} else {
1025			op = OP_DEPENDS;
1026		}
1027	} else {
1028		Parse_Error(PARSE_FATAL, "Missing dependency operator");
1029		return;
1030	}
1031
1032	cp++;			/* Advance beyond operator */
1033
1034	ParseDoOp(op);
1035
1036	/*
1037	 * Get to the first source
1038	 */
1039	while (*cp && isspace((unsigned char)*cp)) {
1040		cp++;
1041	}
1042	line = cp;
1043
1044	/*
1045	 * Several special targets take different actions if present with no
1046	 * sources:
1047	 *	a .SUFFIXES line with no sources clears out all old suffixes
1048	 *	a .PRECIOUS line makes all targets precious
1049	 *	a .IGNORE line ignores errors for all targets
1050	 *	a .SILENT line creates silence when making all targets
1051	 *	a .PATH removes all directories from the search path(s).
1052	 */
1053	if (!*line) {
1054		switch (specType) {
1055		  case Suffixes:
1056			Suff_ClearSuffixes();
1057			break;
1058		  case Precious:
1059			allPrecious = TRUE;
1060			break;
1061		  case Ignore:
1062			ignoreErrors = TRUE;
1063			break;
1064		  case Silent:
1065			beSilent = TRUE;
1066			break;
1067		  case ExPath:
1068			LST_FOREACH(ln, &paths)
1069			Path_Clear(Lst_Datum(ln));
1070			break;
1071		  case Posix:
1072			Var_Set("%POSIX", "1003.2", VAR_GLOBAL);
1073			break;
1074		  default:
1075			break;
1076		}
1077
1078	} else if (specType == MFlags) {
1079		/*
1080		 * Call on functions in main.c to deal with these arguments and
1081		 * set the initial character to a null-character so the loop to
1082		 * get sources won't get anything
1083		 */
1084		Main_ParseArgLine(line, 0);
1085		*line = '\0';
1086
1087	} else if (specType == Warn) {
1088		parse_warn(line);
1089		*line = '\0';
1090
1091	} else if (specType == ExShell) {
1092		if (Job_ParseShell(line) != SUCCESS) {
1093			Parse_Error(PARSE_FATAL,
1094			    "improper shell specification");
1095			return;
1096		}
1097		*line = '\0';
1098
1099	} else if (specType == NotParallel || specType == SingleShell) {
1100		*line = '\0';
1101	}
1102
1103	/*
1104	* NOW GO FOR THE SOURCES
1105	*/
1106	if (specType == Suffixes || specType == ExPath ||
1107	    specType == Includes || specType == Libs ||
1108	    specType == Null) {
1109		while (*line) {
1110			/*
1111			 * If the target was one that doesn't take files as its
1112			 * sources but takes something like suffixes, we take
1113			 * each space-separated word on the line as a something
1114			 * and deal with it accordingly.
1115			 *
1116			 * If the target was .SUFFIXES, we take each source as
1117			 * a suffix and add it to the list of suffixes
1118			 * maintained by the Suff module.
1119			 *
1120			 * If the target was a .PATH, we add the source as a
1121			 * directory to search on the search path.
1122			 *
1123			 * If it was .INCLUDES, the source is taken to be the
1124			 * suffix of files which will be #included and whose
1125			 * search path should be present in the .INCLUDES
1126			 * variable.
1127			 *
1128			 * If it was .LIBS, the source is taken to be the
1129			 * suffix of files which are considered libraries and
1130			 * whose search path should be present in the .LIBS
1131			 * variable.
1132			 *
1133			 * If it was .NULL, the source is the suffix to use
1134			 * when a file has no valid suffix.
1135			 */
1136			char  savech;
1137			while (*cp && !isspace((unsigned char)*cp)) {
1138				cp++;
1139			}
1140			savech = *cp;
1141			*cp = '\0';
1142			switch (specType) {
1143			  case Suffixes:
1144				Suff_AddSuffix(line);
1145				break;
1146			  case ExPath:
1147				LST_FOREACH(ln, &paths)
1148					Path_AddDir(Lst_Datum(ln), line);
1149				break;
1150			  case Includes:
1151				Suff_AddInclude(line);
1152				break;
1153			  case Libs:
1154				Suff_AddLib(line);
1155				break;
1156			  case Null:
1157				Suff_SetNull(line);
1158				break;
1159			  default:
1160				break;
1161			}
1162			*cp = savech;
1163			if (savech != '\0') {
1164				cp++;
1165			}
1166			while (*cp && isspace((unsigned char)*cp)) {
1167				cp++;
1168			}
1169			line = cp;
1170		}
1171		Lst_Destroy(&paths, NOFREE);
1172
1173	} else if (specType == ExportVar) {
1174		Var_SetEnv(line, VAR_GLOBAL);
1175
1176	} else {
1177		/* list of sources in order */
1178		Lst curSrcs = Lst_Initializer(curSrc);
1179
1180		while (*line) {
1181			/*
1182			 * The targets take real sources, so we must beware of
1183			 * archive specifications (i.e. things with left
1184			 * parentheses in them) and handle them accordingly.
1185			 */
1186			while (*cp && !isspace((unsigned char)*cp)) {
1187				if (*cp == '(' && cp > line && cp[-1] != '$') {
1188					/*
1189					 * Only stop for a left parenthesis if
1190					 * it isn't at the start of a word
1191					 * (that'll be for variable changes
1192					 * later) and isn't preceded by a dollar
1193					 * sign (a dynamic source).
1194					 */
1195					break;
1196				} else {
1197					cp++;
1198				}
1199			}
1200
1201			if (*cp == '(') {
1202				GNode	  *gnp;
1203
1204				/* list of archive source names after exp. */
1205				Lst sources = Lst_Initializer(sources);
1206
1207				if (Arch_ParseArchive(&line, &sources,
1208				    VAR_CMD) != SUCCESS) {
1209					Parse_Error(PARSE_FATAL, "Error in "
1210					    "source archive spec \"%s\"", line);
1211					return;
1212				}
1213
1214				while (!Lst_IsEmpty(&sources)) {
1215					gnp = Lst_DeQueue(&sources);
1216					ParseDoSrc(tOp, gnp->name, &curSrcs);
1217				}
1218				cp = line;
1219			} else {
1220				if (*cp) {
1221					*cp = '\0';
1222					cp += 1;
1223				}
1224
1225				ParseDoSrc(tOp, line, &curSrcs);
1226			}
1227			while (*cp && isspace((unsigned char)*cp)) {
1228				cp++;
1229			}
1230			line = cp;
1231		}
1232		Lst_Destroy(&curSrcs, NOFREE);
1233	}
1234
1235	if (mainNode == NULL) {
1236		/*
1237		 * If we have yet to decide on a main target to make, in the
1238		 * absence of any user input, we want the first target on
1239		 * the first dependency line that is actually a real target
1240		 * (i.e. isn't a .USE or .EXEC rule) to be made.
1241		 */
1242		LST_FOREACH(ln, &targets) {
1243			gn = Lst_Datum(ln);
1244			if ((gn->type & (OP_NOTMAIN | OP_USE |
1245			    OP_EXEC | OP_TRANSFORM)) == 0) {
1246				mainNode = gn;
1247				Targ_SetMain(gn);
1248				break;
1249			}
1250		}
1251	}
1252}
1253
1254/*-
1255 *---------------------------------------------------------------------
1256 * Parse_IsVar  --
1257 *	Return TRUE if the passed line is a variable assignment. A variable
1258 *	assignment consists of a single word followed by optional whitespace
1259 *	followed by either a += or an = operator.
1260 *	This function is used both by the Parse_File function and main when
1261 *	parsing the command-line arguments.
1262 *
1263 * Results:
1264 *	TRUE if it is. FALSE if it ain't
1265 *
1266 * Side Effects:
1267 *	none
1268 *---------------------------------------------------------------------
1269 */
1270Boolean
1271Parse_IsVar(char *line)
1272{
1273	Boolean wasSpace = FALSE;	/* set TRUE if found a space */
1274	Boolean haveName = FALSE;	/* Set TRUE if have a variable name */
1275
1276	int level = 0;
1277#define	ISEQOPERATOR(c) \
1278	((c) == '+' || (c) == ':' || (c) == '?' || (c) == '!')
1279
1280	/*
1281	 * Skip to variable name
1282	 */
1283	for (; *line == ' ' || *line == '\t'; line++)
1284		continue;
1285
1286	for (; *line != '=' || level != 0; line++) {
1287		switch (*line) {
1288		  case '\0':
1289			/*
1290			 * end-of-line -- can't be a variable assignment.
1291			 */
1292			return (FALSE);
1293
1294		  case ' ':
1295		  case '\t':
1296			/*
1297			 * there can be as much white space as desired so long
1298			 * as there is only one word before the operator
1299			*/
1300			wasSpace = TRUE;
1301			break;
1302
1303		  case '(':
1304		  case '{':
1305			level++;
1306			break;
1307
1308		  case '}':
1309		  case ')':
1310			level--;
1311			break;
1312
1313		  default:
1314			if (wasSpace && haveName) {
1315				if (ISEQOPERATOR(*line)) {
1316					/*
1317					 * We must have a finished word
1318					 */
1319					if (level != 0)
1320						return (FALSE);
1321
1322					/*
1323					 * When an = operator [+?!:] is found,
1324					 * the next character must be an = or
1325					 * it ain't a valid assignment.
1326					 */
1327					if (line[1] == '=')
1328						return (haveName);
1329#ifdef SUNSHCMD
1330					/*
1331					 * This is a shell command
1332					 */
1333					if (strncmp(line, ":sh", 3) == 0)
1334						return (haveName);
1335#endif
1336				}
1337				/*
1338				 * This is the start of another word, so not
1339				 * assignment.
1340				 */
1341				return (FALSE);
1342
1343			} else {
1344				haveName = TRUE;
1345				wasSpace = FALSE;
1346			}
1347			break;
1348		}
1349	}
1350
1351	return (haveName);
1352}
1353
1354/*-
1355 *---------------------------------------------------------------------
1356 * Parse_DoVar  --
1357 *	Take the variable assignment in the passed line and do it in the
1358 *	global context.
1359 *
1360 *	Note: There is a lexical ambiguity with assignment modifier characters
1361 *	in variable names. This routine interprets the character before the =
1362 *	as a modifier. Therefore, an assignment like
1363 *	    C++=/usr/bin/CC
1364 *	is interpreted as "C+ +=" instead of "C++ =".
1365 *
1366 * Results:
1367 *	none
1368 *
1369 * Side Effects:
1370 *	the variable structure of the given variable name is altered in the
1371 *	global context.
1372 *---------------------------------------------------------------------
1373 */
1374void
1375Parse_DoVar(char *line, GNode *ctxt)
1376{
1377	char	*cp;	/* pointer into line */
1378	enum {
1379		VAR_SUBST,
1380		VAR_APPEND,
1381		VAR_SHELL,
1382		VAR_NORMAL
1383	}	type;	/* Type of assignment */
1384	char	*opc;	/* ptr to operator character to
1385			 * null-terminate the variable name */
1386
1387	/*
1388	 * Skip to variable name
1389	 */
1390	while (*line == ' ' || *line == '\t') {
1391		line++;
1392	}
1393
1394	/*
1395	 * Skip to operator character, nulling out whitespace as we go
1396	 */
1397	for (cp = line + 1; *cp != '='; cp++) {
1398		if (isspace((unsigned char)*cp)) {
1399			*cp = '\0';
1400		}
1401	}
1402	opc = cp - 1;		/* operator is the previous character */
1403	*cp++ = '\0';		/* nuke the = */
1404
1405	/*
1406	 * Check operator type
1407	 */
1408	switch (*opc) {
1409	  case '+':
1410		type = VAR_APPEND;
1411		*opc = '\0';
1412		break;
1413
1414	  case '?':
1415		/*
1416		 * If the variable already has a value, we don't do anything.
1417		 */
1418		*opc = '\0';
1419		if (Var_Exists(line, ctxt)) {
1420			return;
1421		} else {
1422			type = VAR_NORMAL;
1423		}
1424		break;
1425
1426	  case ':':
1427		type = VAR_SUBST;
1428		*opc = '\0';
1429		break;
1430
1431	  case '!':
1432		type = VAR_SHELL;
1433		*opc = '\0';
1434		break;
1435
1436	  default:
1437#ifdef SUNSHCMD
1438		while (*opc != ':') {
1439			if (opc == line)
1440				break;
1441			else
1442				--opc;
1443		}
1444
1445		if (strncmp(opc, ":sh", 3) == 0) {
1446			type = VAR_SHELL;
1447			*opc = '\0';
1448			break;
1449		}
1450#endif
1451		type = VAR_NORMAL;
1452		break;
1453	}
1454
1455	while (isspace((unsigned char)*cp)) {
1456		cp++;
1457	}
1458
1459	if (type == VAR_APPEND) {
1460		Var_Append(line, cp, ctxt);
1461
1462	} else if (type == VAR_SUBST) {
1463		/*
1464		 * Allow variables in the old value to be undefined, but leave
1465		 * their invocation alone -- this is done by forcing oldVars
1466		 * to be false.
1467		 * XXX: This can cause recursive variables, but that's not
1468		 * hard to do, and this allows someone to do something like
1469		 *
1470		 *  CFLAGS = $(.INCLUDES)
1471		 *  CFLAGS := -I.. $(CFLAGS)
1472		 *
1473		 * And not get an error.
1474		 */
1475		Boolean oldOldVars = oldVars;
1476
1477		oldVars = FALSE;
1478
1479		/*
1480		 * make sure that we set the variable the first time to nothing
1481		 * so that it gets substituted!
1482		 */
1483		if (!Var_Exists(line, ctxt))
1484			Var_Set(line, "", ctxt);
1485
1486		cp = Buf_Peel(Var_Subst(cp, ctxt, FALSE));
1487
1488		oldVars = oldOldVars;
1489
1490		Var_Set(line, cp, ctxt);
1491		free(cp);
1492
1493	} else if (type == VAR_SHELL) {
1494		/*
1495		 * TRUE if the command needs to be freed, i.e.
1496		 * if any variable expansion was performed
1497		 */
1498		Boolean	freeCmd = FALSE;
1499		Buffer *buf;
1500		const char *error;
1501
1502		if (strchr(cp, '$') != NULL) {
1503			/*
1504			 * There's a dollar sign in the command, so perform
1505			 * variable expansion on the whole thing. The
1506			 * resulting string will need freeing when we're done,
1507			 * so set freeCmd to TRUE.
1508			 */
1509			cp = Buf_Peel(Var_Subst(cp, VAR_CMD, TRUE));
1510			freeCmd = TRUE;
1511		}
1512
1513		buf = Cmd_Exec(cp, &error);
1514		Var_Set(line, Buf_Data(buf), ctxt);
1515		Buf_Destroy(buf, TRUE);
1516
1517		if (error)
1518			Parse_Error(PARSE_WARNING, error, cp);
1519
1520		if (freeCmd)
1521			free(cp);
1522
1523	} else {
1524		/*
1525		 * Normal assignment -- just do it.
1526		 */
1527		Var_Set(line, cp, ctxt);
1528	}
1529}
1530
1531/*-
1532 *-----------------------------------------------------------------------
1533 * ParseHasCommands --
1534 *	Callback procedure for Parse_File when destroying the list of
1535 *	targets on the last dependency line. Marks a target as already
1536 *	having commands if it does, to keep from having shell commands
1537 *	on multiple dependency lines.
1538 *
1539 * Results:
1540 *	None
1541 *
1542 * Side Effects:
1543 *	OP_HAS_COMMANDS may be set for the target.
1544 *
1545 *-----------------------------------------------------------------------
1546 */
1547static void
1548ParseHasCommands(void *gnp)
1549{
1550	GNode *gn = gnp;
1551
1552	if (!Lst_IsEmpty(&gn->commands)) {
1553		gn->type |= OP_HAS_COMMANDS;
1554	}
1555}
1556
1557/*-
1558 *-----------------------------------------------------------------------
1559 * Parse_AddIncludeDir --
1560 *	Add a directory to the path searched for included makefiles
1561 *	bracketed by double-quotes. Used by functions in main.c
1562 *
1563 * Results:
1564 *	None.
1565 *
1566 * Side Effects:
1567 *	The directory is appended to the list.
1568 *
1569 *-----------------------------------------------------------------------
1570 */
1571void
1572Parse_AddIncludeDir(char *dir)
1573{
1574
1575	Path_AddDir(&parseIncPath, dir);
1576}
1577
1578/*-
1579 *---------------------------------------------------------------------
1580 * Parse_FromString  --
1581 *	Start Parsing from the given string
1582 *
1583 * Results:
1584 *	None
1585 *
1586 * Side Effects:
1587 *	A structure is added to the includes Lst and readProc, curFile.lineno,
1588 *	curFile.fname and curFile.F are altered for the new file
1589 *---------------------------------------------------------------------
1590 */
1591void
1592Parse_FromString(char *str, int lineno)
1593{
1594
1595	DEBUGF(FOR, ("%s\n---- at line %d\n", str, lineno));
1596
1597	ParsePushInput(estrdup(CURFILE->fname), NULL, str, lineno);
1598}
1599
1600#ifdef SYSVINCLUDE
1601/*-
1602 *---------------------------------------------------------------------
1603 * ParseTraditionalInclude  --
1604 *	Push to another file.
1605 *
1606 *	The input is the line minus the "include".  The file name is
1607 *	the string following the "include".
1608 *
1609 * Results:
1610 *	None
1611 *
1612 * Side Effects:
1613 *	A structure is added to the includes Lst and readProc, curFile.lineno,
1614 *	curFile.fname and curFile.F are altered for the new file
1615 *---------------------------------------------------------------------
1616 */
1617static void
1618ParseTraditionalInclude(char *file)
1619{
1620	char	*fullname;	/* full pathname of file */
1621	char	*cp;		/* current position in file spec */
1622
1623	/*
1624	 * Skip over whitespace
1625	 */
1626	while (*file == ' ' || *file == '\t') {
1627		file++;
1628	}
1629
1630	if (*file == '\0') {
1631		Parse_Error(PARSE_FATAL, "Filename missing from \"include\"");
1632		return;
1633	}
1634
1635	/*
1636	* Skip to end of line or next whitespace
1637	*/
1638	for (cp = file; *cp && *cp != '\n' && *cp != '\t' && *cp != ' '; cp++) {
1639		continue;
1640	}
1641
1642	*cp = '\0';
1643
1644	/*
1645	 * Substitute for any variables in the file name before trying to
1646	 * find the thing.
1647	 */
1648	file = Buf_Peel(Var_Subst(file, VAR_CMD, FALSE));
1649
1650	/*
1651	 * Now we know the file's name, we attempt to find the durn thing.
1652	 * Search for it first on the -I search path, then on the .PATH
1653	 * search path, if not found in a -I directory.
1654	 */
1655	fullname = Path_FindFile(file, &parseIncPath);
1656	if (fullname == NULL) {
1657		fullname = Path_FindFile(file, &dirSearchPath);
1658	}
1659
1660	if (fullname == NULL) {
1661		/*
1662		 * Still haven't found the makefile. Look for it on the system
1663		 * path as a last resort.
1664		 */
1665		fullname = Path_FindFile(file, &sysIncPath);
1666	}
1667
1668	if (fullname == NULL) {
1669		Parse_Error(PARSE_FATAL, "Could not find %s", file);
1670		/* XXXHB free(file) */
1671		return;
1672	}
1673
1674	/* XXXHB free(file) */
1675
1676	/*
1677	 * We set up the name of the file to be the absolute
1678	 * name of the include file so error messages refer to the right
1679	 * place.
1680	 */
1681	ParsePushInput(fullname, NULL, NULL, 0);
1682}
1683#endif
1684
1685/*-
1686 *---------------------------------------------------------------------
1687 * ParseReadc  --
1688 *	Read a character from the current file
1689 *
1690 * Results:
1691 *	The character that was read
1692 *
1693 * Side Effects:
1694 *---------------------------------------------------------------------
1695 */
1696static int
1697ParseReadc(void)
1698{
1699
1700	if (CURFILE->F != NULL)
1701		return (fgetc(CURFILE->F));
1702
1703	if (CURFILE->str != NULL && *CURFILE->ptr != '\0')
1704		return (*CURFILE->ptr++);
1705
1706	return (EOF);
1707}
1708
1709
1710/*-
1711 *---------------------------------------------------------------------
1712 * ParseUnreadc  --
1713 *	Put back a character to the current file
1714 *
1715 * Results:
1716 *	None.
1717 *
1718 * Side Effects:
1719 *---------------------------------------------------------------------
1720 */
1721static void
1722ParseUnreadc(int c)
1723{
1724
1725	if (CURFILE->F != NULL) {
1726		ungetc(c, CURFILE->F);
1727		return;
1728	}
1729	if (CURFILE->str != NULL) {
1730		*--(CURFILE->ptr) = c;
1731		return;
1732	}
1733}
1734
1735/* ParseSkipLine():
1736 *	Grab the next line unless it begins with a dot (`.') and we're told to
1737 *	ignore such lines.
1738 */
1739static char *
1740ParseSkipLine(int skip, int keep_newline)
1741{
1742	char *line;
1743	int c, lastc;
1744	Buffer *buf;
1745
1746	buf = Buf_Init(MAKE_BSIZE);
1747
1748	do {
1749		Buf_Clear(buf);
1750		lastc = '\0';
1751
1752		while (((c = ParseReadc()) != '\n' || lastc == '\\')
1753		    && c != EOF) {
1754			if (skip && c == '#' && lastc != '\\') {
1755				/*
1756				 * let a comment be terminated even by an
1757				 * escaped \n. This is consistent to comment
1758				 * handling in ParseReadLine
1759				 */
1760				while ((c = ParseReadc()) != '\n' && c != EOF)
1761					;
1762				break;
1763			}
1764			if (c == '\n') {
1765				if (keep_newline)
1766					Buf_AddByte(buf, (Byte)c);
1767				else
1768					Buf_ReplaceLastByte(buf, (Byte)' ');
1769				CURFILE->lineno++;
1770
1771				while ((c = ParseReadc()) == ' ' || c == '\t')
1772					continue;
1773
1774				if (c == EOF)
1775					break;
1776			}
1777
1778			Buf_AddByte(buf, (Byte)c);
1779			lastc = c;
1780		}
1781
1782		if (c == EOF) {
1783			Parse_Error(PARSE_FATAL,
1784			    "Unclosed conditional/for loop");
1785			Buf_Destroy(buf, TRUE);
1786			return (NULL);
1787		}
1788
1789		CURFILE->lineno++;
1790		Buf_AddByte(buf, (Byte)'\0');
1791		line = Buf_Data(buf);
1792	} while (skip == 1 && line[0] != '.');
1793
1794	Buf_Destroy(buf, FALSE);
1795	return (line);
1796}
1797
1798/*-
1799 *---------------------------------------------------------------------
1800 * ParseReadLine --
1801 *	Read an entire line from the input file. Called only by Parse_File.
1802 *	To facilitate escaped newlines and what have you, a character is
1803 *	buffered in 'lastc', which is '\0' when no characters have been
1804 *	read. When we break out of the loop, c holds the terminating
1805 *	character and lastc holds a character that should be added to
1806 *	the line (unless we don't read anything but a terminator).
1807 *
1808 * Results:
1809 *	A line w/o its newline
1810 *
1811 * Side Effects:
1812 *	Only those associated with reading a character
1813 *---------------------------------------------------------------------
1814 */
1815static char *
1816ParseReadLine(void)
1817{
1818	Buffer	*buf;		/* Buffer for current line */
1819	int	c;		/* the current character */
1820	int	lastc;		/* The most-recent character */
1821	Boolean	semiNL;		/* treat semi-colons as newlines */
1822	Boolean	ignDepOp;	/* TRUE if should ignore dependency operators
1823				 * for the purposes of setting semiNL */
1824	Boolean	ignComment;	/* TRUE if should ignore comments (in a
1825				 * shell command */
1826	char	*line;		/* Result */
1827	char	*ep;		/* to strip trailing blanks */
1828
1829  again:
1830	semiNL = FALSE;
1831	ignDepOp = FALSE;
1832	ignComment = FALSE;
1833
1834	lastc = '\0';
1835
1836	/*
1837	 * Handle tab at the beginning of the line. A leading tab (shell
1838	 * command) forces us to ignore comments and dependency operators and
1839	 * treat semi-colons as semi-colons (by leaving semiNL FALSE).
1840	 * This also discards completely blank lines.
1841	 */
1842	for (;;) {
1843		c = ParseReadc();
1844		if (c == EOF) {
1845			if (ParsePopInput() == DONE) {
1846				/* End of all inputs - return NULL */
1847				return (NULL);
1848			}
1849			continue;
1850		}
1851
1852		if (c == '\t') {
1853			ignComment = ignDepOp = TRUE;
1854			lastc = c;
1855			break;
1856		}
1857		if (c != '\n') {
1858			ParseUnreadc(c);
1859			break;
1860		}
1861		CURFILE->lineno++;
1862	}
1863
1864	buf = Buf_Init(MAKE_BSIZE);
1865
1866	while (((c = ParseReadc()) != '\n' || lastc == '\\') && c != EOF) {
1867  test_char:
1868		switch (c) {
1869		  case '\n':
1870			/*
1871			 * Escaped newline: read characters until a
1872			 * non-space or an unescaped newline and
1873			 * replace them all by a single space. This is
1874			 * done by storing the space over the backslash
1875			 * and dropping through with the next nonspace.
1876			 * If it is a semi-colon and semiNL is TRUE,
1877			 * it will be recognized as a newline in the
1878			 * code below this...
1879			 */
1880			CURFILE->lineno++;
1881			lastc = ' ';
1882			while ((c = ParseReadc()) == ' ' || c == '\t') {
1883				continue;
1884			}
1885			if (c == EOF || c == '\n') {
1886				goto line_read;
1887			} else {
1888				/*
1889				 * Check for comments, semiNL's, etc. --
1890				 * easier than ParseUnreadc(c);
1891				 * continue;
1892				 */
1893				goto test_char;
1894			}
1895			/*NOTREACHED*/
1896			break;
1897
1898		  case ';':
1899			/*
1900			 * Semi-colon: Need to see if it should be
1901			 * interpreted as a newline
1902			 */
1903			if (semiNL) {
1904				/*
1905				 * To make sure the command that may
1906				 * be following this semi-colon begins
1907				 * with a tab, we push one back into the
1908				 * input stream. This will overwrite the
1909				 * semi-colon in the buffer. If there is
1910				 * no command following, this does no
1911				 * harm, since the newline remains in
1912				 * the buffer and the
1913				 * whole line is ignored.
1914				 */
1915				ParseUnreadc('\t');
1916				goto line_read;
1917			}
1918			break;
1919		  case '=':
1920			if (!semiNL) {
1921				/*
1922				 * Haven't seen a dependency operator
1923				 * before this, so this must be a
1924				 * variable assignment -- don't pay
1925				 * attention to dependency operators
1926				 * after this.
1927				 */
1928				ignDepOp = TRUE;
1929			} else if (lastc == ':' || lastc == '!') {
1930				/*
1931				 * Well, we've seen a dependency
1932				 * operator already, but it was the
1933				 * previous character, so this is really
1934				 * just an expanded variable assignment.
1935				 * Revert semi-colons to being just
1936				 * semi-colons again and ignore any more
1937				 * dependency operators.
1938				 *
1939				 * XXX: Note that a line like
1940				 * "foo : a:=b" will blow up, but who'd
1941				 * write a line like that anyway?
1942				 */
1943				ignDepOp = TRUE;
1944				semiNL = FALSE;
1945			}
1946			break;
1947		  case '#':
1948			if (!ignComment) {
1949				if (lastc != '\\') {
1950					/*
1951					 * If the character is a hash
1952					 * mark and it isn't escaped
1953					 * (or we're being compatible),
1954					 * the thing is a comment.
1955					 * Skip to the end of the line.
1956					 */
1957					do {
1958						c = ParseReadc();
1959					} while (c != '\n' && c != EOF);
1960					goto line_read;
1961				} else {
1962					/*
1963					 * Don't add the backslash.
1964					 * Just let the # get copied
1965					 * over.
1966					 */
1967					lastc = c;
1968					continue;
1969				}
1970			}
1971			break;
1972
1973		  case ':':
1974		  case '!':
1975			if (!ignDepOp) {
1976				/*
1977				 * A semi-colon is recognized as a
1978				 * newline only on dependency lines.
1979				 * Dependency lines are lines with a
1980				 * colon or an exclamation point.
1981				 * Ergo...
1982				 */
1983				semiNL = TRUE;
1984			}
1985			break;
1986
1987		  default:
1988			break;
1989		}
1990		/*
1991		 * Copy in the previous character (there may be none if this
1992		 * was the first character) and save this one in
1993		 * lastc.
1994		 */
1995		if (lastc != '\0')
1996			Buf_AddByte(buf, (Byte)lastc);
1997		lastc = c;
1998	}
1999  line_read:
2000	CURFILE->lineno++;
2001
2002	if (lastc != '\0') {
2003		Buf_AddByte(buf, (Byte)lastc);
2004	}
2005	Buf_AddByte(buf, (Byte)'\0');
2006	line = Buf_Peel(buf);
2007
2008	/*
2009	 * Strip trailing blanks and tabs from the line.
2010	 * Do not strip a blank or tab that is preceded by
2011	 * a '\'
2012	 */
2013	ep = line;
2014	while (*ep)
2015		++ep;
2016	while (ep > line + 1 && (ep[-1] == ' ' || ep[-1] == '\t')) {
2017		if (ep > line + 1 && ep[-2] == '\\')
2018			break;
2019		--ep;
2020	}
2021	*ep = 0;
2022
2023	if (line[0] == '\0') {
2024		/* empty line - just ignore */
2025		free(line);
2026		goto again;
2027	}
2028
2029	return (line);
2030}
2031
2032/*-
2033 *-----------------------------------------------------------------------
2034 * ParseFinishLine --
2035 *	Handle the end of a dependency group.
2036 *
2037 * Results:
2038 *	Nothing.
2039 *
2040 * Side Effects:
2041 *	inLine set FALSE. 'targets' list destroyed.
2042 *
2043 *-----------------------------------------------------------------------
2044 */
2045static void
2046ParseFinishLine(void)
2047{
2048	const LstNode	*ln;
2049
2050	if (inLine) {
2051		LST_FOREACH(ln, &targets) {
2052			if (((const GNode *)Lst_Datum(ln))->type & OP_TRANSFORM)
2053				Suff_EndTransform(Lst_Datum(ln));
2054		}
2055		Lst_Destroy(&targets, ParseHasCommands);
2056		inLine = FALSE;
2057	}
2058}
2059
2060/**
2061 * parse_include
2062 *	Parse an .include directive and push the file onto the input stack.
2063 *	The input is the line minus the .include. A file spec is a string
2064 *	enclosed in <> or "". The former is looked for only in sysIncPath.
2065 *	The latter in . and the directories specified by -I command line
2066 *	options
2067 */
2068static void
2069parse_include(char *file, int code __unused, int lineno __unused)
2070{
2071	char	*fullname;	/* full pathname of file */
2072	char	endc;		/* the character which ends the file spec */
2073	char	*cp;		/* current position in file spec */
2074	Boolean	isSystem;	/* TRUE if makefile is a system makefile */
2075	char	*prefEnd, *Fname;
2076	char	*newName;
2077
2078	/*
2079	 * Skip to delimiter character so we know where to look
2080	 */
2081	while (*file == ' ' || *file == '\t') {
2082		file++;
2083	}
2084
2085	if (*file != '"' && *file != '<') {
2086		Parse_Error(PARSE_FATAL,
2087		    ".include filename must be delimited by '\"' or '<'");
2088		return;
2089	}
2090
2091	/*
2092	 * Set the search path on which to find the include file based on the
2093	 * characters which bracket its name. Angle-brackets imply it's
2094	 * a system Makefile while double-quotes imply it's a user makefile
2095	 */
2096	if (*file == '<') {
2097		isSystem = TRUE;
2098		endc = '>';
2099	} else {
2100		isSystem = FALSE;
2101		endc = '"';
2102	}
2103
2104	/*
2105	* Skip to matching delimiter
2106	*/
2107	for (cp = ++file; *cp != endc; cp++) {
2108		if (*cp == '\0') {
2109			Parse_Error(PARSE_FATAL,
2110			    "Unclosed .include filename. '%c' expected", endc);
2111			return;
2112		}
2113	}
2114	*cp = '\0';
2115
2116	/*
2117	 * Substitute for any variables in the file name before trying to
2118	 * find the thing.
2119	 */
2120	file = Buf_Peel(Var_Subst(file, VAR_CMD, FALSE));
2121
2122	/*
2123	 * Now we know the file's name and its search path, we attempt to
2124	 * find the durn thing. A return of NULL indicates the file don't
2125	 * exist.
2126	 */
2127	if (!isSystem) {
2128		/*
2129		 * Include files contained in double-quotes are first searched
2130		 * for relative to the including file's location. We don't want
2131		 * to cd there, of course, so we just tack on the old file's
2132		 * leading path components and call Dir_FindFile to see if
2133		 * we can locate the beast.
2134		 */
2135
2136		/* Make a temporary copy of this, to be safe. */
2137		Fname = estrdup(CURFILE->fname);
2138
2139		prefEnd = strrchr(Fname, '/');
2140		if (prefEnd != NULL) {
2141			*prefEnd = '\0';
2142			if (file[0] == '/')
2143				newName = estrdup(file);
2144			else
2145				newName = str_concat(Fname, file, STR_ADDSLASH);
2146			fullname = Path_FindFile(newName, &parseIncPath);
2147			if (fullname == NULL) {
2148				fullname = Path_FindFile(newName,
2149				    &dirSearchPath);
2150			}
2151			free(newName);
2152			*prefEnd = '/';
2153		} else {
2154			fullname = NULL;
2155		}
2156		free(Fname);
2157	} else {
2158		fullname = NULL;
2159	}
2160
2161	if (fullname == NULL) {
2162		/*
2163		 * System makefile or makefile wasn't found in same directory as
2164		 * included makefile. Search for it first on the -I search path,
2165		 * then on the .PATH search path, if not found in a -I
2166		 * directory.
2167		 * XXX: Suffix specific?
2168		 */
2169		fullname = Path_FindFile(file, &parseIncPath);
2170		if (fullname == NULL) {
2171			fullname = Path_FindFile(file, &dirSearchPath);
2172		}
2173	}
2174
2175	if (fullname == NULL) {
2176		/*
2177		 * Still haven't found the makefile. Look for it on the system
2178		 * path as a last resort.
2179		 */
2180		fullname = Path_FindFile(file, &sysIncPath);
2181	}
2182
2183	if (fullname == NULL) {
2184		*cp = endc;
2185		Parse_Error(PARSE_FATAL, "Could not find %s", file);
2186		free(file);
2187		return;
2188	}
2189	free(file);
2190
2191	/*
2192	 * We set up the name of the file to be the absolute
2193	 * name of the include file so error messages refer to the right
2194	 * place.
2195	 */
2196	ParsePushInput(fullname, NULL, NULL, 0);
2197}
2198
2199/**
2200 * parse_message
2201 *	Parse a .warning or .error directive
2202 *
2203 *	The input is the line minus the ".error"/".warning".  We substitute
2204 *	variables, print the message and exit(1) (for .error) or just print
2205 *	a warning if the directive is malformed.
2206 */
2207static void
2208parse_message(char *line, int iserror, int lineno __unused)
2209{
2210
2211	if (!isspace((u_char)*line)) {
2212		Parse_Error(PARSE_WARNING, "invalid syntax: .%s%s",
2213		    iserror ? "error" : "warning", line);
2214		return;
2215	}
2216
2217	while (isspace((u_char)*line))
2218		line++;
2219
2220	line = Buf_Peel(Var_Subst(line, VAR_GLOBAL, FALSE));
2221	Parse_Error(iserror ? PARSE_FATAL : PARSE_WARNING, "%s", line);
2222	free(line);
2223
2224	if (iserror) {
2225		/* Terminate immediately. */
2226		exit(1);
2227	}
2228}
2229
2230/**
2231 * parse_undef
2232 *	Parse an .undef directive.
2233 */
2234static void
2235parse_undef(char *line, int code __unused, int lineno __unused)
2236{
2237	char *cp;
2238
2239	while (isspace((u_char)*line))
2240		line++;
2241
2242	for (cp = line; !isspace((u_char)*cp) && *cp != '\0'; cp++) {
2243		;
2244	}
2245	*cp = '\0';
2246
2247	cp = Buf_Peel(Var_Subst(line, VAR_CMD, FALSE));
2248	Var_Delete(cp, VAR_GLOBAL);
2249	free(cp);
2250}
2251
2252/**
2253 * parse_for
2254 *	Parse a .for directive.
2255 */
2256static void
2257parse_for(char *line, int code __unused, int lineno)
2258{
2259
2260	if (!For_For(line)) {
2261		/* syntax error */
2262		return;
2263	}
2264	line = NULL;
2265
2266	/*
2267	 * Skip after the matching endfor.
2268	 */
2269	do {
2270		free(line);
2271		line = ParseSkipLine(0, 1);
2272		if (line == NULL) {
2273			Parse_Error(PARSE_FATAL,
2274			    "Unexpected end of file in for loop.\n");
2275			return;
2276		}
2277	} while (For_Eval(line));
2278	free(line);
2279
2280	/* execute */
2281	For_Run(lineno);
2282}
2283
2284/**
2285 * parse_endfor
2286 *	Parse endfor. This may only happen if there was no matching .for.
2287 */
2288static void
2289parse_endfor(char *line __unused, int code __unused, int lineno __unused)
2290{
2291
2292	Parse_Error(PARSE_FATAL, "for-less endfor");
2293}
2294
2295/**
2296 * parse_directive
2297 *	Got a line starting with a '.'. Check if this is a directive
2298 *	and parse it.
2299 *
2300 * return:
2301 *	TRUE if line was a directive, FALSE otherwise.
2302 */
2303static Boolean
2304parse_directive(char *line)
2305{
2306	char	*start;
2307	char	*cp;
2308	int	dir;
2309
2310	/*
2311	 * Get the keyword:
2312	 *	.[[:space:]]*\([[:alpha:]][[:alnum:]_]*\).*
2313	 * \1 is the keyword.
2314	 */
2315	for (start = line; isspace((u_char)*start); start++) {
2316		;
2317	}
2318
2319	if (!isalpha((u_char)*start)) {
2320		return (FALSE);
2321	}
2322
2323	cp = start + 1;
2324	while (isalnum((u_char)*cp) || *cp == '_') {
2325		cp++;
2326	}
2327
2328	dir = directive_hash(start, cp - start);
2329	if (dir < 0 || dir >= (int)NDIRECTS ||
2330	    (size_t)(cp - start) != strlen(directives[dir].name) ||
2331	    strncmp(start, directives[dir].name, cp - start) != 0) {
2332		/* not actually matched */
2333		return (FALSE);
2334	}
2335
2336	if (!skipLine || directives[dir].skip_flag)
2337		(*directives[dir].func)(cp, directives[dir].code,
2338		    CURFILE->lineno);
2339	return (TRUE);
2340}
2341
2342/*-
2343 *---------------------------------------------------------------------
2344 * Parse_File --
2345 *	Parse a file into its component parts, incorporating it into the
2346 *	current dependency graph. This is the main function and controls
2347 *	almost every other function in this module
2348 *
2349 * Results:
2350 *	None
2351 *
2352 * Side Effects:
2353 *	Loads. Nodes are added to the list of all targets, nodes and links
2354 *	are added to the dependency graph. etc. etc. etc.
2355 *---------------------------------------------------------------------
2356 */
2357void
2358Parse_File(const char *name, FILE *stream)
2359{
2360	char	*cp;	/* pointer into the line */
2361	char	*line;	/* the line we're working on */
2362
2363	inLine = FALSE;
2364	fatals = 0;
2365
2366	ParsePushInput(estrdup(name), stream, NULL, 0);
2367
2368	while ((line = ParseReadLine()) != NULL) {
2369		if (*line == '.' && parse_directive(line + 1)) {
2370			/* directive consumed */
2371			goto nextLine;
2372		}
2373		if (skipLine || *line == '#') {
2374			/* Skipping .if block or comment. */
2375			goto nextLine;
2376		}
2377
2378		if (*line == '\t') {
2379			/*
2380			 * If a line starts with a tab, it can only
2381			 * hope to be a creation command.
2382			 */
2383			for (cp = line + 1; isspace((unsigned char)*cp); cp++) {
2384				continue;
2385			}
2386			if (*cp) {
2387				if (inLine) {
2388					LstNode	*ln;
2389					GNode	*gn;
2390
2391					/*
2392					 * So long as it's not a blank
2393					 * line and we're actually in a
2394					 * dependency spec, add the
2395					 * command to the list of
2396					 * commands of all targets in
2397					 * the dependency spec.
2398					 */
2399					LST_FOREACH(ln, &targets) {
2400						gn = Lst_Datum(ln);
2401
2402						/*
2403						 * if target already
2404						 * supplied, ignore
2405						 * commands
2406						 */
2407						if (!(gn->type & OP_HAS_COMMANDS))
2408							Lst_AtEnd(&gn->commands, cp);
2409						else
2410							Parse_Error(PARSE_WARNING, "duplicate script "
2411							    "for target \"%s\" ignored", gn->name);
2412					}
2413					continue;
2414				} else {
2415					Parse_Error(PARSE_FATAL,
2416					     "Unassociated shell command \"%s\"",
2417					     cp);
2418				}
2419			}
2420#ifdef SYSVINCLUDE
2421		} else if (strncmp(line, "include", 7) == 0 &&
2422		    isspace((unsigned char)line[7]) &&
2423		    strchr(line, ':') == NULL) {
2424			/*
2425			 * It's an S3/S5-style "include".
2426			 */
2427			ParseTraditionalInclude(line + 7);
2428			goto nextLine;
2429#endif
2430		} else if (Parse_IsVar(line)) {
2431			ParseFinishLine();
2432			Parse_DoVar(line, VAR_GLOBAL);
2433
2434		} else {
2435			/*
2436			 * We now know it's a dependency line so it
2437			 * needs to have all variables expanded before
2438			 * being parsed. Tell the variable module to
2439			 * complain if some variable is undefined...
2440			 * To make life easier on novices, if the line
2441			 * is indented we first make sure the line has
2442			 * a dependency operator in it. If it doesn't
2443			 * have an operator and we're in a dependency
2444			 * line's script, we assume it's actually a
2445			 * shell command and add it to the current
2446			 * list of targets. XXX this comment seems wrong.
2447			 */
2448			cp = line;
2449			if (isspace((unsigned char)line[0])) {
2450				while (*cp != '\0' &&
2451				    isspace((unsigned char)*cp)) {
2452					cp++;
2453				}
2454				if (*cp == '\0') {
2455					goto nextLine;
2456				}
2457			}
2458
2459			ParseFinishLine();
2460
2461			cp = Buf_Peel(Var_Subst(line, VAR_CMD, TRUE));
2462
2463			free(line);
2464			line = cp;
2465
2466			/*
2467			 * Need a non-circular list for the target nodes
2468			 */
2469			Lst_Destroy(&targets, NOFREE);
2470			inLine = TRUE;
2471
2472			ParseDoDependency(line);
2473		}
2474
2475  nextLine:
2476		free(line);
2477	}
2478
2479	ParseFinishLine();
2480
2481	/*
2482	 * Make sure conditionals are clean
2483	 */
2484	Cond_End();
2485
2486	if (fatals)
2487		errx(1, "fatal errors encountered -- cannot continue");
2488}
2489
2490/*-
2491 *-----------------------------------------------------------------------
2492 * Parse_MainName --
2493 *	Return a Lst of the main target to create for main()'s sake. If
2494 *	no such target exists, we Punt with an obnoxious error message.
2495 *
2496 * Results:
2497 *	A Lst of the single node to create.
2498 *
2499 * Side Effects:
2500 *	None.
2501 *
2502 *-----------------------------------------------------------------------
2503 */
2504void
2505Parse_MainName(Lst *listmain)
2506{
2507
2508	if (mainNode == NULL) {
2509		Punt("no target to make.");
2510		/*NOTREACHED*/
2511	} else if (mainNode->type & OP_DOUBLEDEP) {
2512		Lst_AtEnd(listmain, mainNode);
2513		Lst_Concat(listmain, &mainNode->cohorts, LST_CONCNEW);
2514	} else
2515		Lst_AtEnd(listmain, mainNode);
2516}
2517