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