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