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