parse.c revision 237578
1/*	$NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $	*/
2
3/*
4 * Copyright (c) 1988, 1989, 1990, 1993
5 *	The Regents of the University of California.  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. Neither the name of the University nor the names of its contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35/*
36 * Copyright (c) 1989 by Berkeley Softworks
37 * All rights reserved.
38 *
39 * This code is derived from software contributed to Berkeley by
40 * Adam de Boor.
41 *
42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions
44 * are met:
45 * 1. Redistributions of source code must retain the above copyright
46 *    notice, this list of conditions and the following disclaimer.
47 * 2. Redistributions in binary form must reproduce the above copyright
48 *    notice, this list of conditions and the following disclaimer in the
49 *    documentation and/or other materials provided with the distribution.
50 * 3. All advertising materials mentioning features or use of this software
51 *    must display the following acknowledgement:
52 *	This product includes software developed by the University of
53 *	California, Berkeley and its contributors.
54 * 4. Neither the name of the University nor the names of its contributors
55 *    may be used to endorse or promote products derived from this software
56 *    without specific prior written permission.
57 *
58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * SUCH DAMAGE.
69 */
70
71#ifndef MAKE_NATIVE
72static char rcsid[] = "$NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $";
73#else
74#include <sys/cdefs.h>
75#ifndef lint
76#if 0
77static char sccsid[] = "@(#)parse.c	8.3 (Berkeley) 3/19/94";
78#else
79__RCSID("$NetBSD: parse.c,v 1.185 2012/06/12 19:21:51 joerg Exp $");
80#endif
81#endif /* not lint */
82#endif
83
84/*-
85 * parse.c --
86 *	Functions to parse a makefile.
87 *
88 *	One function, Parse_Init, must be called before any functions
89 *	in this module are used. After that, the function Parse_File is the
90 *	main entry point and controls most of the other functions in this
91 *	module.
92 *
93 *	Most important structures are kept in Lsts. Directories for
94 *	the .include "..." function are kept in the 'parseIncPath' Lst, while
95 *	those for the .include <...> are kept in the 'sysIncPath' Lst. The
96 *	targets currently being defined are kept in the 'targets' Lst.
97 *
98 *	The variables 'fname' and 'lineno' are used to track the name
99 *	of the current file and the line number in that file so that error
100 *	messages can be more meaningful.
101 *
102 * Interface:
103 *	Parse_Init	    	    Initialization function which must be
104 *	    	  	    	    called before anything else in this module
105 *	    	  	    	    is used.
106 *
107 *	Parse_End		    Cleanup the module
108 *
109 *	Parse_File	    	    Function used to parse a makefile. It must
110 *	    	  	    	    be given the name of the file, which should
111 *	    	  	    	    already have been opened, and a function
112 *	    	  	    	    to call to read a character from the file.
113 *
114 *	Parse_IsVar	    	    Returns TRUE if the given line is a
115 *	    	  	    	    variable assignment. Used by MainParseArgs
116 *	    	  	    	    to determine if an argument is a target
117 *	    	  	    	    or a variable assignment. Used internally
118 *	    	  	    	    for pretty much the same thing...
119 *
120 *	Parse_Error	    	    Function called when an error occurs in
121 *	    	  	    	    parsing. Used by the variable and
122 *	    	  	    	    conditional modules.
123 *	Parse_MainName	    	    Returns a Lst of the main target to create.
124 */
125
126#include <sys/types.h>
127#include <sys/stat.h>
128#include <assert.h>
129#include <ctype.h>
130#include <errno.h>
131#include <fcntl.h>
132#include <stdarg.h>
133#include <stdio.h>
134
135#include "make.h"
136#include "hash.h"
137#include "dir.h"
138#include "job.h"
139#include "buf.h"
140#include "pathnames.h"
141
142#ifdef HAVE_MMAP
143#include <sys/mman.h>
144
145#ifndef MAP_COPY
146#define MAP_COPY MAP_PRIVATE
147#endif
148#ifndef MAP_FILE
149#define MAP_FILE 0
150#endif
151#endif
152
153////////////////////////////////////////////////////////////
154// types and constants
155
156/*
157 * Structure for a file being read ("included file")
158 */
159typedef struct IFile {
160    const char      *fname;         /* name of file */
161    int             lineno;         /* current line number in file */
162    int             first_lineno;   /* line number of start of text */
163    int             cond_depth;     /* 'if' nesting when file opened */
164    char            *P_str;         /* point to base of string buffer */
165    char            *P_ptr;         /* point to next char of string buffer */
166    char            *P_end;         /* point to the end of string buffer */
167    char            *(*nextbuf)(void *, size_t *); /* Function to get more data */
168    void            *nextbuf_arg;   /* Opaque arg for nextbuf() */
169    struct loadedfile *lf;          /* loadedfile object, if any */
170} IFile;
171
172
173/*
174 * These values are returned by ParseEOF to tell Parse_File whether to
175 * CONTINUE parsing, i.e. it had only reached the end of an include file,
176 * or if it's DONE.
177 */
178#define CONTINUE	1
179#define DONE		0
180
181/*
182 * Tokens for target attributes
183 */
184typedef enum {
185    Begin,  	    /* .BEGIN */
186    Default,	    /* .DEFAULT */
187    End,    	    /* .END */
188    dotError,	    /* .ERROR */
189    Ignore,	    /* .IGNORE */
190    Includes,	    /* .INCLUDES */
191    Interrupt,	    /* .INTERRUPT */
192    Libs,	    /* .LIBS */
193    Meta,	    /* .META */
194    MFlags,	    /* .MFLAGS or .MAKEFLAGS */
195    Main,	    /* .MAIN and we don't have anything user-specified to
196		     * make */
197    NoExport,	    /* .NOEXPORT */
198    NoMeta,	    /* .NOMETA */
199    NoMetaCmp,	    /* .NOMETA_CMP */
200    NoPath,	    /* .NOPATH */
201    Not,	    /* Not special */
202    NotParallel,    /* .NOTPARALLEL */
203    Null,   	    /* .NULL */
204    ExObjdir,	    /* .OBJDIR */
205    Order,  	    /* .ORDER */
206    Parallel,	    /* .PARALLEL */
207    ExPath,	    /* .PATH */
208    Phony,	    /* .PHONY */
209#ifdef POSIX
210    Posix,	    /* .POSIX */
211#endif
212    Precious,	    /* .PRECIOUS */
213    ExShell,	    /* .SHELL */
214    Silent,	    /* .SILENT */
215    SingleShell,    /* .SINGLESHELL */
216    Suffixes,	    /* .SUFFIXES */
217    Wait,	    /* .WAIT */
218    Attribute	    /* Generic attribute */
219} ParseSpecial;
220
221/*
222 * Other tokens
223 */
224#define LPAREN	'('
225#define RPAREN	')'
226
227
228////////////////////////////////////////////////////////////
229// result data
230
231/*
232 * The main target to create. This is the first target on the first
233 * dependency line in the first makefile.
234 */
235static GNode *mainNode;
236
237////////////////////////////////////////////////////////////
238// eval state
239
240/* targets we're working on */
241static Lst targets;
242
243#ifdef CLEANUP
244/* command lines for targets */
245static Lst targCmds;
246#endif
247
248/*
249 * specType contains the SPECial TYPE of the current target. It is
250 * Not if the target is unspecial. If it *is* special, however, the children
251 * are linked as children of the parent but not vice versa. This variable is
252 * set in ParseDoDependency
253 */
254static ParseSpecial specType;
255
256/*
257 * Predecessor node for handling .ORDER. Initialized to NULL when .ORDER
258 * seen, then set to each successive source on the line.
259 */
260static GNode	*predecessor;
261
262////////////////////////////////////////////////////////////
263// parser state
264
265/* true if currently in a dependency line or its commands */
266static Boolean inLine;
267
268/* number of fatal errors */
269static int fatals = 0;
270
271/*
272 * Variables for doing includes
273 */
274
275/* current file being read */
276static IFile *curFile;
277
278/* stack of IFiles generated by .includes */
279static Lst includes;
280
281/* include paths (lists of directories) */
282Lst parseIncPath;	/* dirs for "..." includes */
283Lst sysIncPath;		/* dirs for <...> includes */
284Lst defIncPath;		/* default for sysIncPath */
285
286////////////////////////////////////////////////////////////
287// parser tables
288
289/*
290 * The parseKeywords table is searched using binary search when deciding
291 * if a target or source is special. The 'spec' field is the ParseSpecial
292 * type of the keyword ("Not" if the keyword isn't special as a target) while
293 * the 'op' field is the operator to apply to the list of targets if the
294 * keyword is used as a source ("0" if the keyword isn't special as a source)
295 */
296static const struct {
297    const char   *name;    	/* Name of keyword */
298    ParseSpecial  spec;	    	/* Type when used as a target */
299    int	    	  op;	    	/* Operator when used as a source */
300} parseKeywords[] = {
301{ ".BEGIN", 	  Begin,    	0 },
302{ ".DEFAULT",	  Default,  	0 },
303{ ".END",   	  End,	    	0 },
304{ ".ERROR",   	  dotError,    	0 },
305{ ".EXEC",	  Attribute,   	OP_EXEC },
306{ ".IGNORE",	  Ignore,   	OP_IGNORE },
307{ ".INCLUDES",	  Includes, 	0 },
308{ ".INTERRUPT",	  Interrupt,	0 },
309{ ".INVISIBLE",	  Attribute,   	OP_INVISIBLE },
310{ ".JOIN",  	  Attribute,   	OP_JOIN },
311{ ".LIBS",  	  Libs,	    	0 },
312{ ".MADE",	  Attribute,	OP_MADE },
313{ ".MAIN",	  Main,		0 },
314{ ".MAKE",  	  Attribute,   	OP_MAKE },
315{ ".MAKEFLAGS",	  MFlags,   	0 },
316{ ".META",	  Meta,		OP_META },
317{ ".MFLAGS",	  MFlags,   	0 },
318{ ".NOMETA",	  NoMeta,	OP_NOMETA },
319{ ".NOMETA_CMP",  NoMetaCmp,	OP_NOMETA_CMP },
320{ ".NOPATH",	  NoPath,	OP_NOPATH },
321{ ".NOTMAIN",	  Attribute,   	OP_NOTMAIN },
322{ ".NOTPARALLEL", NotParallel,	0 },
323{ ".NO_PARALLEL", NotParallel,	0 },
324{ ".NULL",  	  Null,	    	0 },
325{ ".OBJDIR",	  ExObjdir,	0 },
326{ ".OPTIONAL",	  Attribute,   	OP_OPTIONAL },
327{ ".ORDER", 	  Order,    	0 },
328{ ".PARALLEL",	  Parallel,	0 },
329{ ".PATH",	  ExPath,	0 },
330{ ".PHONY",	  Phony,	OP_PHONY },
331#ifdef POSIX
332{ ".POSIX",	  Posix,	0 },
333#endif
334{ ".PRECIOUS",	  Precious, 	OP_PRECIOUS },
335{ ".RECURSIVE",	  Attribute,	OP_MAKE },
336{ ".SHELL", 	  ExShell,    	0 },
337{ ".SILENT",	  Silent,   	OP_SILENT },
338{ ".SINGLESHELL", SingleShell,	0 },
339{ ".SUFFIXES",	  Suffixes, 	0 },
340{ ".USE",   	  Attribute,   	OP_USE },
341{ ".USEBEFORE",   Attribute,   	OP_USEBEFORE },
342{ ".WAIT",	  Wait, 	0 },
343};
344
345////////////////////////////////////////////////////////////
346// local functions
347
348static int ParseIsEscaped(const char *, const char *);
349static void ParseErrorInternal(const char *, size_t, int, const char *, ...)
350    MAKE_ATTR_PRINTFLIKE(4,5);
351static void ParseVErrorInternal(FILE *, const char *, size_t, int, const char *, va_list)
352    MAKE_ATTR_PRINTFLIKE(5, 0);
353static int ParseFindKeyword(const char *);
354static int ParseLinkSrc(void *, void *);
355static int ParseDoOp(void *, void *);
356static void ParseDoSrc(int, const char *);
357static int ParseFindMain(void *, void *);
358static int ParseAddDir(void *, void *);
359static int ParseClearPath(void *, void *);
360static void ParseDoDependency(char *);
361static int ParseAddCmd(void *, void *);
362static void ParseHasCommands(void *);
363static void ParseDoInclude(char *);
364static void ParseSetParseFile(const char *);
365#ifdef SYSVINCLUDE
366static void ParseTraditionalInclude(char *);
367#endif
368#ifdef GMAKEEXPORT
369static void ParseGmakeExport(char *);
370#endif
371static int ParseEOF(void);
372static char *ParseReadLine(void);
373static void ParseFinishLine(void);
374static void ParseMark(GNode *);
375
376////////////////////////////////////////////////////////////
377// file loader
378
379struct loadedfile {
380	const char *path;		/* name, for error reports */
381	char *buf;			/* contents buffer */
382	size_t len;			/* length of contents */
383	size_t maplen;			/* length of mmap area, or 0 */
384	Boolean used;			/* XXX: have we used the data yet */
385};
386
387/*
388 * Constructor/destructor for loadedfile
389 */
390static struct loadedfile *
391loadedfile_create(const char *path)
392{
393	struct loadedfile *lf;
394
395	lf = bmake_malloc(sizeof(*lf));
396	lf->path = (path == NULL ? "(stdin)" : path);
397	lf->buf = NULL;
398	lf->len = 0;
399	lf->maplen = 0;
400	lf->used = FALSE;
401	return lf;
402}
403
404static void
405loadedfile_destroy(struct loadedfile *lf)
406{
407	if (lf->buf != NULL) {
408		if (lf->maplen > 0) {
409#ifdef HAVE_MMAP
410			munmap(lf->buf, lf->maplen);
411#endif
412		} else {
413			free(lf->buf);
414		}
415	}
416	free(lf);
417}
418
419/*
420 * nextbuf() operation for loadedfile, as needed by the weird and twisted
421 * logic below. Once that's cleaned up, we can get rid of lf->used...
422 */
423static char *
424loadedfile_nextbuf(void *x, size_t *len)
425{
426	struct loadedfile *lf = x;
427
428	if (lf->used) {
429		return NULL;
430	}
431	lf->used = TRUE;
432	*len = lf->len;
433	return lf->buf;
434}
435
436/*
437 * Try to get the size of a file.
438 */
439static ReturnStatus
440load_getsize(int fd, size_t *ret)
441{
442	struct stat st;
443
444	if (fstat(fd, &st) < 0) {
445		return FAILURE;
446	}
447
448	if (!S_ISREG(st.st_mode)) {
449		return FAILURE;
450	}
451
452	/*
453	 * st_size is an off_t, which is 64 bits signed; *ret is
454	 * size_t, which might be 32 bits unsigned or 64 bits
455	 * unsigned. Rather than being elaborate, just punt on
456	 * files that are more than 2^31 bytes. We should never
457	 * see a makefile that size in practice...
458	 *
459	 * While we're at it reject negative sizes too, just in case.
460	 */
461	if (st.st_size < 0 || st.st_size > 0x7fffffff) {
462		return FAILURE;
463	}
464
465	*ret = (size_t) st.st_size;
466	return SUCCESS;
467}
468
469/*
470 * Read in a file.
471 *
472 * Until the path search logic can be moved under here instead of
473 * being in the caller in another source file, we need to have the fd
474 * passed in already open. Bleh.
475 *
476 * If the path is NULL use stdin and (to insure against fd leaks)
477 * assert that the caller passed in -1.
478 */
479static struct loadedfile *
480loadfile(const char *path, int fd)
481{
482	struct loadedfile *lf;
483#ifdef HAVE_MMAP
484	long pagesize;
485#endif
486	ssize_t result;
487	size_t bufpos;
488
489	lf = loadedfile_create(path);
490
491	if (path == NULL) {
492		assert(fd == -1);
493		fd = STDIN_FILENO;
494	} else {
495#if 0 /* notyet */
496		fd = open(path, O_RDONLY);
497		if (fd < 0) {
498			...
499			Error("%s: %s", path, strerror(errno));
500			exit(1);
501		}
502#endif
503	}
504
505#ifdef HAVE_MMAP
506	if (load_getsize(fd, &lf->len) == SUCCESS) {
507		/* found a size, try mmap */
508		pagesize = sysconf(_SC_PAGESIZE);
509		if (pagesize <= 0) {
510			pagesize = 0x1000;
511		}
512		/* round size up to a page */
513		lf->maplen = pagesize * ((lf->len + pagesize - 1)/pagesize);
514
515		/*
516		 * XXX hack for dealing with empty files; remove when
517		 * we're no longer limited by interfacing to the old
518		 * logic elsewhere in this file.
519		 */
520		if (lf->maplen == 0) {
521			lf->maplen = pagesize;
522		}
523
524		/*
525		 * FUTURE: remove PROT_WRITE when the parser no longer
526		 * needs to scribble on the input.
527		 */
528		lf->buf = mmap(NULL, lf->maplen, PROT_READ|PROT_WRITE,
529			       MAP_FILE|MAP_COPY, fd, 0);
530		if (lf->buf != MAP_FAILED) {
531			/* succeeded */
532			if (lf->len == lf->maplen && lf->buf[lf->len - 1] != '\n') {
533				char *b = malloc(lf->len + 1);
534				b[lf->len] = '\n';
535				memcpy(b, lf->buf, lf->len++);
536				munmap(lf->buf, lf->maplen);
537				lf->maplen = 0;
538				lf->buf = b;
539			}
540			goto done;
541		}
542	}
543#endif
544	/* cannot mmap; load the traditional way */
545
546	lf->maplen = 0;
547	lf->len = 1024;
548	lf->buf = bmake_malloc(lf->len);
549
550	bufpos = 0;
551	while (1) {
552		assert(bufpos <= lf->len);
553		if (bufpos == lf->len) {
554			lf->len *= 2;
555			lf->buf = bmake_realloc(lf->buf, lf->len);
556		}
557		result = read(fd, lf->buf + bufpos, lf->len - bufpos);
558		if (result < 0) {
559			Error("%s: read error: %s", path, strerror(errno));
560			exit(1);
561		}
562		if (result == 0) {
563			break;
564		}
565		bufpos += result;
566	}
567	assert(bufpos <= lf->len);
568	lf->len = bufpos;
569
570	/* truncate malloc region to actual length (maybe not useful) */
571	if (lf->len > 0) {
572		lf->buf = bmake_realloc(lf->buf, lf->len);
573	}
574
575#ifdef HAVE_MMAP
576done:
577#endif
578	if (path != NULL) {
579		close(fd);
580	}
581	return lf;
582}
583
584////////////////////////////////////////////////////////////
585// old code
586
587/*-
588 *----------------------------------------------------------------------
589 * ParseIsEscaped --
590 *	Check if the current character is escaped on the current line
591 *
592 * Results:
593 *	0 if the character is not backslash escaped, 1 otherwise
594 *
595 * Side Effects:
596 *	None
597 *----------------------------------------------------------------------
598 */
599static int
600ParseIsEscaped(const char *line, const char *c)
601{
602    int active = 0;
603    for (;;) {
604	if (line == c)
605	    return active;
606	if (*--c != '\\')
607	    return active;
608	active = !active;
609    }
610}
611
612/*-
613 *----------------------------------------------------------------------
614 * ParseFindKeyword --
615 *	Look in the table of keywords for one matching the given string.
616 *
617 * Input:
618 *	str		String to find
619 *
620 * Results:
621 *	The index of the keyword, or -1 if it isn't there.
622 *
623 * Side Effects:
624 *	None
625 *----------------------------------------------------------------------
626 */
627static int
628ParseFindKeyword(const char *str)
629{
630    int    start, end, cur;
631    int    diff;
632
633    start = 0;
634    end = (sizeof(parseKeywords)/sizeof(parseKeywords[0])) - 1;
635
636    do {
637	cur = start + ((end - start) / 2);
638	diff = strcmp(str, parseKeywords[cur].name);
639
640	if (diff == 0) {
641	    return (cur);
642	} else if (diff < 0) {
643	    end = cur - 1;
644	} else {
645	    start = cur + 1;
646	}
647    } while (start <= end);
648    return (-1);
649}
650
651/*-
652 * ParseVErrorInternal  --
653 *	Error message abort function for parsing. Prints out the context
654 *	of the error (line number and file) as well as the message with
655 *	two optional arguments.
656 *
657 * Results:
658 *	None
659 *
660 * Side Effects:
661 *	"fatals" is incremented if the level is PARSE_FATAL.
662 */
663/* VARARGS */
664static void
665ParseVErrorInternal(FILE *f, const char *cfname, size_t clineno, int type,
666    const char *fmt, va_list ap)
667{
668	static Boolean fatal_warning_error_printed = FALSE;
669
670	(void)fprintf(f, "%s: ", progname);
671
672	if (cfname != NULL) {
673		(void)fprintf(f, "\"");
674		if (*cfname != '/' && strcmp(cfname, "(stdin)") != 0) {
675			char *cp;
676			const char *dir;
677
678			/*
679			 * Nothing is more annoying than not knowing
680			 * which Makefile is the culprit.
681			 */
682			dir = Var_Value(".PARSEDIR", VAR_GLOBAL, &cp);
683			if (dir == NULL || *dir == '\0' ||
684			    (*dir == '.' && dir[1] == '\0'))
685				dir = Var_Value(".CURDIR", VAR_GLOBAL, &cp);
686			if (dir == NULL)
687				dir = ".";
688
689			(void)fprintf(f, "%s/%s", dir, cfname);
690		} else
691			(void)fprintf(f, "%s", cfname);
692
693		(void)fprintf(f, "\" line %d: ", (int)clineno);
694	}
695	if (type == PARSE_WARNING)
696		(void)fprintf(f, "warning: ");
697	(void)vfprintf(f, fmt, ap);
698	(void)fprintf(f, "\n");
699	(void)fflush(f);
700	if (type == PARSE_FATAL || parseWarnFatal)
701		fatals += 1;
702	if (parseWarnFatal && !fatal_warning_error_printed) {
703		Error("parsing warnings being treated as errors");
704		fatal_warning_error_printed = TRUE;
705	}
706}
707
708/*-
709 * ParseErrorInternal  --
710 *	Error function
711 *
712 * Results:
713 *	None
714 *
715 * Side Effects:
716 *	None
717 */
718/* VARARGS */
719static void
720ParseErrorInternal(const char *cfname, size_t clineno, int type,
721    const char *fmt, ...)
722{
723	va_list ap;
724
725	va_start(ap, fmt);
726	(void)fflush(stdout);
727	ParseVErrorInternal(stderr, cfname, clineno, type, fmt, ap);
728	va_end(ap);
729
730	if (debug_file != stderr && debug_file != stdout) {
731		va_start(ap, fmt);
732		ParseVErrorInternal(debug_file, cfname, clineno, type, fmt, ap);
733		va_end(ap);
734	}
735}
736
737/*-
738 * Parse_Error  --
739 *	External interface to ParseErrorInternal; uses the default filename
740 *	Line number.
741 *
742 * Results:
743 *	None
744 *
745 * Side Effects:
746 *	None
747 */
748/* VARARGS */
749void
750Parse_Error(int type, const char *fmt, ...)
751{
752	va_list ap;
753	const char *fname;
754	size_t lineno;
755
756	if (curFile == NULL) {
757		fname = NULL;
758		lineno = 0;
759	} else {
760		fname = curFile->fname;
761		lineno = curFile->lineno;
762	}
763
764	va_start(ap, fmt);
765	(void)fflush(stdout);
766	ParseVErrorInternal(stderr, fname, lineno, type, fmt, ap);
767	va_end(ap);
768
769	if (debug_file != stderr && debug_file != stdout) {
770		va_start(ap, fmt);
771		ParseVErrorInternal(debug_file, fname, lineno, type, fmt, ap);
772		va_end(ap);
773	}
774}
775
776
777/*
778 * ParseMessage
779 *	Parse a .info .warning or .error directive
780 *
781 *	The input is the line minus the ".".  We substitute
782 *	variables, print the message and exit(1) (for .error) or just print
783 *	a warning if the directive is malformed.
784 */
785static Boolean
786ParseMessage(char *line)
787{
788    int mtype;
789
790    switch(*line) {
791    case 'i':
792	mtype = 0;
793	break;
794    case 'w':
795	mtype = PARSE_WARNING;
796	break;
797    case 'e':
798	mtype = PARSE_FATAL;
799	break;
800    default:
801	Parse_Error(PARSE_WARNING, "invalid syntax: \".%s\"", line);
802	return FALSE;
803    }
804
805    while (isalpha((u_char)*line))
806	line++;
807    if (!isspace((u_char)*line))
808	return FALSE;			/* not for us */
809    while (isspace((u_char)*line))
810	line++;
811
812    line = Var_Subst(NULL, line, VAR_CMD, 0);
813    Parse_Error(mtype, "%s", line);
814    free(line);
815
816    if (mtype == PARSE_FATAL) {
817	/* Terminate immediately. */
818	exit(1);
819    }
820    return TRUE;
821}
822
823/*-
824 *---------------------------------------------------------------------
825 * ParseLinkSrc  --
826 *	Link the parent node to its new child. Used in a Lst_ForEach by
827 *	ParseDoDependency. If the specType isn't 'Not', the parent
828 *	isn't linked as a parent of the child.
829 *
830 * Input:
831 *	pgnp		The parent node
832 *	cgpn		The child node
833 *
834 * Results:
835 *	Always = 0
836 *
837 * Side Effects:
838 *	New elements are added to the parents list of cgn and the
839 *	children list of cgn. the unmade field of pgn is updated
840 *	to reflect the additional child.
841 *---------------------------------------------------------------------
842 */
843static int
844ParseLinkSrc(void *pgnp, void *cgnp)
845{
846    GNode          *pgn = (GNode *)pgnp;
847    GNode          *cgn = (GNode *)cgnp;
848
849    if ((pgn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (pgn->cohorts))
850	pgn = (GNode *)Lst_Datum(Lst_Last(pgn->cohorts));
851    (void)Lst_AtEnd(pgn->children, cgn);
852    if (specType == Not)
853	    (void)Lst_AtEnd(cgn->parents, pgn);
854    pgn->unmade += 1;
855    if (DEBUG(PARSE)) {
856	fprintf(debug_file, "# ParseLinkSrc: added child %s - %s\n", pgn->name, cgn->name);
857	Targ_PrintNode(pgn, 0);
858	Targ_PrintNode(cgn, 0);
859    }
860    return (0);
861}
862
863/*-
864 *---------------------------------------------------------------------
865 * ParseDoOp  --
866 *	Apply the parsed operator to the given target node. Used in a
867 *	Lst_ForEach call by ParseDoDependency once all targets have
868 *	been found and their operator parsed. If the previous and new
869 *	operators are incompatible, a major error is taken.
870 *
871 * Input:
872 *	gnp		The node to which the operator is to be applied
873 *	opp		The operator to apply
874 *
875 * Results:
876 *	Always 0
877 *
878 * Side Effects:
879 *	The type field of the node is altered to reflect any new bits in
880 *	the op.
881 *---------------------------------------------------------------------
882 */
883static int
884ParseDoOp(void *gnp, void *opp)
885{
886    GNode          *gn = (GNode *)gnp;
887    int             op = *(int *)opp;
888    /*
889     * If the dependency mask of the operator and the node don't match and
890     * the node has actually had an operator applied to it before, and
891     * the operator actually has some dependency information in it, complain.
892     */
893    if (((op & OP_OPMASK) != (gn->type & OP_OPMASK)) &&
894	!OP_NOP(gn->type) && !OP_NOP(op))
895    {
896	Parse_Error(PARSE_FATAL, "Inconsistent operator for %s", gn->name);
897	return (1);
898    }
899
900    if ((op == OP_DOUBLEDEP) && ((gn->type & OP_OPMASK) == OP_DOUBLEDEP)) {
901	/*
902	 * If the node was the object of a :: operator, we need to create a
903	 * new instance of it for the children and commands on this dependency
904	 * line. The new instance is placed on the 'cohorts' list of the
905	 * initial one (note the initial one is not on its own cohorts list)
906	 * and the new instance is linked to all parents of the initial
907	 * instance.
908	 */
909	GNode	*cohort;
910
911	/*
912	 * Propagate copied bits to the initial node.  They'll be propagated
913	 * back to the rest of the cohorts later.
914	 */
915	gn->type |= op & ~OP_OPMASK;
916
917	cohort = Targ_FindNode(gn->name, TARG_NOHASH);
918	/*
919	 * Make the cohort invisible as well to avoid duplicating it into
920	 * other variables. True, parents of this target won't tend to do
921	 * anything with their local variables, but better safe than
922	 * sorry. (I think this is pointless now, since the relevant list
923	 * traversals will no longer see this node anyway. -mycroft)
924	 */
925	cohort->type = op | OP_INVISIBLE;
926	(void)Lst_AtEnd(gn->cohorts, cohort);
927	cohort->centurion = gn;
928	gn->unmade_cohorts += 1;
929	snprintf(cohort->cohort_num, sizeof cohort->cohort_num, "#%d",
930		gn->unmade_cohorts);
931    } else {
932	/*
933	 * We don't want to nuke any previous flags (whatever they were) so we
934	 * just OR the new operator into the old
935	 */
936	gn->type |= op;
937    }
938
939    return (0);
940}
941
942/*-
943 *---------------------------------------------------------------------
944 * ParseDoSrc  --
945 *	Given the name of a source, figure out if it is an attribute
946 *	and apply it to the targets if it is. Else decide if there is
947 *	some attribute which should be applied *to* the source because
948 *	of some special target and apply it if so. Otherwise, make the
949 *	source be a child of the targets in the list 'targets'
950 *
951 * Input:
952 *	tOp		operator (if any) from special targets
953 *	src		name of the source to handle
954 *
955 * Results:
956 *	None
957 *
958 * Side Effects:
959 *	Operator bits may be added to the list of targets or to the source.
960 *	The targets may have a new source added to their lists of children.
961 *---------------------------------------------------------------------
962 */
963static void
964ParseDoSrc(int tOp, const char *src)
965{
966    GNode	*gn = NULL;
967    static int wait_number = 0;
968    char wait_src[16];
969
970    if (*src == '.' && isupper ((unsigned char)src[1])) {
971	int keywd = ParseFindKeyword(src);
972	if (keywd != -1) {
973	    int op = parseKeywords[keywd].op;
974	    if (op != 0) {
975		Lst_ForEach(targets, ParseDoOp, &op);
976		return;
977	    }
978	    if (parseKeywords[keywd].spec == Wait) {
979		/*
980		 * We add a .WAIT node in the dependency list.
981		 * After any dynamic dependencies (and filename globbing)
982		 * have happened, it is given a dependency on the each
983		 * previous child back to and previous .WAIT node.
984		 * The next child won't be scheduled until the .WAIT node
985		 * is built.
986		 * We give each .WAIT node a unique name (mainly for diag).
987		 */
988		snprintf(wait_src, sizeof wait_src, ".WAIT_%u", ++wait_number);
989		gn = Targ_FindNode(wait_src, TARG_NOHASH);
990		gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN;
991		Lst_ForEach(targets, ParseLinkSrc, gn);
992		return;
993	    }
994	}
995    }
996
997    switch (specType) {
998    case Main:
999	/*
1000	 * If we have noted the existence of a .MAIN, it means we need
1001	 * to add the sources of said target to the list of things
1002	 * to create. The string 'src' is likely to be free, so we
1003	 * must make a new copy of it. Note that this will only be
1004	 * invoked if the user didn't specify a target on the command
1005	 * line. This is to allow #ifmake's to succeed, or something...
1006	 */
1007	(void)Lst_AtEnd(create, bmake_strdup(src));
1008	/*
1009	 * Add the name to the .TARGETS variable as well, so the user can
1010	 * employ that, if desired.
1011	 */
1012	Var_Append(".TARGETS", src, VAR_GLOBAL);
1013	return;
1014
1015    case Order:
1016	/*
1017	 * Create proper predecessor/successor links between the previous
1018	 * source and the current one.
1019	 */
1020	gn = Targ_FindNode(src, TARG_CREATE);
1021	if (predecessor != NULL) {
1022	    (void)Lst_AtEnd(predecessor->order_succ, gn);
1023	    (void)Lst_AtEnd(gn->order_pred, predecessor);
1024	    if (DEBUG(PARSE)) {
1025		fprintf(debug_file, "# ParseDoSrc: added Order dependency %s - %s\n",
1026			predecessor->name, gn->name);
1027		Targ_PrintNode(predecessor, 0);
1028		Targ_PrintNode(gn, 0);
1029	    }
1030	}
1031	/*
1032	 * The current source now becomes the predecessor for the next one.
1033	 */
1034	predecessor = gn;
1035	break;
1036
1037    default:
1038	/*
1039	 * If the source is not an attribute, we need to find/create
1040	 * a node for it. After that we can apply any operator to it
1041	 * from a special target or link it to its parents, as
1042	 * appropriate.
1043	 *
1044	 * In the case of a source that was the object of a :: operator,
1045	 * the attribute is applied to all of its instances (as kept in
1046	 * the 'cohorts' list of the node) or all the cohorts are linked
1047	 * to all the targets.
1048	 */
1049
1050	/* Find/create the 'src' node and attach to all targets */
1051	gn = Targ_FindNode(src, TARG_CREATE);
1052	if (tOp) {
1053	    gn->type |= tOp;
1054	} else {
1055	    Lst_ForEach(targets, ParseLinkSrc, gn);
1056	}
1057	break;
1058    }
1059}
1060
1061/*-
1062 *-----------------------------------------------------------------------
1063 * ParseFindMain --
1064 *	Find a real target in the list and set it to be the main one.
1065 *	Called by ParseDoDependency when a main target hasn't been found
1066 *	yet.
1067 *
1068 * Input:
1069 *	gnp		Node to examine
1070 *
1071 * Results:
1072 *	0 if main not found yet, 1 if it is.
1073 *
1074 * Side Effects:
1075 *	mainNode is changed and Targ_SetMain is called.
1076 *
1077 *-----------------------------------------------------------------------
1078 */
1079static int
1080ParseFindMain(void *gnp, void *dummy)
1081{
1082    GNode   	  *gn = (GNode *)gnp;
1083    if ((gn->type & OP_NOTARGET) == 0) {
1084	mainNode = gn;
1085	Targ_SetMain(gn);
1086	return (dummy ? 1 : 1);
1087    } else {
1088	return (dummy ? 0 : 0);
1089    }
1090}
1091
1092/*-
1093 *-----------------------------------------------------------------------
1094 * ParseAddDir --
1095 *	Front-end for Dir_AddDir to make sure Lst_ForEach keeps going
1096 *
1097 * Results:
1098 *	=== 0
1099 *
1100 * Side Effects:
1101 *	See Dir_AddDir.
1102 *
1103 *-----------------------------------------------------------------------
1104 */
1105static int
1106ParseAddDir(void *path, void *name)
1107{
1108    (void)Dir_AddDir((Lst) path, (char *)name);
1109    return(0);
1110}
1111
1112/*-
1113 *-----------------------------------------------------------------------
1114 * ParseClearPath --
1115 *	Front-end for Dir_ClearPath to make sure Lst_ForEach keeps going
1116 *
1117 * Results:
1118 *	=== 0
1119 *
1120 * Side Effects:
1121 *	See Dir_ClearPath
1122 *
1123 *-----------------------------------------------------------------------
1124 */
1125static int
1126ParseClearPath(void *path, void *dummy)
1127{
1128    Dir_ClearPath((Lst) path);
1129    return(dummy ? 0 : 0);
1130}
1131
1132/*-
1133 *---------------------------------------------------------------------
1134 * ParseDoDependency  --
1135 *	Parse the dependency line in line.
1136 *
1137 * Input:
1138 *	line		the line to parse
1139 *
1140 * Results:
1141 *	None
1142 *
1143 * Side Effects:
1144 *	The nodes of the sources are linked as children to the nodes of the
1145 *	targets. Some nodes may be created.
1146 *
1147 *	We parse a dependency line by first extracting words from the line and
1148 * finding nodes in the list of all targets with that name. This is done
1149 * until a character is encountered which is an operator character. Currently
1150 * these are only ! and :. At this point the operator is parsed and the
1151 * pointer into the line advanced until the first source is encountered.
1152 * 	The parsed operator is applied to each node in the 'targets' list,
1153 * which is where the nodes found for the targets are kept, by means of
1154 * the ParseDoOp function.
1155 *	The sources are read in much the same way as the targets were except
1156 * that now they are expanded using the wildcarding scheme of the C-Shell
1157 * and all instances of the resulting words in the list of all targets
1158 * are found. Each of the resulting nodes is then linked to each of the
1159 * targets as one of its children.
1160 *	Certain targets are handled specially. These are the ones detailed
1161 * by the specType variable.
1162 *	The storing of transformation rules is also taken care of here.
1163 * A target is recognized as a transformation rule by calling
1164 * Suff_IsTransform. If it is a transformation rule, its node is gotten
1165 * from the suffix module via Suff_AddTransform rather than the standard
1166 * Targ_FindNode in the target module.
1167 *---------------------------------------------------------------------
1168 */
1169static void
1170ParseDoDependency(char *line)
1171{
1172    char  	   *cp;		/* our current position */
1173    GNode 	   *gn = NULL;	/* a general purpose temporary node */
1174    int             op;		/* the operator on the line */
1175    char            savec;	/* a place to save a character */
1176    Lst    	    paths;   	/* List of search paths to alter when parsing
1177				 * a list of .PATH targets */
1178    int	    	    tOp;    	/* operator from special target */
1179    Lst	    	    sources;	/* list of archive source names after
1180				 * expansion */
1181    Lst 	    curTargs;	/* list of target names to be found and added
1182				 * to the targets list */
1183    char	   *lstart = line;
1184
1185    if (DEBUG(PARSE))
1186	fprintf(debug_file, "ParseDoDependency(%s)\n", line);
1187    tOp = 0;
1188
1189    specType = Not;
1190    paths = NULL;
1191
1192    curTargs = Lst_Init(FALSE);
1193
1194    do {
1195	for (cp = line; *cp && (ParseIsEscaped(lstart, cp) ||
1196		     !(isspace((unsigned char)*cp) ||
1197			 *cp == '!' || *cp == ':' || *cp == LPAREN));
1198		 cp++) {
1199	    if (*cp == '$') {
1200		/*
1201		 * Must be a dynamic source (would have been expanded
1202		 * otherwise), so call the Var module to parse the puppy
1203		 * so we can safely advance beyond it...There should be
1204		 * no errors in this, as they would have been discovered
1205		 * in the initial Var_Subst and we wouldn't be here.
1206		 */
1207		int 	length;
1208		void    *freeIt;
1209		char	*result;
1210
1211		result = Var_Parse(cp, VAR_CMD, TRUE, &length, &freeIt);
1212		if (freeIt)
1213		    free(freeIt);
1214		cp += length-1;
1215	    }
1216	}
1217
1218	if (!ParseIsEscaped(lstart, cp) && *cp == LPAREN) {
1219	    /*
1220	     * Archives must be handled specially to make sure the OP_ARCHV
1221	     * flag is set in their 'type' field, for one thing, and because
1222	     * things like "archive(file1.o file2.o file3.o)" are permissible.
1223	     * Arch_ParseArchive will set 'line' to be the first non-blank
1224	     * after the archive-spec. It creates/finds nodes for the members
1225	     * and places them on the given list, returning SUCCESS if all
1226	     * went well and FAILURE if there was an error in the
1227	     * specification. On error, line should remain untouched.
1228	     */
1229	    if (Arch_ParseArchive(&line, targets, VAR_CMD) != SUCCESS) {
1230		Parse_Error(PARSE_FATAL,
1231			     "Error in archive specification: \"%s\"", line);
1232		goto out;
1233	    } else {
1234		continue;
1235	    }
1236	}
1237	savec = *cp;
1238
1239	if (!*cp) {
1240	    /*
1241	     * Ending a dependency line without an operator is a Bozo
1242	     * no-no.  As a heuristic, this is also often triggered by
1243	     * undetected conflicts from cvs/rcs merges.
1244	     */
1245	    if ((strncmp(line, "<<<<<<", 6) == 0) ||
1246		(strncmp(line, "======", 6) == 0) ||
1247		(strncmp(line, ">>>>>>", 6) == 0))
1248		Parse_Error(PARSE_FATAL,
1249		    "Makefile appears to contain unresolved cvs/rcs/??? merge conflicts");
1250	    else
1251		Parse_Error(PARSE_FATAL, lstart[0] == '.' ? "Unknown directive"
1252				     : "Need an operator");
1253	    goto out;
1254	}
1255	*cp = '\0';
1256
1257	/*
1258	 * Have a word in line. See if it's a special target and set
1259	 * specType to match it.
1260	 */
1261	if (*line == '.' && isupper ((unsigned char)line[1])) {
1262	    /*
1263	     * See if the target is a special target that must have it
1264	     * or its sources handled specially.
1265	     */
1266	    int keywd = ParseFindKeyword(line);
1267	    if (keywd != -1) {
1268		if (specType == ExPath && parseKeywords[keywd].spec != ExPath) {
1269		    Parse_Error(PARSE_FATAL, "Mismatched special targets");
1270		    goto out;
1271		}
1272
1273		specType = parseKeywords[keywd].spec;
1274		tOp = parseKeywords[keywd].op;
1275
1276		/*
1277		 * Certain special targets have special semantics:
1278		 *	.PATH		Have to set the dirSearchPath
1279		 *			variable too
1280		 *	.MAIN		Its sources are only used if
1281		 *			nothing has been specified to
1282		 *			create.
1283		 *	.DEFAULT    	Need to create a node to hang
1284		 *			commands on, but we don't want
1285		 *			it in the graph, nor do we want
1286		 *			it to be the Main Target, so we
1287		 *			create it, set OP_NOTMAIN and
1288		 *			add it to the list, setting
1289		 *			DEFAULT to the new node for
1290		 *			later use. We claim the node is
1291		 *	    	    	A transformation rule to make
1292		 *	    	    	life easier later, when we'll
1293		 *	    	    	use Make_HandleUse to actually
1294		 *	    	    	apply the .DEFAULT commands.
1295		 *	.PHONY		The list of targets
1296		 *	.NOPATH		Don't search for file in the path
1297		 *	.BEGIN
1298		 *	.END
1299		 *	.ERROR
1300		 *	.INTERRUPT  	Are not to be considered the
1301		 *			main target.
1302		 *  	.NOTPARALLEL	Make only one target at a time.
1303		 *  	.SINGLESHELL	Create a shell for each command.
1304		 *  	.ORDER	    	Must set initial predecessor to NULL
1305		 */
1306		switch (specType) {
1307		    case ExPath:
1308			if (paths == NULL) {
1309			    paths = Lst_Init(FALSE);
1310			}
1311			(void)Lst_AtEnd(paths, dirSearchPath);
1312			break;
1313		    case Main:
1314			if (!Lst_IsEmpty(create)) {
1315			    specType = Not;
1316			}
1317			break;
1318		    case Begin:
1319		    case End:
1320		    case dotError:
1321		    case Interrupt:
1322			gn = Targ_FindNode(line, TARG_CREATE);
1323			gn->type |= OP_NOTMAIN|OP_SPECIAL;
1324			(void)Lst_AtEnd(targets, gn);
1325			break;
1326		    case Default:
1327			gn = Targ_NewGN(".DEFAULT");
1328			gn->type |= (OP_NOTMAIN|OP_TRANSFORM);
1329			(void)Lst_AtEnd(targets, gn);
1330			DEFAULT = gn;
1331			break;
1332		    case NotParallel:
1333			maxJobs = 1;
1334			break;
1335		    case SingleShell:
1336			compatMake = TRUE;
1337			break;
1338		    case Order:
1339			predecessor = NULL;
1340			break;
1341		    default:
1342			break;
1343		}
1344	    } else if (strncmp(line, ".PATH", 5) == 0) {
1345		/*
1346		 * .PATH<suffix> has to be handled specially.
1347		 * Call on the suffix module to give us a path to
1348		 * modify.
1349		 */
1350		Lst 	path;
1351
1352		specType = ExPath;
1353		path = Suff_GetPath(&line[5]);
1354		if (path == NULL) {
1355		    Parse_Error(PARSE_FATAL,
1356				 "Suffix '%s' not defined (yet)",
1357				 &line[5]);
1358		    goto out;
1359		} else {
1360		    if (paths == NULL) {
1361			paths = Lst_Init(FALSE);
1362		    }
1363		    (void)Lst_AtEnd(paths, path);
1364		}
1365	    }
1366	}
1367
1368	/*
1369	 * Have word in line. Get or create its node and stick it at
1370	 * the end of the targets list
1371	 */
1372	if ((specType == Not) && (*line != '\0')) {
1373	    if (Dir_HasWildcards(line)) {
1374		/*
1375		 * Targets are to be sought only in the current directory,
1376		 * so create an empty path for the thing. Note we need to
1377		 * use Dir_Destroy in the destruction of the path as the
1378		 * Dir module could have added a directory to the path...
1379		 */
1380		Lst	    emptyPath = Lst_Init(FALSE);
1381
1382		Dir_Expand(line, emptyPath, curTargs);
1383
1384		Lst_Destroy(emptyPath, Dir_Destroy);
1385	    } else {
1386		/*
1387		 * No wildcards, but we want to avoid code duplication,
1388		 * so create a list with the word on it.
1389		 */
1390		(void)Lst_AtEnd(curTargs, line);
1391	    }
1392
1393	    while(!Lst_IsEmpty(curTargs)) {
1394		char	*targName = (char *)Lst_DeQueue(curTargs);
1395
1396		if (!Suff_IsTransform (targName)) {
1397		    gn = Targ_FindNode(targName, TARG_CREATE);
1398		} else {
1399		    gn = Suff_AddTransform(targName);
1400		}
1401
1402		(void)Lst_AtEnd(targets, gn);
1403	    }
1404	} else if (specType == ExPath && *line != '.' && *line != '\0') {
1405	    Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", line);
1406	}
1407
1408	*cp = savec;
1409	/*
1410	 * If it is a special type and not .PATH, it's the only target we
1411	 * allow on this line...
1412	 */
1413	if (specType != Not && specType != ExPath) {
1414	    Boolean warning = FALSE;
1415
1416	    while (*cp && (ParseIsEscaped(lstart, cp) ||
1417		((*cp != '!') && (*cp != ':')))) {
1418		if (ParseIsEscaped(lstart, cp) ||
1419		    (*cp != ' ' && *cp != '\t')) {
1420		    warning = TRUE;
1421		}
1422		cp++;
1423	    }
1424	    if (warning) {
1425		Parse_Error(PARSE_WARNING, "Extra target ignored");
1426	    }
1427	} else {
1428	    while (*cp && isspace ((unsigned char)*cp)) {
1429		cp++;
1430	    }
1431	}
1432	line = cp;
1433    } while (*line && (ParseIsEscaped(lstart, line) ||
1434	((*line != '!') && (*line != ':'))));
1435
1436    /*
1437     * Don't need the list of target names anymore...
1438     */
1439    Lst_Destroy(curTargs, NULL);
1440    curTargs = NULL;
1441
1442    if (!Lst_IsEmpty(targets)) {
1443	switch(specType) {
1444	    default:
1445		Parse_Error(PARSE_WARNING, "Special and mundane targets don't mix. Mundane ones ignored");
1446		break;
1447	    case Default:
1448	    case Begin:
1449	    case End:
1450	    case dotError:
1451	    case Interrupt:
1452		/*
1453		 * These four create nodes on which to hang commands, so
1454		 * targets shouldn't be empty...
1455		 */
1456	    case Not:
1457		/*
1458		 * Nothing special here -- targets can be empty if it wants.
1459		 */
1460		break;
1461	}
1462    }
1463
1464    /*
1465     * Have now parsed all the target names. Must parse the operator next. The
1466     * result is left in  op .
1467     */
1468    if (*cp == '!') {
1469	op = OP_FORCE;
1470    } else if (*cp == ':') {
1471	if (cp[1] == ':') {
1472	    op = OP_DOUBLEDEP;
1473	    cp++;
1474	} else {
1475	    op = OP_DEPENDS;
1476	}
1477    } else {
1478	Parse_Error(PARSE_FATAL, lstart[0] == '.' ? "Unknown directive"
1479		    : "Missing dependency operator");
1480	goto out;
1481    }
1482
1483    cp++;			/* Advance beyond operator */
1484
1485    Lst_ForEach(targets, ParseDoOp, &op);
1486
1487    /*
1488     * Get to the first source
1489     */
1490    while (*cp && isspace ((unsigned char)*cp)) {
1491	cp++;
1492    }
1493    line = cp;
1494
1495    /*
1496     * Several special targets take different actions if present with no
1497     * sources:
1498     *	a .SUFFIXES line with no sources clears out all old suffixes
1499     *	a .PRECIOUS line makes all targets precious
1500     *	a .IGNORE line ignores errors for all targets
1501     *	a .SILENT line creates silence when making all targets
1502     *	a .PATH removes all directories from the search path(s).
1503     */
1504    if (!*line) {
1505	switch (specType) {
1506	    case Suffixes:
1507		Suff_ClearSuffixes();
1508		break;
1509	    case Precious:
1510		allPrecious = TRUE;
1511		break;
1512	    case Ignore:
1513		ignoreErrors = TRUE;
1514		break;
1515	    case Silent:
1516		beSilent = TRUE;
1517		break;
1518	    case ExPath:
1519		Lst_ForEach(paths, ParseClearPath, NULL);
1520		Dir_SetPATH();
1521		break;
1522#ifdef POSIX
1523            case Posix:
1524                Var_Set("%POSIX", "1003.2", VAR_GLOBAL, 0);
1525                break;
1526#endif
1527	    default:
1528		break;
1529	}
1530    } else if (specType == MFlags) {
1531	/*
1532	 * Call on functions in main.c to deal with these arguments and
1533	 * set the initial character to a null-character so the loop to
1534	 * get sources won't get anything
1535	 */
1536	Main_ParseArgLine(line);
1537	*line = '\0';
1538    } else if (specType == ExShell) {
1539	if (Job_ParseShell(line) != SUCCESS) {
1540	    Parse_Error(PARSE_FATAL, "improper shell specification");
1541	    goto out;
1542	}
1543	*line = '\0';
1544    } else if ((specType == NotParallel) || (specType == SingleShell)) {
1545	*line = '\0';
1546    }
1547
1548    /*
1549     * NOW GO FOR THE SOURCES
1550     */
1551    if ((specType == Suffixes) || (specType == ExPath) ||
1552	(specType == Includes) || (specType == Libs) ||
1553	(specType == Null) || (specType == ExObjdir))
1554    {
1555	while (*line) {
1556	    /*
1557	     * If the target was one that doesn't take files as its sources
1558	     * but takes something like suffixes, we take each
1559	     * space-separated word on the line as a something and deal
1560	     * with it accordingly.
1561	     *
1562	     * If the target was .SUFFIXES, we take each source as a
1563	     * suffix and add it to the list of suffixes maintained by the
1564	     * Suff module.
1565	     *
1566	     * If the target was a .PATH, we add the source as a directory
1567	     * to search on the search path.
1568	     *
1569	     * If it was .INCLUDES, the source is taken to be the suffix of
1570	     * files which will be #included and whose search path should
1571	     * be present in the .INCLUDES variable.
1572	     *
1573	     * If it was .LIBS, the source is taken to be the suffix of
1574	     * files which are considered libraries and whose search path
1575	     * should be present in the .LIBS variable.
1576	     *
1577	     * If it was .NULL, the source is the suffix to use when a file
1578	     * has no valid suffix.
1579	     *
1580	     * If it was .OBJDIR, the source is a new definition for .OBJDIR,
1581	     * and will cause make to do a new chdir to that path.
1582	     */
1583	    while (*cp && !isspace ((unsigned char)*cp)) {
1584		cp++;
1585	    }
1586	    savec = *cp;
1587	    *cp = '\0';
1588	    switch (specType) {
1589		case Suffixes:
1590		    Suff_AddSuffix(line, &mainNode);
1591		    break;
1592		case ExPath:
1593		    Lst_ForEach(paths, ParseAddDir, line);
1594		    break;
1595		case Includes:
1596		    Suff_AddInclude(line);
1597		    break;
1598		case Libs:
1599		    Suff_AddLib(line);
1600		    break;
1601		case Null:
1602		    Suff_SetNull(line);
1603		    break;
1604		case ExObjdir:
1605		    Main_SetObjdir(line);
1606		    break;
1607		default:
1608		    break;
1609	    }
1610	    *cp = savec;
1611	    if (savec != '\0') {
1612		cp++;
1613	    }
1614	    while (*cp && isspace ((unsigned char)*cp)) {
1615		cp++;
1616	    }
1617	    line = cp;
1618	}
1619	if (paths) {
1620	    Lst_Destroy(paths, NULL);
1621	}
1622	if (specType == ExPath)
1623	    Dir_SetPATH();
1624    } else {
1625	while (*line) {
1626	    /*
1627	     * The targets take real sources, so we must beware of archive
1628	     * specifications (i.e. things with left parentheses in them)
1629	     * and handle them accordingly.
1630	     */
1631	    for (; *cp && !isspace ((unsigned char)*cp); cp++) {
1632		if ((*cp == LPAREN) && (cp > line) && (cp[-1] != '$')) {
1633		    /*
1634		     * Only stop for a left parenthesis if it isn't at the
1635		     * start of a word (that'll be for variable changes
1636		     * later) and isn't preceded by a dollar sign (a dynamic
1637		     * source).
1638		     */
1639		    break;
1640		}
1641	    }
1642
1643	    if (*cp == LPAREN) {
1644		sources = Lst_Init(FALSE);
1645		if (Arch_ParseArchive(&line, sources, VAR_CMD) != SUCCESS) {
1646		    Parse_Error(PARSE_FATAL,
1647				 "Error in source archive spec \"%s\"", line);
1648		    goto out;
1649		}
1650
1651		while (!Lst_IsEmpty (sources)) {
1652		    gn = (GNode *)Lst_DeQueue(sources);
1653		    ParseDoSrc(tOp, gn->name);
1654		}
1655		Lst_Destroy(sources, NULL);
1656		cp = line;
1657	    } else {
1658		if (*cp) {
1659		    *cp = '\0';
1660		    cp += 1;
1661		}
1662
1663		ParseDoSrc(tOp, line);
1664	    }
1665	    while (*cp && isspace ((unsigned char)*cp)) {
1666		cp++;
1667	    }
1668	    line = cp;
1669	}
1670    }
1671
1672    if (mainNode == NULL) {
1673	/*
1674	 * If we have yet to decide on a main target to make, in the
1675	 * absence of any user input, we want the first target on
1676	 * the first dependency line that is actually a real target
1677	 * (i.e. isn't a .USE or .EXEC rule) to be made.
1678	 */
1679	Lst_ForEach(targets, ParseFindMain, NULL);
1680    }
1681
1682out:
1683    if (curTargs)
1684	    Lst_Destroy(curTargs, NULL);
1685}
1686
1687/*-
1688 *---------------------------------------------------------------------
1689 * Parse_IsVar  --
1690 *	Return TRUE if the passed line is a variable assignment. A variable
1691 *	assignment consists of a single word followed by optional whitespace
1692 *	followed by either a += or an = operator.
1693 *	This function is used both by the Parse_File function and main when
1694 *	parsing the command-line arguments.
1695 *
1696 * Input:
1697 *	line		the line to check
1698 *
1699 * Results:
1700 *	TRUE if it is. FALSE if it ain't
1701 *
1702 * Side Effects:
1703 *	none
1704 *---------------------------------------------------------------------
1705 */
1706Boolean
1707Parse_IsVar(char *line)
1708{
1709    Boolean wasSpace = FALSE;	/* set TRUE if found a space */
1710    char ch;
1711    int level = 0;
1712#define ISEQOPERATOR(c) \
1713	(((c) == '+') || ((c) == ':') || ((c) == '?') || ((c) == '!'))
1714
1715    /*
1716     * Skip to variable name
1717     */
1718    for (;(*line == ' ') || (*line == '\t'); line++)
1719	continue;
1720
1721    /* Scan for one of the assignment operators outside a variable expansion */
1722    while ((ch = *line++) != 0) {
1723	if (ch == '(' || ch == '{') {
1724	    level++;
1725	    continue;
1726	}
1727	if (ch == ')' || ch == '}') {
1728	    level--;
1729	    continue;
1730	}
1731	if (level != 0)
1732	    continue;
1733	while (ch == ' ' || ch == '\t') {
1734	    ch = *line++;
1735	    wasSpace = TRUE;
1736	}
1737	if (ch == '=')
1738	    return TRUE;
1739	if (*line == '=' && ISEQOPERATOR(ch))
1740	    return TRUE;
1741	if (wasSpace)
1742	    return FALSE;
1743    }
1744
1745    return FALSE;
1746}
1747
1748/*-
1749 *---------------------------------------------------------------------
1750 * Parse_DoVar  --
1751 *	Take the variable assignment in the passed line and do it in the
1752 *	global context.
1753 *
1754 *	Note: There is a lexical ambiguity with assignment modifier characters
1755 *	in variable names. This routine interprets the character before the =
1756 *	as a modifier. Therefore, an assignment like
1757 *	    C++=/usr/bin/CC
1758 *	is interpreted as "C+ +=" instead of "C++ =".
1759 *
1760 * Input:
1761 *	line		a line guaranteed to be a variable assignment.
1762 *			This reduces error checks
1763 *	ctxt		Context in which to do the assignment
1764 *
1765 * Results:
1766 *	none
1767 *
1768 * Side Effects:
1769 *	the variable structure of the given variable name is altered in the
1770 *	global context.
1771 *---------------------------------------------------------------------
1772 */
1773void
1774Parse_DoVar(char *line, GNode *ctxt)
1775{
1776    char	   *cp;	/* pointer into line */
1777    enum {
1778	VAR_SUBST, VAR_APPEND, VAR_SHELL, VAR_NORMAL
1779    }	    	    type;   	/* Type of assignment */
1780    char            *opc;	/* ptr to operator character to
1781				 * null-terminate the variable name */
1782    Boolean	   freeCp = FALSE; /* TRUE if cp needs to be freed,
1783				    * i.e. if any variable expansion was
1784				    * performed */
1785    int depth;
1786
1787    /*
1788     * Skip to variable name
1789     */
1790    while ((*line == ' ') || (*line == '\t')) {
1791	line++;
1792    }
1793
1794    /*
1795     * Skip to operator character, nulling out whitespace as we go
1796     * XXX Rather than counting () and {} we should look for $ and
1797     * then expand the variable.
1798     */
1799    for (depth = 0, cp = line + 1; depth != 0 || *cp != '='; cp++) {
1800	if (*cp == '(' || *cp == '{') {
1801	    depth++;
1802	    continue;
1803	}
1804	if (*cp == ')' || *cp == '}') {
1805	    depth--;
1806	    continue;
1807	}
1808	if (depth == 0 && isspace ((unsigned char)*cp)) {
1809	    *cp = '\0';
1810	}
1811    }
1812    opc = cp-1;		/* operator is the previous character */
1813    *cp++ = '\0';	/* nuke the = */
1814
1815    /*
1816     * Check operator type
1817     */
1818    switch (*opc) {
1819	case '+':
1820	    type = VAR_APPEND;
1821	    *opc = '\0';
1822	    break;
1823
1824	case '?':
1825	    /*
1826	     * If the variable already has a value, we don't do anything.
1827	     */
1828	    *opc = '\0';
1829	    if (Var_Exists(line, ctxt)) {
1830		return;
1831	    } else {
1832		type = VAR_NORMAL;
1833	    }
1834	    break;
1835
1836	case ':':
1837	    type = VAR_SUBST;
1838	    *opc = '\0';
1839	    break;
1840
1841	case '!':
1842	    type = VAR_SHELL;
1843	    *opc = '\0';
1844	    break;
1845
1846	default:
1847#ifdef SUNSHCMD
1848	    while (opc > line && *opc != ':')
1849		opc--;
1850
1851	    if (strncmp(opc, ":sh", 3) == 0) {
1852		type = VAR_SHELL;
1853		*opc = '\0';
1854		break;
1855	    }
1856#endif
1857	    type = VAR_NORMAL;
1858	    break;
1859    }
1860
1861    while (isspace ((unsigned char)*cp)) {
1862	cp++;
1863    }
1864
1865    if (type == VAR_APPEND) {
1866	Var_Append(line, cp, ctxt);
1867    } else if (type == VAR_SUBST) {
1868	/*
1869	 * Allow variables in the old value to be undefined, but leave their
1870	 * invocation alone -- this is done by forcing oldVars to be false.
1871	 * XXX: This can cause recursive variables, but that's not hard to do,
1872	 * and this allows someone to do something like
1873	 *
1874	 *  CFLAGS = $(.INCLUDES)
1875	 *  CFLAGS := -I.. $(CFLAGS)
1876	 *
1877	 * And not get an error.
1878	 */
1879	Boolean	  oldOldVars = oldVars;
1880
1881	oldVars = FALSE;
1882
1883	/*
1884	 * make sure that we set the variable the first time to nothing
1885	 * so that it gets substituted!
1886	 */
1887	if (!Var_Exists(line, ctxt))
1888	    Var_Set(line, "", ctxt, 0);
1889
1890	cp = Var_Subst(NULL, cp, ctxt, FALSE);
1891	oldVars = oldOldVars;
1892	freeCp = TRUE;
1893
1894	Var_Set(line, cp, ctxt, 0);
1895    } else if (type == VAR_SHELL) {
1896	char *res;
1897	const char *error;
1898
1899	if (strchr(cp, '$') != NULL) {
1900	    /*
1901	     * There's a dollar sign in the command, so perform variable
1902	     * expansion on the whole thing. The resulting string will need
1903	     * freeing when we're done, so set freeCmd to TRUE.
1904	     */
1905	    cp = Var_Subst(NULL, cp, VAR_CMD, TRUE);
1906	    freeCp = TRUE;
1907	}
1908
1909	res = Cmd_Exec(cp, &error);
1910	Var_Set(line, res, ctxt, 0);
1911	free(res);
1912
1913	if (error)
1914	    Parse_Error(PARSE_WARNING, error, cp);
1915    } else {
1916	/*
1917	 * Normal assignment -- just do it.
1918	 */
1919	Var_Set(line, cp, ctxt, 0);
1920    }
1921    if (strcmp(line, MAKEOVERRIDES) == 0)
1922	Main_ExportMAKEFLAGS(FALSE);	/* re-export MAKEFLAGS */
1923    else if (strcmp(line, ".CURDIR") == 0) {
1924	/*
1925	 * Somone is being (too?) clever...
1926	 * Let's pretend they know what they are doing and
1927	 * re-initialize the 'cur' Path.
1928	 */
1929	Dir_InitCur(cp);
1930	Dir_SetPATH();
1931    } else if (strcmp(line, MAKE_JOB_PREFIX) == 0) {
1932	Job_SetPrefix();
1933    } else if (strcmp(line, MAKE_EXPORTED) == 0) {
1934	Var_Export(cp, 0);
1935    }
1936    if (freeCp)
1937	free(cp);
1938}
1939
1940
1941/*-
1942 * ParseAddCmd  --
1943 *	Lst_ForEach function to add a command line to all targets
1944 *
1945 * Input:
1946 *	gnp		the node to which the command is to be added
1947 *	cmd		the command to add
1948 *
1949 * Results:
1950 *	Always 0
1951 *
1952 * Side Effects:
1953 *	A new element is added to the commands list of the node.
1954 */
1955static int
1956ParseAddCmd(void *gnp, void *cmd)
1957{
1958    GNode *gn = (GNode *)gnp;
1959
1960    /* Add to last (ie current) cohort for :: targets */
1961    if ((gn->type & OP_DOUBLEDEP) && !Lst_IsEmpty (gn->cohorts))
1962	gn = (GNode *)Lst_Datum(Lst_Last(gn->cohorts));
1963
1964    /* if target already supplied, ignore commands */
1965    if (!(gn->type & OP_HAS_COMMANDS)) {
1966	(void)Lst_AtEnd(gn->commands, cmd);
1967	ParseMark(gn);
1968    } else {
1969#ifdef notyet
1970	/* XXX: We cannot do this until we fix the tree */
1971	(void)Lst_AtEnd(gn->commands, cmd);
1972	Parse_Error(PARSE_WARNING,
1973		     "overriding commands for target \"%s\"; "
1974		     "previous commands defined at %s: %d ignored",
1975		     gn->name, gn->fname, gn->lineno);
1976#else
1977	Parse_Error(PARSE_WARNING,
1978		     "duplicate script for target \"%s\" ignored",
1979		     gn->name);
1980	ParseErrorInternal(gn->fname, gn->lineno, PARSE_WARNING,
1981			    "using previous script for \"%s\" defined here",
1982			    gn->name);
1983#endif
1984    }
1985    return(0);
1986}
1987
1988/*-
1989 *-----------------------------------------------------------------------
1990 * ParseHasCommands --
1991 *	Callback procedure for Parse_File when destroying the list of
1992 *	targets on the last dependency line. Marks a target as already
1993 *	having commands if it does, to keep from having shell commands
1994 *	on multiple dependency lines.
1995 *
1996 * Input:
1997 *	gnp		Node to examine
1998 *
1999 * Results:
2000 *	None
2001 *
2002 * Side Effects:
2003 *	OP_HAS_COMMANDS may be set for the target.
2004 *
2005 *-----------------------------------------------------------------------
2006 */
2007static void
2008ParseHasCommands(void *gnp)
2009{
2010    GNode *gn = (GNode *)gnp;
2011    if (!Lst_IsEmpty(gn->commands)) {
2012	gn->type |= OP_HAS_COMMANDS;
2013    }
2014}
2015
2016/*-
2017 *-----------------------------------------------------------------------
2018 * Parse_AddIncludeDir --
2019 *	Add a directory to the path searched for included makefiles
2020 *	bracketed by double-quotes. Used by functions in main.c
2021 *
2022 * Input:
2023 *	dir		The name of the directory to add
2024 *
2025 * Results:
2026 *	None.
2027 *
2028 * Side Effects:
2029 *	The directory is appended to the list.
2030 *
2031 *-----------------------------------------------------------------------
2032 */
2033void
2034Parse_AddIncludeDir(char *dir)
2035{
2036    (void)Dir_AddDir(parseIncPath, dir);
2037}
2038
2039/*-
2040 *---------------------------------------------------------------------
2041 * ParseDoInclude  --
2042 *	Push to another file.
2043 *
2044 *	The input is the line minus the `.'. A file spec is a string
2045 *	enclosed in <> or "". The former is looked for only in sysIncPath.
2046 *	The latter in . and the directories specified by -I command line
2047 *	options
2048 *
2049 * Results:
2050 *	None
2051 *
2052 * Side Effects:
2053 *	A structure is added to the includes Lst and readProc, lineno,
2054 *	fname and curFILE are altered for the new file
2055 *---------------------------------------------------------------------
2056 */
2057
2058static void
2059Parse_include_file(char *file, Boolean isSystem, int silent)
2060{
2061    struct loadedfile *lf;
2062    char          *fullname;	/* full pathname of file */
2063    char          *newName;
2064    char          *prefEnd, *incdir;
2065    int           fd;
2066    int           i;
2067
2068    /*
2069     * Now we know the file's name and its search path, we attempt to
2070     * find the durn thing. A return of NULL indicates the file don't
2071     * exist.
2072     */
2073    fullname = file[0] == '/' ? bmake_strdup(file) : NULL;
2074
2075    if (fullname == NULL && !isSystem) {
2076	/*
2077	 * Include files contained in double-quotes are first searched for
2078	 * relative to the including file's location. We don't want to
2079	 * cd there, of course, so we just tack on the old file's
2080	 * leading path components and call Dir_FindFile to see if
2081	 * we can locate the beast.
2082	 */
2083
2084	incdir = bmake_strdup(curFile->fname);
2085	prefEnd = strrchr(incdir, '/');
2086	if (prefEnd != NULL) {
2087	    *prefEnd = '\0';
2088	    /* Now do lexical processing of leading "../" on the filename */
2089	    for (i = 0; strncmp(file + i, "../", 3) == 0; i += 3) {
2090		prefEnd = strrchr(incdir + 1, '/');
2091		if (prefEnd == NULL || strcmp(prefEnd, "/..") == 0)
2092		    break;
2093		*prefEnd = '\0';
2094	    }
2095	    newName = str_concat(incdir, file + i, STR_ADDSLASH);
2096	    fullname = Dir_FindFile(newName, parseIncPath);
2097	    if (fullname == NULL)
2098		fullname = Dir_FindFile(newName, dirSearchPath);
2099	    free(newName);
2100	}
2101	free(incdir);
2102
2103	if (fullname == NULL) {
2104	    /*
2105    	     * Makefile wasn't found in same directory as included makefile.
2106	     * Search for it first on the -I search path,
2107	     * then on the .PATH search path, if not found in a -I directory.
2108	     * If we have a suffix specific path we should use that.
2109	     */
2110	    char *suff;
2111	    Lst	suffPath = NULL;
2112
2113	    if ((suff = strrchr(file, '.'))) {
2114		suffPath = Suff_GetPath(suff);
2115		if (suffPath != NULL) {
2116		    fullname = Dir_FindFile(file, suffPath);
2117		}
2118	    }
2119	    if (fullname == NULL) {
2120		fullname = Dir_FindFile(file, parseIncPath);
2121		if (fullname == NULL) {
2122		    fullname = Dir_FindFile(file, dirSearchPath);
2123		}
2124	    }
2125	}
2126    }
2127
2128    /* Looking for a system file or file still not found */
2129    if (fullname == NULL) {
2130	/*
2131	 * Look for it on the system path
2132	 */
2133	fullname = Dir_FindFile(file,
2134		    Lst_IsEmpty(sysIncPath) ? defIncPath : sysIncPath);
2135    }
2136
2137    if (fullname == NULL) {
2138	if (!silent)
2139	    Parse_Error(PARSE_FATAL, "Could not find %s", file);
2140	return;
2141    }
2142
2143    /* Actually open the file... */
2144    fd = open(fullname, O_RDONLY);
2145    if (fd == -1) {
2146	if (!silent)
2147	    Parse_Error(PARSE_FATAL, "Cannot open %s", fullname);
2148	free(fullname);
2149	return;
2150    }
2151
2152    /* load it */
2153    lf = loadfile(fullname, fd);
2154
2155    /* Start reading from this file next */
2156    Parse_SetInput(fullname, 0, -1, loadedfile_nextbuf, lf);
2157    curFile->lf = lf;
2158}
2159
2160static void
2161ParseDoInclude(char *line)
2162{
2163    char          endc;	    	/* the character which ends the file spec */
2164    char          *cp;		/* current position in file spec */
2165    int		  silent = (*line != 'i') ? 1 : 0;
2166    char	  *file = &line[7 + silent];
2167
2168    /* Skip to delimiter character so we know where to look */
2169    while (*file == ' ' || *file == '\t')
2170	file++;
2171
2172    if (*file != '"' && *file != '<') {
2173	Parse_Error(PARSE_FATAL,
2174	    ".include filename must be delimited by '\"' or '<'");
2175	return;
2176    }
2177
2178    /*
2179     * Set the search path on which to find the include file based on the
2180     * characters which bracket its name. Angle-brackets imply it's
2181     * a system Makefile while double-quotes imply it's a user makefile
2182     */
2183    if (*file == '<') {
2184	endc = '>';
2185    } else {
2186	endc = '"';
2187    }
2188
2189    /* Skip to matching delimiter */
2190    for (cp = ++file; *cp && *cp != endc; cp++)
2191	continue;
2192
2193    if (*cp != endc) {
2194	Parse_Error(PARSE_FATAL,
2195		     "Unclosed %cinclude filename. '%c' expected",
2196		     '.', endc);
2197	return;
2198    }
2199    *cp = '\0';
2200
2201    /*
2202     * Substitute for any variables in the file name before trying to
2203     * find the thing.
2204     */
2205    file = Var_Subst(NULL, file, VAR_CMD, FALSE);
2206
2207    Parse_include_file(file, endc == '>', silent);
2208    free(file);
2209}
2210
2211
2212/*-
2213 *---------------------------------------------------------------------
2214 * ParseSetParseFile  --
2215 *	Set the .PARSEDIR and .PARSEFILE variables to the dirname and
2216 *	basename of the given filename
2217 *
2218 * Results:
2219 *	None
2220 *
2221 * Side Effects:
2222 *	The .PARSEDIR and .PARSEFILE variables are overwritten by the
2223 *	dirname and basename of the given filename.
2224 *---------------------------------------------------------------------
2225 */
2226static void
2227ParseSetParseFile(const char *filename)
2228{
2229    char *slash, *dirname;
2230    const char *pd, *pf;
2231    int len;
2232
2233    slash = strrchr(filename, '/');
2234    if (slash == NULL) {
2235	Var_Set(".PARSEDIR", pd = curdir, VAR_GLOBAL, 0);
2236	Var_Set(".PARSEFILE", pf = filename, VAR_GLOBAL, 0);
2237	dirname= NULL;
2238    } else {
2239	len = slash - filename;
2240	dirname = bmake_malloc(len + 1);
2241	memcpy(dirname, filename, len);
2242	dirname[len] = '\0';
2243	Var_Set(".PARSEDIR", pd = dirname, VAR_GLOBAL, 0);
2244	Var_Set(".PARSEFILE", pf = slash + 1, VAR_GLOBAL, 0);
2245    }
2246    if (DEBUG(PARSE))
2247	fprintf(debug_file, "ParseSetParseFile: ${.PARSEDIR} = `%s' "
2248	    "${.PARSEFILE} = `%s'\n", pd, pf);
2249    free(dirname);
2250}
2251
2252/*
2253 * Track the makefiles we read - so makefiles can
2254 * set dependencies on them.
2255 * Avoid adding anything more than once.
2256 */
2257
2258static void
2259ParseTrackInput(const char *name)
2260{
2261    char *old;
2262    char *fp = NULL;
2263    size_t name_len = strlen(name);
2264
2265    old = Var_Value(MAKE_MAKEFILES, VAR_GLOBAL, &fp);
2266    if (old) {
2267	/* does it contain name? */
2268	for (; old != NULL; old = strchr(old, ' ')) {
2269	    if (*old == ' ')
2270		old++;
2271	    if (memcmp(old, name, name_len) == 0
2272		    && (old[name_len] == 0 || old[name_len] == ' '))
2273		goto cleanup;
2274	}
2275    }
2276    Var_Append (MAKE_MAKEFILES, name, VAR_GLOBAL);
2277 cleanup:
2278    if (fp) {
2279	free(fp);
2280    }
2281}
2282
2283
2284/*-
2285 *---------------------------------------------------------------------
2286 * Parse_setInput  --
2287 *	Start Parsing from the given source
2288 *
2289 * Results:
2290 *	None
2291 *
2292 * Side Effects:
2293 *	A structure is added to the includes Lst and readProc, lineno,
2294 *	fname and curFile are altered for the new file
2295 *---------------------------------------------------------------------
2296 */
2297void
2298Parse_SetInput(const char *name, int line, int fd,
2299	char *(*nextbuf)(void *, size_t *), void *arg)
2300{
2301    char *buf;
2302    size_t len;
2303
2304    if (name == NULL)
2305	name = curFile->fname;
2306    else
2307	ParseTrackInput(name);
2308
2309    if (DEBUG(PARSE))
2310	fprintf(debug_file, "Parse_SetInput: file %s, line %d, fd %d, nextbuf %p, arg %p\n",
2311		name, line, fd, nextbuf, arg);
2312
2313    if (fd == -1 && nextbuf == NULL)
2314	/* sanity */
2315	return;
2316
2317    if (curFile != NULL)
2318	/* Save exiting file info */
2319	Lst_AtFront(includes, curFile);
2320
2321    /* Allocate and fill in new structure */
2322    curFile = bmake_malloc(sizeof *curFile);
2323
2324    /*
2325     * Once the previous state has been saved, we can get down to reading
2326     * the new file. We set up the name of the file to be the absolute
2327     * name of the include file so error messages refer to the right
2328     * place.
2329     */
2330    curFile->fname = name;
2331    curFile->lineno = line;
2332    curFile->first_lineno = line;
2333    curFile->nextbuf = nextbuf;
2334    curFile->nextbuf_arg = arg;
2335    curFile->lf = NULL;
2336
2337    assert(nextbuf != NULL);
2338
2339    /* Get first block of input data */
2340    buf = curFile->nextbuf(curFile->nextbuf_arg, &len);
2341    if (buf == NULL) {
2342        /* Was all a waste of time ... */
2343	free(curFile);
2344	return;
2345    }
2346    curFile->P_str = buf;
2347    curFile->P_ptr = buf;
2348    curFile->P_end = buf+len;
2349
2350    curFile->cond_depth = Cond_save_depth();
2351    ParseSetParseFile(name);
2352}
2353
2354#ifdef SYSVINCLUDE
2355/*-
2356 *---------------------------------------------------------------------
2357 * ParseTraditionalInclude  --
2358 *	Push to another file.
2359 *
2360 *	The input is the current line. The file name(s) are
2361 *	following the "include".
2362 *
2363 * Results:
2364 *	None
2365 *
2366 * Side Effects:
2367 *	A structure is added to the includes Lst and readProc, lineno,
2368 *	fname and curFILE are altered for the new file
2369 *---------------------------------------------------------------------
2370 */
2371static void
2372ParseTraditionalInclude(char *line)
2373{
2374    char          *cp;		/* current position in file spec */
2375    int		   done = 0;
2376    int		   silent = (line[0] != 'i') ? 1 : 0;
2377    char	  *file = &line[silent + 7];
2378    char	  *all_files;
2379
2380    if (DEBUG(PARSE)) {
2381	    fprintf(debug_file, "ParseTraditionalInclude: %s\n", file);
2382    }
2383
2384    /*
2385     * Skip over whitespace
2386     */
2387    while (isspace((unsigned char)*file))
2388	file++;
2389
2390    /*
2391     * Substitute for any variables in the file name before trying to
2392     * find the thing.
2393     */
2394    all_files = Var_Subst(NULL, file, VAR_CMD, FALSE);
2395
2396    if (*file == '\0') {
2397	Parse_Error(PARSE_FATAL,
2398		     "Filename missing from \"include\"");
2399	return;
2400    }
2401
2402    for (file = all_files; !done; file = cp + 1) {
2403	/* Skip to end of line or next whitespace */
2404	for (cp = file; *cp && !isspace((unsigned char) *cp); cp++)
2405	    continue;
2406
2407	if (*cp)
2408	    *cp = '\0';
2409	else
2410	    done = 1;
2411
2412	Parse_include_file(file, FALSE, silent);
2413    }
2414    free(all_files);
2415}
2416#endif
2417
2418#ifdef GMAKEEXPORT
2419/*-
2420 *---------------------------------------------------------------------
2421 * ParseGmakeExport  --
2422 *	Parse export <variable>=<value>
2423 *
2424 *	And set the environment with it.
2425 *
2426 * Results:
2427 *	None
2428 *
2429 * Side Effects:
2430 *	None
2431 *---------------------------------------------------------------------
2432 */
2433static void
2434ParseGmakeExport(char *line)
2435{
2436    char	  *variable = &line[6];
2437    char	  *value;
2438
2439    if (DEBUG(PARSE)) {
2440	    fprintf(debug_file, "ParseGmakeExport: %s\n", variable);
2441    }
2442
2443    /*
2444     * Skip over whitespace
2445     */
2446    while (isspace((unsigned char)*variable))
2447	variable++;
2448
2449    for (value = variable; *value && *value != '='; value++)
2450	continue;
2451
2452    if (*value != '=') {
2453	Parse_Error(PARSE_FATAL,
2454		     "Variable/Value missing from \"export\"");
2455	return;
2456    }
2457
2458    /*
2459     * Expand the value before putting it in the environment.
2460     */
2461    value = Var_Subst(NULL, value, VAR_CMD, FALSE);
2462    setenv(variable, value, 1);
2463}
2464#endif
2465
2466/*-
2467 *---------------------------------------------------------------------
2468 * ParseEOF  --
2469 *	Called when EOF is reached in the current file. If we were reading
2470 *	an include file, the includes stack is popped and things set up
2471 *	to go back to reading the previous file at the previous location.
2472 *
2473 * Results:
2474 *	CONTINUE if there's more to do. DONE if not.
2475 *
2476 * Side Effects:
2477 *	The old curFILE, is closed. The includes list is shortened.
2478 *	lineno, curFILE, and fname are changed if CONTINUE is returned.
2479 *---------------------------------------------------------------------
2480 */
2481static int
2482ParseEOF(void)
2483{
2484    char *ptr;
2485    size_t len;
2486
2487    assert(curFile->nextbuf != NULL);
2488
2489    /* get next input buffer, if any */
2490    ptr = curFile->nextbuf(curFile->nextbuf_arg, &len);
2491    curFile->P_ptr = ptr;
2492    curFile->P_str = ptr;
2493    curFile->P_end = ptr + len;
2494    curFile->lineno = curFile->first_lineno;
2495    if (ptr != NULL) {
2496	/* Iterate again */
2497	return CONTINUE;
2498    }
2499
2500    /* Ensure the makefile (or loop) didn't have mismatched conditionals */
2501    Cond_restore_depth(curFile->cond_depth);
2502
2503    if (curFile->lf != NULL) {
2504	    loadedfile_destroy(curFile->lf);
2505	    curFile->lf = NULL;
2506    }
2507
2508    /* Dispose of curFile info */
2509    /* Leak curFile->fname because all the gnodes have pointers to it */
2510    free(curFile->P_str);
2511    free(curFile);
2512
2513    curFile = Lst_DeQueue(includes);
2514
2515    if (curFile == NULL) {
2516	/* We've run out of input */
2517	Var_Delete(".PARSEDIR", VAR_GLOBAL);
2518	Var_Delete(".PARSEFILE", VAR_GLOBAL);
2519	return DONE;
2520    }
2521
2522    if (DEBUG(PARSE))
2523	fprintf(debug_file, "ParseEOF: returning to file %s, line %d\n",
2524	    curFile->fname, curFile->lineno);
2525
2526    /* Restore the PARSEDIR/PARSEFILE variables */
2527    ParseSetParseFile(curFile->fname);
2528    return (CONTINUE);
2529}
2530
2531#define PARSE_RAW 1
2532#define PARSE_SKIP 2
2533
2534static char *
2535ParseGetLine(int flags, int *length)
2536{
2537    IFile *cf = curFile;
2538    char *ptr;
2539    char ch;
2540    char *line;
2541    char *line_end;
2542    char *escaped;
2543    char *comment;
2544    char *tp;
2545
2546    /* Loop through blank lines and comment lines */
2547    for (;;) {
2548	cf->lineno++;
2549	line = cf->P_ptr;
2550	ptr = line;
2551	line_end = line;
2552	escaped = NULL;
2553	comment = NULL;
2554	for (;;) {
2555	    if (cf->P_end != NULL && ptr == cf->P_end) {
2556		/* end of buffer */
2557		ch = 0;
2558		break;
2559	    }
2560	    ch = *ptr;
2561	    if (ch == 0 || (ch == '\\' && ptr[1] == 0)) {
2562		if (cf->P_end == NULL)
2563		    /* End of string (aka for loop) data */
2564		    break;
2565		if (cf->nextbuf != NULL) {
2566		    /*
2567		     * End of this buffer; return EOF and outer logic
2568		     * will get the next one. (eww)
2569		     */
2570		    break;
2571		}
2572		Parse_Error(PARSE_FATAL, "Zero byte read from file");
2573		return NULL;
2574	    }
2575
2576	    if (ch == '\\') {
2577		/* Don't treat next character as special, remember first one */
2578		if (escaped == NULL)
2579		    escaped = ptr;
2580		if (ptr[1] == '\n')
2581		    cf->lineno++;
2582		ptr += 2;
2583		line_end = ptr;
2584		continue;
2585	    }
2586	    if (ch == '#' && comment == NULL) {
2587		/* Remember first '#' for comment stripping */
2588		/* Unless previous char was '[', as in modifier :[#] */
2589		if (!(ptr > line && ptr[-1] == '['))
2590		    comment = line_end;
2591	    }
2592	    ptr++;
2593	    if (ch == '\n')
2594		break;
2595	    if (!isspace((unsigned char)ch))
2596		/* We are not interested in trailing whitespace */
2597		line_end = ptr;
2598	}
2599
2600	/* Save next 'to be processed' location */
2601	cf->P_ptr = ptr;
2602
2603	/* Check we have a non-comment, non-blank line */
2604	if (line_end == line || comment == line) {
2605	    if (ch == 0)
2606		/* At end of file */
2607		return NULL;
2608	    /* Parse another line */
2609	    continue;
2610	}
2611
2612	/* We now have a line of data */
2613	*line_end = 0;
2614
2615	if (flags & PARSE_RAW) {
2616	    /* Leave '\' (etc) in line buffer (eg 'for' lines) */
2617	    *length = line_end - line;
2618	    return line;
2619	}
2620
2621	if (flags & PARSE_SKIP) {
2622	    /* Completely ignore non-directives */
2623	    if (line[0] != '.')
2624		continue;
2625	    /* We could do more of the .else/.elif/.endif checks here */
2626	}
2627	break;
2628    }
2629
2630    /* Brutally ignore anything after a non-escaped '#' in non-commands */
2631    if (comment != NULL && line[0] != '\t') {
2632	line_end = comment;
2633	*line_end = 0;
2634    }
2635
2636    /* If we didn't see a '\\' then the in-situ data is fine */
2637    if (escaped == NULL) {
2638	*length = line_end - line;
2639	return line;
2640    }
2641
2642    /* Remove escapes from '\n' and '#' */
2643    tp = ptr = escaped;
2644    escaped = line;
2645    for (; ; *tp++ = ch) {
2646	ch = *ptr++;
2647	if (ch != '\\') {
2648	    if (ch == 0)
2649		break;
2650	    continue;
2651	}
2652
2653	ch = *ptr++;
2654	if (ch == 0) {
2655	    /* Delete '\\' at end of buffer */
2656	    tp--;
2657	    break;
2658	}
2659
2660	if (ch == '#' && line[0] != '\t')
2661	    /* Delete '\\' from before '#' on non-command lines */
2662	    continue;
2663
2664	if (ch != '\n') {
2665	    /* Leave '\\' in buffer for later */
2666	    *tp++ = '\\';
2667	    /* Make sure we don't delete an escaped ' ' from the line end */
2668	    escaped = tp + 1;
2669	    continue;
2670	}
2671
2672	/* Escaped '\n' replace following whitespace with a single ' ' */
2673	while (ptr[0] == ' ' || ptr[0] == '\t')
2674	    ptr++;
2675	ch = ' ';
2676    }
2677
2678    /* Delete any trailing spaces - eg from empty continuations */
2679    while (tp > escaped && isspace((unsigned char)tp[-1]))
2680	tp--;
2681
2682    *tp = 0;
2683    *length = tp - line;
2684    return line;
2685}
2686
2687/*-
2688 *---------------------------------------------------------------------
2689 * ParseReadLine --
2690 *	Read an entire line from the input file. Called only by Parse_File.
2691 *
2692 * Results:
2693 *	A line w/o its newline
2694 *
2695 * Side Effects:
2696 *	Only those associated with reading a character
2697 *---------------------------------------------------------------------
2698 */
2699static char *
2700ParseReadLine(void)
2701{
2702    char 	  *line;    	/* Result */
2703    int	    	  lineLength;	/* Length of result */
2704    int	    	  lineno;	/* Saved line # */
2705    int	    	  rval;
2706
2707    for (;;) {
2708	line = ParseGetLine(0, &lineLength);
2709	if (line == NULL)
2710	    return NULL;
2711
2712	if (line[0] != '.')
2713	    return line;
2714
2715	/*
2716	 * The line might be a conditional. Ask the conditional module
2717	 * about it and act accordingly
2718	 */
2719	switch (Cond_Eval(line)) {
2720	case COND_SKIP:
2721	    /* Skip to next conditional that evaluates to COND_PARSE.  */
2722	    do {
2723		line = ParseGetLine(PARSE_SKIP, &lineLength);
2724	    } while (line && Cond_Eval(line) != COND_PARSE);
2725	    if (line == NULL)
2726		break;
2727	    continue;
2728	case COND_PARSE:
2729	    continue;
2730	case COND_INVALID:    /* Not a conditional line */
2731	    /* Check for .for loops */
2732	    rval = For_Eval(line);
2733	    if (rval == 0)
2734		/* Not a .for line */
2735		break;
2736	    if (rval < 0)
2737		/* Syntax error - error printed, ignore line */
2738		continue;
2739	    /* Start of a .for loop */
2740	    lineno = curFile->lineno;
2741	    /* Accumulate loop lines until matching .endfor */
2742	    do {
2743		line = ParseGetLine(PARSE_RAW, &lineLength);
2744		if (line == NULL) {
2745		    Parse_Error(PARSE_FATAL,
2746			     "Unexpected end of file in for loop.");
2747		    break;
2748		}
2749	    } while (For_Accum(line));
2750	    /* Stash each iteration as a new 'input file' */
2751	    For_Run(lineno);
2752	    /* Read next line from for-loop buffer */
2753	    continue;
2754	}
2755	return (line);
2756    }
2757}
2758
2759/*-
2760 *-----------------------------------------------------------------------
2761 * ParseFinishLine --
2762 *	Handle the end of a dependency group.
2763 *
2764 * Results:
2765 *	Nothing.
2766 *
2767 * Side Effects:
2768 *	inLine set FALSE. 'targets' list destroyed.
2769 *
2770 *-----------------------------------------------------------------------
2771 */
2772static void
2773ParseFinishLine(void)
2774{
2775    if (inLine) {
2776	Lst_ForEach(targets, Suff_EndTransform, NULL);
2777	Lst_Destroy(targets, ParseHasCommands);
2778	targets = NULL;
2779	inLine = FALSE;
2780    }
2781}
2782
2783
2784/*-
2785 *---------------------------------------------------------------------
2786 * Parse_File --
2787 *	Parse a file into its component parts, incorporating it into the
2788 *	current dependency graph. This is the main function and controls
2789 *	almost every other function in this module
2790 *
2791 * Input:
2792 *	name		the name of the file being read
2793 *	fd		Open file to makefile to parse
2794 *
2795 * Results:
2796 *	None
2797 *
2798 * Side Effects:
2799 *	closes fd.
2800 *	Loads. Nodes are added to the list of all targets, nodes and links
2801 *	are added to the dependency graph. etc. etc. etc.
2802 *---------------------------------------------------------------------
2803 */
2804void
2805Parse_File(const char *name, int fd)
2806{
2807    char	  *cp;		/* pointer into the line */
2808    char          *line;	/* the line we're working on */
2809    struct loadedfile *lf;
2810
2811    lf = loadfile(name, fd);
2812
2813    inLine = FALSE;
2814    fatals = 0;
2815
2816    if (name == NULL) {
2817	    name = "(stdin)";
2818    }
2819
2820    Parse_SetInput(name, 0, -1, loadedfile_nextbuf, lf);
2821    curFile->lf = lf;
2822
2823    do {
2824	for (; (line = ParseReadLine()) != NULL; ) {
2825	    if (DEBUG(PARSE))
2826		fprintf(debug_file, "ParseReadLine (%d): '%s'\n",
2827			curFile->lineno, line);
2828	    if (*line == '.') {
2829		/*
2830		 * Lines that begin with the special character may be
2831		 * include or undef directives.
2832		 * On the other hand they can be suffix rules (.c.o: ...)
2833		 * or just dependencies for filenames that start '.'.
2834		 */
2835		for (cp = line + 1; isspace((unsigned char)*cp); cp++) {
2836		    continue;
2837		}
2838		if (strncmp(cp, "include", 7) == 0 ||
2839			((cp[0] == 's' || cp[0] == '-') &&
2840			    strncmp(&cp[1], "include", 7) == 0)) {
2841		    ParseDoInclude(cp);
2842		    continue;
2843		}
2844		if (strncmp(cp, "undef", 5) == 0) {
2845		    char *cp2;
2846		    for (cp += 5; isspace((unsigned char) *cp); cp++)
2847			continue;
2848		    for (cp2 = cp; !isspace((unsigned char) *cp2) &&
2849				   (*cp2 != '\0'); cp2++)
2850			continue;
2851		    *cp2 = '\0';
2852		    Var_Delete(cp, VAR_GLOBAL);
2853		    continue;
2854		} else if (strncmp(cp, "export", 6) == 0) {
2855		    for (cp += 6; isspace((unsigned char) *cp); cp++)
2856			continue;
2857		    Var_Export(cp, 1);
2858		    continue;
2859		} else if (strncmp(cp, "unexport", 8) == 0) {
2860		    Var_UnExport(cp);
2861		    continue;
2862		} else if (strncmp(cp, "info", 4) == 0 ||
2863			   strncmp(cp, "error", 5) == 0 ||
2864			   strncmp(cp, "warning", 7) == 0) {
2865		    if (ParseMessage(cp))
2866			continue;
2867		}
2868	    }
2869
2870	    if (*line == '\t') {
2871		/*
2872		 * If a line starts with a tab, it can only hope to be
2873		 * a creation command.
2874		 */
2875		cp = line + 1;
2876	      shellCommand:
2877		for (; isspace ((unsigned char)*cp); cp++) {
2878		    continue;
2879		}
2880		if (*cp) {
2881		    if (!inLine)
2882			Parse_Error(PARSE_FATAL,
2883				     "Unassociated shell command \"%s\"",
2884				     cp);
2885		    /*
2886		     * So long as it's not a blank line and we're actually
2887		     * in a dependency spec, add the command to the list of
2888		     * commands of all targets in the dependency spec
2889		     */
2890		    if (targets) {
2891			cp = bmake_strdup(cp);
2892			Lst_ForEach(targets, ParseAddCmd, cp);
2893#ifdef CLEANUP
2894			Lst_AtEnd(targCmds, cp);
2895#endif
2896		    }
2897		}
2898		continue;
2899	    }
2900
2901#ifdef SYSVINCLUDE
2902	    if (((strncmp(line, "include", 7) == 0 &&
2903		    isspace((unsigned char) line[7])) ||
2904			((line[0] == 's' || line[0] == '-') &&
2905			    strncmp(&line[1], "include", 7) == 0 &&
2906			    isspace((unsigned char) line[8]))) &&
2907		    strchr(line, ':') == NULL) {
2908		/*
2909		 * It's an S3/S5-style "include".
2910		 */
2911		ParseTraditionalInclude(line);
2912		continue;
2913	    }
2914#endif
2915#ifdef GMAKEEXPORT
2916	    if (strncmp(line, "export", 6) == 0 &&
2917		isspace((unsigned char) line[6]) &&
2918		strchr(line, ':') == NULL) {
2919		/*
2920		 * It's a Gmake "export".
2921		 */
2922		ParseGmakeExport(line);
2923		continue;
2924	    }
2925#endif
2926	    if (Parse_IsVar(line)) {
2927		ParseFinishLine();
2928		Parse_DoVar(line, VAR_GLOBAL);
2929		continue;
2930	    }
2931
2932#ifndef POSIX
2933	    /*
2934	     * To make life easier on novices, if the line is indented we
2935	     * first make sure the line has a dependency operator in it.
2936	     * If it doesn't have an operator and we're in a dependency
2937	     * line's script, we assume it's actually a shell command
2938	     * and add it to the current list of targets.
2939	     */
2940	    cp = line;
2941	    if (isspace((unsigned char) line[0])) {
2942		while ((*cp != '\0') && isspace((unsigned char) *cp))
2943		    cp++;
2944		while (*cp && (ParseIsEscaped(line, cp) ||
2945			(*cp != ':') && (*cp != '!'))) {
2946		    cp++;
2947		}
2948		if (*cp == '\0') {
2949		    if (inLine) {
2950			Parse_Error(PARSE_WARNING,
2951				     "Shell command needs a leading tab");
2952			goto shellCommand;
2953		    }
2954		}
2955	    }
2956#endif
2957	    ParseFinishLine();
2958
2959	    /*
2960	     * For some reason - probably to make the parser impossible -
2961	     * a ';' can be used to separate commands from dependencies.
2962	     * Attempt to avoid ';' inside substitution patterns.
2963	     */
2964	    {
2965		int level = 0;
2966
2967		for (cp = line; *cp != 0; cp++) {
2968		    if (*cp == '\\' && cp[1] != 0) {
2969			cp++;
2970			continue;
2971		    }
2972		    if (*cp == '$' &&
2973			(cp[1] == '(' || cp[1] == '{')) {
2974			level++;
2975			continue;
2976		    }
2977		    if (level > 0) {
2978			if (*cp == ')' || *cp == '}') {
2979			    level--;
2980			    continue;
2981			}
2982		    } else if (*cp == ';') {
2983			break;
2984		    }
2985		}
2986	    }
2987	    if (*cp != 0)
2988		/* Terminate the dependency list at the ';' */
2989		*cp++ = 0;
2990	    else
2991		cp = NULL;
2992
2993	    /*
2994	     * We now know it's a dependency line so it needs to have all
2995	     * variables expanded before being parsed. Tell the variable
2996	     * module to complain if some variable is undefined...
2997	     */
2998	    line = Var_Subst(NULL, line, VAR_CMD, TRUE);
2999
3000	    /*
3001	     * Need a non-circular list for the target nodes
3002	     */
3003	    if (targets)
3004		Lst_Destroy(targets, NULL);
3005
3006	    targets = Lst_Init(FALSE);
3007	    inLine = TRUE;
3008
3009	    ParseDoDependency(line);
3010	    free(line);
3011
3012	    /* If there were commands after a ';', add them now */
3013	    if (cp != NULL) {
3014		goto shellCommand;
3015	    }
3016	}
3017	/*
3018	 * Reached EOF, but it may be just EOF of an include file...
3019	 */
3020    } while (ParseEOF() == CONTINUE);
3021
3022    if (fatals) {
3023	(void)fflush(stdout);
3024	(void)fprintf(stderr,
3025	    "%s: Fatal errors encountered -- cannot continue",
3026	    progname);
3027	PrintOnError(NULL, NULL);
3028	exit(1);
3029    }
3030}
3031
3032/*-
3033 *---------------------------------------------------------------------
3034 * Parse_Init --
3035 *	initialize the parsing module
3036 *
3037 * Results:
3038 *	none
3039 *
3040 * Side Effects:
3041 *	the parseIncPath list is initialized...
3042 *---------------------------------------------------------------------
3043 */
3044void
3045Parse_Init(void)
3046{
3047    mainNode = NULL;
3048    parseIncPath = Lst_Init(FALSE);
3049    sysIncPath = Lst_Init(FALSE);
3050    defIncPath = Lst_Init(FALSE);
3051    includes = Lst_Init(FALSE);
3052#ifdef CLEANUP
3053    targCmds = Lst_Init(FALSE);
3054#endif
3055}
3056
3057void
3058Parse_End(void)
3059{
3060#ifdef CLEANUP
3061    Lst_Destroy(targCmds, (FreeProc *)free);
3062    if (targets)
3063	Lst_Destroy(targets, NULL);
3064    Lst_Destroy(defIncPath, Dir_Destroy);
3065    Lst_Destroy(sysIncPath, Dir_Destroy);
3066    Lst_Destroy(parseIncPath, Dir_Destroy);
3067    Lst_Destroy(includes, NULL);	/* Should be empty now */
3068#endif
3069}
3070
3071
3072/*-
3073 *-----------------------------------------------------------------------
3074 * Parse_MainName --
3075 *	Return a Lst of the main target to create for main()'s sake. If
3076 *	no such target exists, we Punt with an obnoxious error message.
3077 *
3078 * Results:
3079 *	A Lst of the single node to create.
3080 *
3081 * Side Effects:
3082 *	None.
3083 *
3084 *-----------------------------------------------------------------------
3085 */
3086Lst
3087Parse_MainName(void)
3088{
3089    Lst           mainList;	/* result list */
3090
3091    mainList = Lst_Init(FALSE);
3092
3093    if (mainNode == NULL) {
3094	Punt("no target to make.");
3095    	/*NOTREACHED*/
3096    } else if (mainNode->type & OP_DOUBLEDEP) {
3097	(void)Lst_AtEnd(mainList, mainNode);
3098	Lst_Concat(mainList, mainNode->cohorts, LST_CONCNEW);
3099    }
3100    else
3101	(void)Lst_AtEnd(mainList, mainNode);
3102    Var_Append(".TARGETS", mainNode->name, VAR_GLOBAL);
3103    return (mainList);
3104}
3105
3106/*-
3107 *-----------------------------------------------------------------------
3108 * ParseMark --
3109 *	Add the filename and lineno to the GNode so that we remember
3110 *	where it was first defined.
3111 *
3112 * Side Effects:
3113 *	None.
3114 *
3115 *-----------------------------------------------------------------------
3116 */
3117static void
3118ParseMark(GNode *gn)
3119{
3120    gn->fname = curFile->fname;
3121    gn->lineno = curFile->lineno;
3122}
3123