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