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