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