]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/bmake/parse.c
ssh: Update to OpenSSH 9.3p1
[FreeBSD/FreeBSD.git] / contrib / bmake / parse.c
1 /*      $NetBSD: parse.c,v 1.692 2023/01/24 00:24:02 sjg Exp $  */
2
3 /*
4  * Copyright (c) 1988, 1989, 1990, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Adam de Boor.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34
35 /*
36  * Copyright (c) 1989 by Berkeley Softworks
37  * All rights reserved.
38  *
39  * This code is derived from software contributed to Berkeley by
40  * Adam de Boor.
41  *
42  * Redistribution and use in source and binary forms, with or without
43  * modification, are permitted provided that the following conditions
44  * are met:
45  * 1. Redistributions of source code must retain the above copyright
46  *    notice, this list of conditions and the following disclaimer.
47  * 2. Redistributions in binary form must reproduce the above copyright
48  *    notice, this list of conditions and the following disclaimer in the
49  *    documentation and/or other materials provided with the distribution.
50  * 3. All advertising materials mentioning features or use of this software
51  *    must display the following acknowledgement:
52  *      This product includes software developed by the University of
53  *      California, Berkeley and its contributors.
54  * 4. Neither the name of the University nor the names of its contributors
55  *    may be used to endorse or promote products derived from this software
56  *    without specific prior written permission.
57  *
58  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68  * SUCH DAMAGE.
69  */
70
71 /*
72  * Parsing of makefiles.
73  *
74  * Parse_File is the main entry point and controls most of the other
75  * functions in this module.
76  *
77  * Interface:
78  *      Parse_Init      Initialize the module
79  *
80  *      Parse_End       Clean up the module
81  *
82  *      Parse_File      Parse a top-level makefile.  Included files are
83  *                      handled by IncludeFile instead.
84  *
85  *      Parse_VarAssign
86  *                      Try to parse the given line as a variable assignment.
87  *                      Used by MainParseArgs to determine if an argument is
88  *                      a target or a variable assignment.  Used internally
89  *                      for pretty much the same thing.
90  *
91  *      Parse_Error     Report a parse error, a warning or an informational
92  *                      message.
93  *
94  *      Parse_MainName  Returns a list of the single main target to create.
95  */
96
97 #include <sys/types.h>
98 #include <sys/stat.h>
99 #include <errno.h>
100 #include <stdarg.h>
101
102 #include "make.h"
103
104 #ifdef HAVE_STDINT_H
105 #include <stdint.h>
106 #endif
107
108 #ifdef HAVE_MMAP
109 #include <sys/mman.h>
110
111 #ifndef MAP_COPY
112 #define MAP_COPY MAP_PRIVATE
113 #endif
114 #ifndef MAP_FILE
115 #define MAP_FILE 0
116 #endif
117 #endif
118
119 #include "dir.h"
120 #include "job.h"
121 #include "pathnames.h"
122
123 /*      "@(#)parse.c    8.3 (Berkeley) 3/19/94" */
124 MAKE_RCSID("$NetBSD: parse.c,v 1.692 2023/01/24 00:24:02 sjg Exp $");
125
126 /*
127  * A file being read.
128  */
129 typedef struct IncludedFile {
130         FStr name;              /* absolute or relative to the cwd */
131         unsigned lineno;        /* 1-based */
132         unsigned readLines;     /* the number of physical lines that have
133                                  * been read from the file */
134         unsigned forHeadLineno; /* 1-based */
135         unsigned forBodyReadLines; /* the number of physical lines that have
136                                  * been read from the file above the body of
137                                  * the .for loop */
138         unsigned int condMinDepth; /* depth of nested 'if' directives, at the
139                                  * beginning of the file */
140         bool depending;         /* state of doing_depend on EOF */
141
142         Buffer buf;             /* the file's content or the body of the .for
143                                  * loop; either empty or ends with '\n' */
144         char *buf_ptr;          /* next char to be read */
145         char *buf_end;          /* buf_end[-1] == '\n' */
146
147         struct ForLoop *forLoop;
148 } IncludedFile;
149
150 /* Special attributes for target nodes. */
151 typedef enum ParseSpecial {
152         SP_ATTRIBUTE,   /* Generic attribute */
153         SP_BEGIN,       /* .BEGIN */
154         SP_DEFAULT,     /* .DEFAULT */
155         SP_DELETE_ON_ERROR, /* .DELETE_ON_ERROR */
156         SP_END,         /* .END */
157         SP_ERROR,       /* .ERROR */
158         SP_IGNORE,      /* .IGNORE */
159         SP_INCLUDES,    /* .INCLUDES; not mentioned in the manual page */
160         SP_INTERRUPT,   /* .INTERRUPT */
161         SP_LIBS,        /* .LIBS; not mentioned in the manual page */
162         SP_MAIN,        /* .MAIN and no user-specified targets to make */
163         SP_META,        /* .META */
164         SP_MFLAGS,      /* .MFLAGS or .MAKEFLAGS */
165         SP_NOMETA,      /* .NOMETA */
166         SP_NOMETA_CMP,  /* .NOMETA_CMP */
167         SP_NOPATH,      /* .NOPATH */
168         SP_NOREADONLY,  /* .NOREADONLY */
169         SP_NOT,         /* Not special */
170         SP_NOTPARALLEL, /* .NOTPARALLEL or .NO_PARALLEL */
171         SP_NULL,        /* .NULL; not mentioned in the manual page */
172         SP_OBJDIR,      /* .OBJDIR */
173         SP_ORDER,       /* .ORDER */
174         SP_PARALLEL,    /* .PARALLEL; not mentioned in the manual page */
175         SP_PATH,        /* .PATH or .PATH.suffix */
176         SP_PHONY,       /* .PHONY */
177 #ifdef POSIX
178         SP_POSIX,       /* .POSIX; not mentioned in the manual page */
179 #endif
180         SP_PRECIOUS,    /* .PRECIOUS */
181         SP_READONLY,    /* .READONLY */
182         SP_SHELL,       /* .SHELL */
183         SP_SILENT,      /* .SILENT */
184         SP_SINGLESHELL, /* .SINGLESHELL; not mentioned in the manual page */
185         SP_STALE,       /* .STALE */
186         SP_SUFFIXES,    /* .SUFFIXES */
187         SP_SYSPATH,     /* .SYSPATH */
188         SP_WAIT         /* .WAIT */
189 } ParseSpecial;
190
191 typedef List SearchPathList;
192 typedef ListNode SearchPathListNode;
193
194
195 typedef enum VarAssignOp {
196         VAR_NORMAL,             /* = */
197         VAR_APPEND,             /* += */
198         VAR_DEFAULT,            /* ?= */
199         VAR_SUBST,              /* := */
200         VAR_SHELL               /* != or :sh= */
201 } VarAssignOp;
202
203 typedef struct VarAssign {
204         char *varname;          /* unexpanded */
205         VarAssignOp op;
206         const char *value;      /* unexpanded */
207 } VarAssign;
208
209 static bool Parse_IsVar(const char *, VarAssign *);
210 static void Parse_Var(VarAssign *, GNode *);
211
212 /*
213  * The target to be made if no targets are specified in the command line.
214  * This is the first target defined in any of the makefiles.
215  */
216 GNode *mainNode;
217
218 /*
219  * During parsing, the targets from the left-hand side of the currently
220  * active dependency line, or NULL if the current line does not belong to a
221  * dependency line, for example because it is a variable assignment.
222  *
223  * See unit-tests/deptgt.mk, keyword "parse.c:targets".
224  */
225 static GNodeList *targets;
226
227 #ifdef CLEANUP
228 /*
229  * All shell commands for all targets, in no particular order and possibly
230  * with duplicates.  Kept in a separate list since the commands from .USE or
231  * .USEBEFORE nodes are shared with other GNodes, thereby giving up the
232  * easily understandable ownership over the allocated strings.
233  */
234 static StringList targCmds = LST_INIT;
235 #endif
236
237 /*
238  * Predecessor node for handling .ORDER. Initialized to NULL when .ORDER
239  * is seen, then set to each successive source on the line.
240  */
241 static GNode *order_pred;
242
243 static int parseErrors = 0;
244
245 /*
246  * The include chain of makefiles.  At index 0 is the top-level makefile from
247  * the command line, followed by the included files or .for loops, up to and
248  * including the current file.
249  *
250  * See PrintStackTrace for how to interpret the data.
251  */
252 static Vector /* of IncludedFile */ includes;
253
254 SearchPath *parseIncPath;       /* directories for "..." includes */
255 SearchPath *sysIncPath;         /* directories for <...> includes */
256 SearchPath *defSysIncPath;      /* default for sysIncPath */
257
258 /*
259  * The parseKeywords table is searched using binary search when deciding
260  * if a target or source is special. The 'spec' field is the ParseSpecial
261  * type of the keyword (SP_NOT if the keyword isn't special as a target) while
262  * the 'op' field is the operator to apply to the list of targets if the
263  * keyword is used as a source ("0" if the keyword isn't special as a source)
264  */
265 static const struct {
266         const char name[17];
267         ParseSpecial special;   /* when used as a target */
268         GNodeType targetAttr;   /* when used as a source */
269 } parseKeywords[] = {
270     { ".BEGIN",         SP_BEGIN,       OP_NONE },
271     { ".DEFAULT",       SP_DEFAULT,     OP_NONE },
272     { ".DELETE_ON_ERROR", SP_DELETE_ON_ERROR, OP_NONE },
273     { ".END",           SP_END,         OP_NONE },
274     { ".ERROR",         SP_ERROR,       OP_NONE },
275     { ".EXEC",          SP_ATTRIBUTE,   OP_EXEC },
276     { ".IGNORE",        SP_IGNORE,      OP_IGNORE },
277     { ".INCLUDES",      SP_INCLUDES,    OP_NONE },
278     { ".INTERRUPT",     SP_INTERRUPT,   OP_NONE },
279     { ".INVISIBLE",     SP_ATTRIBUTE,   OP_INVISIBLE },
280     { ".JOIN",          SP_ATTRIBUTE,   OP_JOIN },
281     { ".LIBS",          SP_LIBS,        OP_NONE },
282     { ".MADE",          SP_ATTRIBUTE,   OP_MADE },
283     { ".MAIN",          SP_MAIN,        OP_NONE },
284     { ".MAKE",          SP_ATTRIBUTE,   OP_MAKE },
285     { ".MAKEFLAGS",     SP_MFLAGS,      OP_NONE },
286     { ".META",          SP_META,        OP_META },
287     { ".MFLAGS",        SP_MFLAGS,      OP_NONE },
288     { ".NOMETA",        SP_NOMETA,      OP_NOMETA },
289     { ".NOMETA_CMP",    SP_NOMETA_CMP,  OP_NOMETA_CMP },
290     { ".NOPATH",        SP_NOPATH,      OP_NOPATH },
291     { ".NOREADONLY",    SP_NOREADONLY,  OP_NONE },
292     { ".NOTMAIN",       SP_ATTRIBUTE,   OP_NOTMAIN },
293     { ".NOTPARALLEL",   SP_NOTPARALLEL, OP_NONE },
294     { ".NO_PARALLEL",   SP_NOTPARALLEL, OP_NONE },
295     { ".NULL",          SP_NULL,        OP_NONE },
296     { ".OBJDIR",        SP_OBJDIR,      OP_NONE },
297     { ".OPTIONAL",      SP_ATTRIBUTE,   OP_OPTIONAL },
298     { ".ORDER",         SP_ORDER,       OP_NONE },
299     { ".PARALLEL",      SP_PARALLEL,    OP_NONE },
300     { ".PATH",          SP_PATH,        OP_NONE },
301     { ".PHONY",         SP_PHONY,       OP_PHONY },
302 #ifdef POSIX
303     { ".POSIX",         SP_POSIX,       OP_NONE },
304 #endif
305     { ".PRECIOUS",      SP_PRECIOUS,    OP_PRECIOUS },
306     { ".READONLY",      SP_READONLY,    OP_NONE },
307     { ".RECURSIVE",     SP_ATTRIBUTE,   OP_MAKE },
308     { ".SHELL",         SP_SHELL,       OP_NONE },
309     { ".SILENT",        SP_SILENT,      OP_SILENT },
310     { ".SINGLESHELL",   SP_SINGLESHELL, OP_NONE },
311     { ".STALE",         SP_STALE,       OP_NONE },
312     { ".SUFFIXES",      SP_SUFFIXES,    OP_NONE },
313     { ".SYSPATH",       SP_SYSPATH,     OP_NONE },
314     { ".USE",           SP_ATTRIBUTE,   OP_USE },
315     { ".USEBEFORE",     SP_ATTRIBUTE,   OP_USEBEFORE },
316     { ".WAIT",          SP_WAIT,        OP_NONE },
317 };
318
319 enum PosixState posix_state = PS_NOT_YET;
320
321 static IncludedFile *
322 GetInclude(size_t i)
323 {
324         assert(i < includes.len);
325         return Vector_Get(&includes, i);
326 }
327
328 /* The file that is currently being read. */
329 static IncludedFile *
330 CurFile(void)
331 {
332         return GetInclude(includes.len - 1);
333 }
334
335 unsigned int
336 CurFile_CondMinDepth(void)
337 {
338         return CurFile()->condMinDepth;
339 }
340
341 static Buffer
342 LoadFile(const char *path, int fd)
343 {
344         ssize_t n;
345         Buffer buf;
346         size_t bufSize;
347         struct stat st;
348
349         bufSize = fstat(fd, &st) == 0 && S_ISREG(st.st_mode) &&
350                   st.st_size > 0 && st.st_size < 1024 * 1024 * 1024
351             ? (size_t)st.st_size : 1024;
352         Buf_InitSize(&buf, bufSize);
353
354         for (;;) {
355                 if (buf.len == buf.cap) {
356                         if (buf.cap >= 512 * 1024 * 1024) {
357                                 Error("%s: file too large", path);
358                                 exit(2); /* Not 1 so -q can distinguish error */
359                         }
360                         Buf_Expand(&buf);
361                 }
362                 assert(buf.len < buf.cap);
363                 n = read(fd, buf.data + buf.len, buf.cap - buf.len);
364                 if (n < 0) {
365                         Error("%s: read error: %s", path, strerror(errno));
366                         exit(2);        /* Not 1 so -q can distinguish error */
367                 }
368                 if (n == 0)
369                         break;
370
371                 buf.len += (size_t)n;
372         }
373         assert(buf.len <= buf.cap);
374
375         if (!Buf_EndsWith(&buf, '\n'))
376                 Buf_AddByte(&buf, '\n');
377
378         return buf;             /* may not be null-terminated */
379 }
380
381 /*
382  * Print the current chain of .include and .for directives.  In Parse_Fatal
383  * or other functions that already print the location, includingInnermost
384  * would be redundant, but in other cases like Error or Fatal it needs to be
385  * included.
386  */
387 void
388 PrintStackTrace(bool includingInnermost)
389 {
390         const IncludedFile *entries;
391         size_t i, n;
392
393         n = includes.len;
394         if (n == 0)
395                 return;
396
397         entries = GetInclude(0);
398         if (!includingInnermost && entries[n - 1].forLoop == NULL)
399                 n--;            /* already in the diagnostic */
400
401         for (i = n; i-- > 0;) {
402                 const IncludedFile *entry = entries + i;
403                 const char *fname = entry->name.str;
404                 char dirbuf[MAXPATHLEN + 1];
405
406                 if (fname[0] != '/' && strcmp(fname, "(stdin)") != 0)
407                         fname = realpath(fname, dirbuf);
408
409                 if (entry->forLoop != NULL) {
410                         char *details = ForLoop_Details(entry->forLoop);
411                         debug_printf("\tin .for loop from %s:%u with %s\n",
412                             fname, entry->forHeadLineno, details);
413                         free(details);
414                 } else if (i + 1 < n && entries[i + 1].forLoop != NULL) {
415                         /* entry->lineno is not a useful line number */
416                 } else
417                         debug_printf("\tin %s:%u\n", fname, entry->lineno);
418         }
419 }
420
421 /* Check if the current character is escaped on the current line. */
422 static bool
423 IsEscaped(const char *line, const char *p)
424 {
425         bool escaped = false;
426         while (p > line && *--p == '\\')
427                 escaped = !escaped;
428         return escaped;
429 }
430
431 /*
432  * Add the filename and lineno to the GNode so that we remember where it
433  * was first defined.
434  */
435 static void
436 RememberLocation(GNode *gn)
437 {
438         IncludedFile *curFile = CurFile();
439         gn->fname = Str_Intern(curFile->name.str);
440         gn->lineno = curFile->lineno;
441 }
442
443 /*
444  * Look in the table of keywords for one matching the given string.
445  * Return the index of the keyword, or -1 if it isn't there.
446  */
447 static int
448 FindKeyword(const char *str)
449 {
450         int start = 0;
451         int end = sizeof parseKeywords / sizeof parseKeywords[0] - 1;
452
453         while (start <= end) {
454                 int curr = start + (end - start) / 2;
455                 int diff = strcmp(str, parseKeywords[curr].name);
456
457                 if (diff == 0)
458                         return curr;
459                 if (diff < 0)
460                         end = curr - 1;
461                 else
462                         start = curr + 1;
463         }
464
465         return -1;
466 }
467
468 void
469 PrintLocation(FILE *f, bool useVars, const GNode *gn)
470 {
471         char dirbuf[MAXPATHLEN + 1];
472         FStr dir, base;
473         const char *fname;
474         unsigned lineno;
475
476         if (gn != NULL) {
477                 fname = gn->fname;
478                 lineno = gn->lineno;
479         } else if (includes.len > 0) {
480                 IncludedFile *curFile = CurFile();
481                 fname = curFile->name.str;
482                 lineno = curFile->lineno;
483         } else
484                 return;
485
486         if (!useVars || fname[0] == '/' || strcmp(fname, "(stdin)") == 0) {
487                 (void)fprintf(f, "\"%s\" line %u: ", fname, lineno);
488                 return;
489         }
490
491         dir = Var_Value(SCOPE_GLOBAL, ".PARSEDIR");
492         if (dir.str == NULL)
493                 dir.str = ".";
494         if (dir.str[0] != '/')
495                 dir.str = realpath(dir.str, dirbuf);
496
497         base = Var_Value(SCOPE_GLOBAL, ".PARSEFILE");
498         if (base.str == NULL)
499                 base.str = str_basename(fname);
500
501         (void)fprintf(f, "\"%s/%s\" line %u: ", dir.str, base.str, lineno);
502
503         FStr_Done(&base);
504         FStr_Done(&dir);
505 }
506
507 static void MAKE_ATTR_PRINTFLIKE(5, 0)
508 ParseVErrorInternal(FILE *f, bool useVars, const GNode *gn,
509                     ParseErrorLevel level, const char *fmt, va_list ap)
510 {
511         static bool fatal_warning_error_printed = false;
512
513         (void)fprintf(f, "%s: ", progname);
514
515         PrintLocation(f, useVars, gn);
516         if (level == PARSE_WARNING)
517                 (void)fprintf(f, "warning: ");
518         (void)vfprintf(f, fmt, ap);
519         (void)fprintf(f, "\n");
520         (void)fflush(f);
521
522         if (level == PARSE_FATAL)
523                 parseErrors++;
524         if (level == PARSE_WARNING && opts.parseWarnFatal) {
525                 if (!fatal_warning_error_printed) {
526                         Error("parsing warnings being treated as errors");
527                         fatal_warning_error_printed = true;
528                 }
529                 parseErrors++;
530         }
531
532         if (DEBUG(PARSE))
533                 PrintStackTrace(false);
534 }
535
536 static void MAKE_ATTR_PRINTFLIKE(3, 4)
537 ParseErrorInternal(const GNode *gn,
538                    ParseErrorLevel level, const char *fmt, ...)
539 {
540         va_list ap;
541
542         (void)fflush(stdout);
543         va_start(ap, fmt);
544         ParseVErrorInternal(stderr, false, gn, level, fmt, ap);
545         va_end(ap);
546
547         if (opts.debug_file != stdout && opts.debug_file != stderr) {
548                 va_start(ap, fmt);
549                 ParseVErrorInternal(opts.debug_file, false, gn,
550                     level, fmt, ap);
551                 va_end(ap);
552         }
553 }
554
555 /*
556  * Print a parse error message, including location information.
557  *
558  * If the level is PARSE_FATAL, continue parsing until the end of the
559  * current top-level makefile, then exit (see Parse_File).
560  *
561  * Fmt is given without a trailing newline.
562  */
563 void
564 Parse_Error(ParseErrorLevel level, const char *fmt, ...)
565 {
566         va_list ap;
567
568         (void)fflush(stdout);
569         va_start(ap, fmt);
570         ParseVErrorInternal(stderr, true, NULL, level, fmt, ap);
571         va_end(ap);
572
573         if (opts.debug_file != stdout && opts.debug_file != stderr) {
574                 va_start(ap, fmt);
575                 ParseVErrorInternal(opts.debug_file, true, NULL,
576                     level, fmt, ap);
577                 va_end(ap);
578         }
579 }
580
581
582 /*
583  * Handle an .info, .warning or .error directive.  For an .error directive,
584  * exit immediately.
585  */
586 static void
587 HandleMessage(ParseErrorLevel level, const char *levelName, const char *umsg)
588 {
589         char *xmsg;
590
591         if (umsg[0] == '\0') {
592                 Parse_Error(PARSE_FATAL, "Missing argument for \".%s\"",
593                     levelName);
594                 return;
595         }
596
597         (void)Var_Subst(umsg, SCOPE_CMDLINE, VARE_WANTRES, &xmsg);
598         /* TODO: handle errors */
599
600         Parse_Error(level, "%s", xmsg);
601         free(xmsg);
602
603         if (level == PARSE_FATAL) {
604                 PrintOnError(NULL, "\n");
605                 exit(1);
606         }
607 }
608
609 /*
610  * Add the child to the parent's children, and for non-special targets, vice
611  * versa.  Special targets such as .END do not need to be informed once the
612  * child target has been made.
613  */
614 static void
615 LinkSource(GNode *pgn, GNode *cgn, bool isSpecial)
616 {
617         if ((pgn->type & OP_DOUBLEDEP) && !Lst_IsEmpty(&pgn->cohorts))
618                 pgn = pgn->cohorts.last->datum;
619
620         Lst_Append(&pgn->children, cgn);
621         pgn->unmade++;
622
623         /* Special targets like .END don't need any children. */
624         if (!isSpecial)
625                 Lst_Append(&cgn->parents, pgn);
626
627         if (DEBUG(PARSE)) {
628                 debug_printf("# LinkSource: added child %s - %s\n",
629                     pgn->name, cgn->name);
630                 Targ_PrintNode(pgn, 0);
631                 Targ_PrintNode(cgn, 0);
632         }
633 }
634
635 /* Add the node to each target from the current dependency group. */
636 static void
637 LinkToTargets(GNode *gn, bool isSpecial)
638 {
639         GNodeListNode *ln;
640
641         for (ln = targets->first; ln != NULL; ln = ln->next)
642                 LinkSource(ln->datum, gn, isSpecial);
643 }
644
645 static bool
646 TryApplyDependencyOperator(GNode *gn, GNodeType op)
647 {
648         /*
649          * If the node occurred on the left-hand side of a dependency and the
650          * operator also defines a dependency, they must match.
651          */
652         if ((op & OP_OPMASK) && (gn->type & OP_OPMASK) &&
653             ((op & OP_OPMASK) != (gn->type & OP_OPMASK))) {
654                 Parse_Error(PARSE_FATAL, "Inconsistent operator for %s",
655                     gn->name);
656                 return false;
657         }
658
659         if (op == OP_DOUBLEDEP && (gn->type & OP_OPMASK) == OP_DOUBLEDEP) {
660                 /*
661                  * If the node was of the left-hand side of a '::' operator,
662                  * we need to create a new instance of it for the children
663                  * and commands on this dependency line since each of these
664                  * dependency groups has its own attributes and commands,
665                  * separate from the others.
666                  *
667                  * The new instance is placed on the 'cohorts' list of the
668                  * initial one (note the initial one is not on its own
669                  * cohorts list) and the new instance is linked to all
670                  * parents of the initial instance.
671                  */
672                 GNode *cohort;
673
674                 /*
675                  * Propagate copied bits to the initial node.  They'll be
676                  * propagated back to the rest of the cohorts later.
677                  */
678                 gn->type |= op & (unsigned)~OP_OPMASK;
679
680                 cohort = Targ_NewInternalNode(gn->name);
681                 if (doing_depend)
682                         RememberLocation(cohort);
683                 /*
684                  * Make the cohort invisible as well to avoid duplicating it
685                  * into other variables. True, parents of this target won't
686                  * tend to do anything with their local variables, but better
687                  * safe than sorry.
688                  *
689                  * (I think this is pointless now, since the relevant list
690                  * traversals will no longer see this node anyway. -mycroft)
691                  */
692                 cohort->type = op | OP_INVISIBLE;
693                 Lst_Append(&gn->cohorts, cohort);
694                 cohort->centurion = gn;
695                 gn->unmade_cohorts++;
696                 snprintf(cohort->cohort_num, sizeof cohort->cohort_num, "#%d",
697                     (unsigned int)gn->unmade_cohorts % 1000000);
698         } else {
699                 /*
700                  * We don't want to nuke any previous flags (whatever they
701                  * were) so we just OR the new operator into the old.
702                  */
703                 gn->type |= op;
704         }
705
706         return true;
707 }
708
709 static void
710 ApplyDependencyOperator(GNodeType op)
711 {
712         GNodeListNode *ln;
713
714         for (ln = targets->first; ln != NULL; ln = ln->next)
715                 if (!TryApplyDependencyOperator(ln->datum, op))
716                         break;
717 }
718
719 /*
720  * We add a .WAIT node in the dependency list. After any dynamic dependencies
721  * (and filename globbing) have happened, it is given a dependency on each
722  * previous child, back until the previous .WAIT node. The next child won't
723  * be scheduled until the .WAIT node is built.
724  *
725  * We give each .WAIT node a unique name (mainly for diagnostics).
726  */
727 static void
728 ApplyDependencySourceWait(bool isSpecial)
729 {
730         static unsigned wait_number = 0;
731         char name[6 + 10 + 1];
732         GNode *gn;
733
734         snprintf(name, sizeof name, ".WAIT_%u", ++wait_number);
735         gn = Targ_NewInternalNode(name);
736         if (doing_depend)
737                 RememberLocation(gn);
738         gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN;
739         LinkToTargets(gn, isSpecial);
740 }
741
742 static bool
743 ApplyDependencySourceKeyword(const char *src, ParseSpecial special)
744 {
745         int keywd;
746         GNodeType targetAttr;
747
748         if (*src != '.' || !ch_isupper(src[1]))
749                 return false;
750
751         keywd = FindKeyword(src);
752         if (keywd == -1)
753                 return false;
754
755         targetAttr = parseKeywords[keywd].targetAttr;
756         if (targetAttr != OP_NONE) {
757                 ApplyDependencyOperator(targetAttr);
758                 return true;
759         }
760         if (parseKeywords[keywd].special == SP_WAIT) {
761                 ApplyDependencySourceWait(special != SP_NOT);
762                 return true;
763         }
764         return false;
765 }
766
767 /*
768  * In a line like ".MAIN: source1 source2", add all sources to the list of
769  * things to create, but only if the user didn't specify a target on the
770  * command line and .MAIN occurs for the first time.
771  *
772  * See HandleDependencyTargetSpecial, branch SP_MAIN.
773  * See unit-tests/cond-func-make-main.mk.
774  */
775 static void
776 ApplyDependencySourceMain(const char *src)
777 {
778         Lst_Append(&opts.create, bmake_strdup(src));
779         /*
780          * Add the name to the .TARGETS variable as well, so the user can
781          * employ that, if desired.
782          */
783         Global_Append(".TARGETS", src);
784 }
785
786 /*
787  * For the sources of a .ORDER target, create predecessor/successor links
788  * between the previous source and the current one.
789  */
790 static void
791 ApplyDependencySourceOrder(const char *src)
792 {
793         GNode *gn;
794
795         gn = Targ_GetNode(src);
796         if (doing_depend)
797                 RememberLocation(gn);
798         if (order_pred != NULL) {
799                 Lst_Append(&order_pred->order_succ, gn);
800                 Lst_Append(&gn->order_pred, order_pred);
801                 if (DEBUG(PARSE)) {
802                         debug_printf(
803                             "# .ORDER forces '%s' to be made before '%s'\n",
804                             order_pred->name, gn->name);
805                         Targ_PrintNode(order_pred, 0);
806                         Targ_PrintNode(gn, 0);
807                 }
808         }
809         /*
810          * The current source now becomes the predecessor for the next one.
811          */
812         order_pred = gn;
813 }
814
815 /* The source is not an attribute, so find/create a node for it. */
816 static void
817 ApplyDependencySourceOther(const char *src, GNodeType targetAttr,
818                            ParseSpecial special)
819 {
820         GNode *gn;
821
822         gn = Targ_GetNode(src);
823         if (doing_depend)
824                 RememberLocation(gn);
825         if (targetAttr != OP_NONE)
826                 gn->type |= targetAttr;
827         else
828                 LinkToTargets(gn, special != SP_NOT);
829 }
830
831 /*
832  * Given the name of a source in a dependency line, figure out if it is an
833  * attribute (such as .SILENT) and if so, apply it to all targets. Otherwise
834  * decide if there is some attribute which should be applied *to* the source
835  * because of some special target (such as .PHONY) and apply it if so.
836  * Otherwise, make the source a child of the targets.
837  */
838 static void
839 ApplyDependencySource(GNodeType targetAttr, const char *src,
840                       ParseSpecial special)
841 {
842         if (ApplyDependencySourceKeyword(src, special))
843                 return;
844
845         if (special == SP_MAIN)
846                 ApplyDependencySourceMain(src);
847         else if (special == SP_ORDER)
848                 ApplyDependencySourceOrder(src);
849         else
850                 ApplyDependencySourceOther(src, targetAttr, special);
851 }
852
853 /*
854  * If we have yet to decide on a main target to make, in the absence of any
855  * user input, we want the first target on the first dependency line that is
856  * actually a real target (i.e. isn't a .USE or .EXEC rule) to be made.
857  */
858 static void
859 MaybeUpdateMainTarget(void)
860 {
861         GNodeListNode *ln;
862
863         if (mainNode != NULL)
864                 return;
865
866         for (ln = targets->first; ln != NULL; ln = ln->next) {
867                 GNode *gn = ln->datum;
868                 if (GNode_IsMainCandidate(gn)) {
869                         DEBUG1(MAKE, "Setting main node to \"%s\"\n", gn->name);
870                         mainNode = gn;
871                         return;
872                 }
873         }
874 }
875
876 static void
877 InvalidLineType(const char *line)
878 {
879         if (strncmp(line, "<<<<<<", 6) == 0 ||
880             strncmp(line, ">>>>>>", 6) == 0)
881                 Parse_Error(PARSE_FATAL,
882                     "Makefile appears to contain unresolved CVS/RCS/??? merge conflicts");
883         else if (line[0] == '.') {
884                 const char *dirstart = line + 1;
885                 const char *dirend;
886                 cpp_skip_whitespace(&dirstart);
887                 dirend = dirstart;
888                 while (ch_isalnum(*dirend) || *dirend == '-')
889                         dirend++;
890                 Parse_Error(PARSE_FATAL, "Unknown directive \"%.*s\"",
891                     (int)(dirend - dirstart), dirstart);
892         } else
893                 Parse_Error(PARSE_FATAL, "Invalid line type");
894 }
895
896 static void
897 ParseDependencyTargetWord(char **pp, const char *lstart)
898 {
899         const char *cp = *pp;
900
901         while (*cp != '\0') {
902                 if ((ch_isspace(*cp) || *cp == '!' || *cp == ':' ||
903                      *cp == '(') &&
904                     !IsEscaped(lstart, cp))
905                         break;
906
907                 if (*cp == '$') {
908                         /*
909                          * Must be a dynamic source (would have been expanded
910                          * otherwise).
911                          *
912                          * There should be no errors in this, as they would
913                          * have been discovered in the initial Var_Subst and
914                          * we wouldn't be here.
915                          */
916                         FStr val;
917
918                         (void)Var_Parse(&cp, SCOPE_CMDLINE,
919                             VARE_PARSE_ONLY, &val);
920                         FStr_Done(&val);
921                 } else
922                         cp++;
923         }
924
925         *pp += cp - *pp;
926 }
927
928 /*
929  * Handle special targets like .PATH, .DEFAULT, .BEGIN, .ORDER.
930  *
931  * See the tests deptgt-*.mk.
932  */
933 static void
934 HandleDependencyTargetSpecial(const char *targetName,
935                               ParseSpecial *inout_special,
936                               SearchPathList **inout_paths)
937 {
938         switch (*inout_special) {
939         case SP_PATH:
940                 if (*inout_paths == NULL)
941                         *inout_paths = Lst_New();
942                 Lst_Append(*inout_paths, &dirSearchPath);
943                 break;
944         case SP_SYSPATH:
945                 if (*inout_paths == NULL)
946                         *inout_paths = Lst_New();
947                 Lst_Append(*inout_paths, sysIncPath);
948                 break;
949         case SP_MAIN:
950                 /*
951                  * Allow targets from the command line to override the
952                  * .MAIN node.
953                  */
954                 if (!Lst_IsEmpty(&opts.create))
955                         *inout_special = SP_NOT;
956                 break;
957         case SP_BEGIN:
958         case SP_END:
959         case SP_STALE:
960         case SP_ERROR:
961         case SP_INTERRUPT: {
962                 GNode *gn = Targ_GetNode(targetName);
963                 if (doing_depend)
964                         RememberLocation(gn);
965                 gn->type |= OP_NOTMAIN | OP_SPECIAL;
966                 Lst_Append(targets, gn);
967                 break;
968         }
969         case SP_DEFAULT: {
970                 /*
971                  * Need to create a node to hang commands on, but we don't
972                  * want it in the graph, nor do we want it to be the Main
973                  * Target. We claim the node is a transformation rule to make
974                  * life easier later, when we'll use Make_HandleUse to
975                  * actually apply the .DEFAULT commands.
976                  */
977                 GNode *gn = GNode_New(".DEFAULT");
978                 gn->type |= OP_NOTMAIN | OP_TRANSFORM;
979                 Lst_Append(targets, gn);
980                 defaultNode = gn;
981                 break;
982         }
983         case SP_DELETE_ON_ERROR:
984                 deleteOnError = true;
985                 break;
986         case SP_NOTPARALLEL:
987                 opts.maxJobs = 1;
988                 break;
989         case SP_SINGLESHELL:
990                 opts.compatMake = true;
991                 break;
992         case SP_ORDER:
993                 order_pred = NULL;
994                 break;
995         default:
996                 break;
997         }
998 }
999
1000 static bool
1001 HandleDependencyTargetPath(const char *suffixName,
1002                            SearchPathList **inout_paths)
1003 {
1004         SearchPath *path;
1005
1006         path = Suff_GetPath(suffixName);
1007         if (path == NULL) {
1008                 Parse_Error(PARSE_FATAL,
1009                     "Suffix '%s' not defined (yet)", suffixName);
1010                 return false;
1011         }
1012
1013         if (*inout_paths == NULL)
1014                 *inout_paths = Lst_New();
1015         Lst_Append(*inout_paths, path);
1016
1017         return true;
1018 }
1019
1020 /* See if it's a special target and if so set inout_special to match it. */
1021 static bool
1022 HandleDependencyTarget(const char *targetName,
1023                        ParseSpecial *inout_special,
1024                        GNodeType *inout_targetAttr,
1025                        SearchPathList **inout_paths)
1026 {
1027         int keywd;
1028
1029         if (!(targetName[0] == '.' && ch_isupper(targetName[1])))
1030                 return true;
1031
1032         /*
1033          * See if the target is a special target that must have it
1034          * or its sources handled specially.
1035          */
1036         keywd = FindKeyword(targetName);
1037         if (keywd != -1) {
1038                 if (*inout_special == SP_PATH &&
1039                     parseKeywords[keywd].special != SP_PATH) {
1040                         Parse_Error(PARSE_FATAL, "Mismatched special targets");
1041                         return false;
1042                 }
1043
1044                 *inout_special = parseKeywords[keywd].special;
1045                 *inout_targetAttr = parseKeywords[keywd].targetAttr;
1046
1047                 HandleDependencyTargetSpecial(targetName, inout_special,
1048                     inout_paths);
1049
1050         } else if (strncmp(targetName, ".PATH", 5) == 0) {
1051                 *inout_special = SP_PATH;
1052                 if (!HandleDependencyTargetPath(targetName + 5, inout_paths))
1053                         return false;
1054         }
1055         return true;
1056 }
1057
1058 static void
1059 HandleSingleDependencyTargetMundane(const char *name)
1060 {
1061         GNode *gn = Suff_IsTransform(name)
1062             ? Suff_AddTransform(name)
1063             : Targ_GetNode(name);
1064         if (doing_depend)
1065                 RememberLocation(gn);
1066
1067         Lst_Append(targets, gn);
1068 }
1069
1070 static void
1071 HandleDependencyTargetMundane(const char *targetName)
1072 {
1073         if (Dir_HasWildcards(targetName)) {
1074                 StringList targetNames = LST_INIT;
1075
1076                 SearchPath *emptyPath = SearchPath_New();
1077                 SearchPath_Expand(emptyPath, targetName, &targetNames);
1078                 SearchPath_Free(emptyPath);
1079
1080                 while (!Lst_IsEmpty(&targetNames)) {
1081                         char *targName = Lst_Dequeue(&targetNames);
1082                         HandleSingleDependencyTargetMundane(targName);
1083                         free(targName);
1084                 }
1085         } else
1086                 HandleSingleDependencyTargetMundane(targetName);
1087 }
1088
1089 static void
1090 SkipExtraTargets(char **pp, const char *lstart)
1091 {
1092         bool warning = false;
1093         const char *p = *pp;
1094
1095         while (*p != '\0') {
1096                 if (!IsEscaped(lstart, p) && (*p == '!' || *p == ':'))
1097                         break;
1098                 if (IsEscaped(lstart, p) || (*p != ' ' && *p != '\t'))
1099                         warning = true;
1100                 p++;
1101         }
1102         if (warning) {
1103                 const char *start = *pp;
1104                 cpp_skip_whitespace(&start);
1105                 Parse_Error(PARSE_WARNING, "Extra target '%.*s' ignored",
1106                     (int)(p - start), start);
1107         }
1108
1109         *pp += p - *pp;
1110 }
1111
1112 static void
1113 CheckSpecialMundaneMixture(ParseSpecial special)
1114 {
1115         switch (special) {
1116         case SP_DEFAULT:
1117         case SP_STALE:
1118         case SP_BEGIN:
1119         case SP_END:
1120         case SP_ERROR:
1121         case SP_INTERRUPT:
1122                 /*
1123                  * These create nodes on which to hang commands, so targets
1124                  * shouldn't be empty.
1125                  */
1126         case SP_NOT:
1127                 /* Nothing special here -- targets may be empty. */
1128                 break;
1129         default:
1130                 Parse_Error(PARSE_WARNING,
1131                     "Special and mundane targets don't mix. "
1132                     "Mundane ones ignored");
1133                 break;
1134         }
1135 }
1136
1137 /*
1138  * In a dependency line like 'targets: sources' or 'targets! sources', parse
1139  * the operator ':', '::' or '!' from between the targets and the sources.
1140  */
1141 static GNodeType
1142 ParseDependencyOp(char **pp)
1143 {
1144         if (**pp == '!')
1145                 return (*pp)++, OP_FORCE;
1146         if (**pp == ':' && (*pp)[1] == ':')
1147                 return *pp += 2, OP_DOUBLEDEP;
1148         else if (**pp == ':')
1149                 return (*pp)++, OP_DEPENDS;
1150         else
1151                 return OP_NONE;
1152 }
1153
1154 static void
1155 ClearPaths(ParseSpecial special, SearchPathList *paths)
1156 {
1157         if (paths != NULL) {
1158                 SearchPathListNode *ln;
1159                 for (ln = paths->first; ln != NULL; ln = ln->next)
1160                         SearchPath_Clear(ln->datum);
1161         }
1162         if (special == SP_SYSPATH)
1163                 Dir_SetSYSPATH();
1164         else
1165                 Dir_SetPATH();
1166 }
1167
1168 static char *
1169 FindInDirOfIncludingFile(const char *file)
1170 {
1171         char *fullname, *incdir, *slash, *newName;
1172         int i;
1173
1174         fullname = NULL;
1175         incdir = bmake_strdup(CurFile()->name.str);
1176         slash = strrchr(incdir, '/');
1177         if (slash != NULL) {
1178                 *slash = '\0';
1179                 /*
1180                  * Now do lexical processing of leading "../" on the
1181                  * filename.
1182                  */
1183                 for (i = 0; strncmp(file + i, "../", 3) == 0; i += 3) {
1184                         slash = strrchr(incdir + 1, '/');
1185                         if (slash == NULL || strcmp(slash, "/..") == 0)
1186                                 break;
1187                         *slash = '\0';
1188                 }
1189                 newName = str_concat3(incdir, "/", file + i);
1190                 fullname = Dir_FindFile(newName, parseIncPath);
1191                 if (fullname == NULL)
1192                         fullname = Dir_FindFile(newName, &dirSearchPath);
1193                 free(newName);
1194         }
1195         free(incdir);
1196         return fullname;
1197 }
1198
1199 static char *
1200 FindInQuotPath(const char *file)
1201 {
1202         const char *suff;
1203         SearchPath *suffPath;
1204         char *fullname;
1205
1206         fullname = FindInDirOfIncludingFile(file);
1207         if (fullname == NULL &&
1208             (suff = strrchr(file, '.')) != NULL &&
1209             (suffPath = Suff_GetPath(suff)) != NULL)
1210                 fullname = Dir_FindFile(file, suffPath);
1211         if (fullname == NULL)
1212                 fullname = Dir_FindFile(file, parseIncPath);
1213         if (fullname == NULL)
1214                 fullname = Dir_FindFile(file, &dirSearchPath);
1215         return fullname;
1216 }
1217
1218 /*
1219  * Handle one of the .[-ds]include directives by remembering the current file
1220  * and pushing the included file on the stack.  After the included file has
1221  * finished, parsing continues with the including file; see Parse_PushInput
1222  * and ParseEOF.
1223  *
1224  * System includes are looked up in sysIncPath, any other includes are looked
1225  * up in the parsedir and then in the directories specified by the -I command
1226  * line options.
1227  */
1228 static void
1229 IncludeFile(const char *file, bool isSystem, bool depinc, bool silent)
1230 {
1231         Buffer buf;
1232         char *fullname;         /* full pathname of file */
1233         int fd;
1234
1235         fullname = file[0] == '/' ? bmake_strdup(file) : NULL;
1236
1237         if (fullname == NULL && !isSystem)
1238                 fullname = FindInQuotPath(file);
1239
1240         if (fullname == NULL) {
1241                 SearchPath *path = Lst_IsEmpty(&sysIncPath->dirs)
1242                     ? defSysIncPath : sysIncPath;
1243                 fullname = Dir_FindFile(file, path);
1244         }
1245
1246         if (fullname == NULL) {
1247                 if (!silent)
1248                         Parse_Error(PARSE_FATAL, "Could not find %s", file);
1249                 return;
1250         }
1251
1252         if ((fd = open(fullname, O_RDONLY)) == -1) {
1253                 if (!silent)
1254                         Parse_Error(PARSE_FATAL, "Cannot open %s", fullname);
1255                 free(fullname);
1256                 return;
1257         }
1258
1259         buf = LoadFile(fullname, fd);
1260         (void)close(fd);
1261
1262         Parse_PushInput(fullname, 1, 0, buf, NULL);
1263         if (depinc)
1264                 doing_depend = depinc;  /* only turn it on */
1265         free(fullname);
1266 }
1267
1268 /* Handle a "dependency" line like '.SPECIAL:' without any sources. */
1269 static void
1270 HandleDependencySourcesEmpty(ParseSpecial special, SearchPathList *paths)
1271 {
1272         switch (special) {
1273         case SP_SUFFIXES:
1274                 Suff_ClearSuffixes();
1275                 break;
1276         case SP_PRECIOUS:
1277                 allPrecious = true;
1278                 break;
1279         case SP_IGNORE:
1280                 opts.ignoreErrors = true;
1281                 break;
1282         case SP_SILENT:
1283                 opts.silent = true;
1284                 break;
1285         case SP_PATH:
1286         case SP_SYSPATH:
1287                 ClearPaths(special, paths);
1288                 break;
1289 #ifdef POSIX
1290         case SP_POSIX:
1291                 if (posix_state == PS_NOW_OR_NEVER) {
1292                         /*
1293                          * With '-r', 'posix.mk' (if it exists)
1294                          * can effectively substitute for 'sys.mk',
1295                          * otherwise it is an extension.
1296                          */
1297                         Global_Set("%POSIX", "1003.2");
1298                         IncludeFile("posix.mk", true, false, true);
1299                 }
1300                 break;
1301 #endif
1302         default:
1303                 break;
1304         }
1305 }
1306
1307 static void
1308 AddToPaths(const char *dir, SearchPathList *paths)
1309 {
1310         if (paths != NULL) {
1311                 SearchPathListNode *ln;
1312                 for (ln = paths->first; ln != NULL; ln = ln->next)
1313                         (void)SearchPath_Add(ln->datum, dir);
1314         }
1315 }
1316
1317 /*
1318  * If the target was one that doesn't take files as its sources but takes
1319  * something like suffixes, we take each space-separated word on the line as
1320  * a something and deal with it accordingly.
1321  */
1322 static void
1323 ParseDependencySourceSpecial(ParseSpecial special, const char *word,
1324                              SearchPathList *paths)
1325 {
1326         switch (special) {
1327         case SP_SUFFIXES:
1328                 Suff_AddSuffix(word);
1329                 break;
1330         case SP_PATH:
1331                 AddToPaths(word, paths);
1332                 break;
1333         case SP_INCLUDES:
1334                 Suff_AddInclude(word);
1335                 break;
1336         case SP_LIBS:
1337                 Suff_AddLib(word);
1338                 break;
1339         case SP_NOREADONLY:
1340                 Var_ReadOnly(word, false);
1341                 break;
1342         case SP_NULL:
1343                 Suff_SetNull(word);
1344                 break;
1345         case SP_OBJDIR:
1346                 Main_SetObjdir(false, "%s", word);
1347                 break;
1348         case SP_READONLY:
1349                 Var_ReadOnly(word, true);
1350                 break;
1351         case SP_SYSPATH:
1352                 AddToPaths(word, paths);
1353                 break;
1354         default:
1355                 break;
1356         }
1357 }
1358
1359 static bool
1360 ApplyDependencyTarget(char *name, char *nameEnd, ParseSpecial *inout_special,
1361                       GNodeType *inout_targetAttr,
1362                       SearchPathList **inout_paths)
1363 {
1364         char savec = *nameEnd;
1365         *nameEnd = '\0';
1366
1367         if (!HandleDependencyTarget(name, inout_special,
1368             inout_targetAttr, inout_paths))
1369                 return false;
1370
1371         if (*inout_special == SP_NOT && *name != '\0')
1372                 HandleDependencyTargetMundane(name);
1373         else if (*inout_special == SP_PATH && *name != '.' && *name != '\0')
1374                 Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", name);
1375
1376         *nameEnd = savec;
1377         return true;
1378 }
1379
1380 static bool
1381 ParseDependencyTargets(char **pp,
1382                        const char *lstart,
1383                        ParseSpecial *inout_special,
1384                        GNodeType *inout_targetAttr,
1385                        SearchPathList **inout_paths)
1386 {
1387         char *p = *pp;
1388
1389         for (;;) {
1390                 char *tgt = p;
1391
1392                 ParseDependencyTargetWord(&p, lstart);
1393
1394                 /*
1395                  * If the word is followed by a left parenthesis, it's the
1396                  * name of one or more files inside an archive.
1397                  */
1398                 if (!IsEscaped(lstart, p) && *p == '(') {
1399                         p = tgt;
1400                         if (!Arch_ParseArchive(&p, targets, SCOPE_CMDLINE)) {
1401                                 Parse_Error(PARSE_FATAL,
1402                                     "Error in archive specification: \"%s\"",
1403                                     tgt);
1404                                 return false;
1405                         }
1406                         continue;
1407                 }
1408
1409                 if (*p == '\0') {
1410                         InvalidLineType(lstart);
1411                         return false;
1412                 }
1413
1414                 if (!ApplyDependencyTarget(tgt, p, inout_special,
1415                     inout_targetAttr, inout_paths))
1416                         return false;
1417
1418                 if (*inout_special != SP_NOT && *inout_special != SP_PATH)
1419                         SkipExtraTargets(&p, lstart);
1420                 else
1421                         pp_skip_whitespace(&p);
1422
1423                 if (*p == '\0')
1424                         break;
1425                 if ((*p == '!' || *p == ':') && !IsEscaped(lstart, p))
1426                         break;
1427         }
1428
1429         *pp = p;
1430         return true;
1431 }
1432
1433 static void
1434 ParseDependencySourcesSpecial(char *start,
1435                               ParseSpecial special, SearchPathList *paths)
1436 {
1437         char savec;
1438
1439         while (*start != '\0') {
1440                 char *end = start;
1441                 while (*end != '\0' && !ch_isspace(*end))
1442                         end++;
1443                 savec = *end;
1444                 *end = '\0';
1445                 ParseDependencySourceSpecial(special, start, paths);
1446                 *end = savec;
1447                 if (savec != '\0')
1448                         end++;
1449                 pp_skip_whitespace(&end);
1450                 start = end;
1451         }
1452 }
1453
1454 static void
1455 LinkVarToTargets(VarAssign *var)
1456 {
1457         GNodeListNode *ln;
1458
1459         for (ln = targets->first; ln != NULL; ln = ln->next)
1460                 Parse_Var(var, ln->datum);
1461 }
1462
1463 static bool
1464 ParseDependencySourcesMundane(char *start,
1465                               ParseSpecial special, GNodeType targetAttr)
1466 {
1467         while (*start != '\0') {
1468                 char *end = start;
1469                 VarAssign var;
1470
1471                 /*
1472                  * Check for local variable assignment,
1473                  * rest of the line is the value.
1474                  */
1475                 if (Parse_IsVar(start, &var)) {
1476                         /*
1477                          * Check if this makefile has disabled
1478                          * setting local variables.
1479                          */
1480                         bool target_vars = GetBooleanExpr(
1481                             "${.MAKE.TARGET_LOCAL_VARIABLES}", true);
1482
1483                         if (target_vars)
1484                                 LinkVarToTargets(&var);
1485                         free(var.varname);
1486                         if (target_vars)
1487                                 return true;
1488                 }
1489
1490                 /*
1491                  * The targets take real sources, so we must beware of archive
1492                  * specifications (i.e. things with left parentheses in them)
1493                  * and handle them accordingly.
1494                  */
1495                 for (; *end != '\0' && !ch_isspace(*end); end++) {
1496                         if (*end == '(' && end > start && end[-1] != '$') {
1497                                 /*
1498                                  * Only stop for a left parenthesis if it
1499                                  * isn't at the start of a word (that'll be
1500                                  * for variable changes later) and isn't
1501                                  * preceded by a dollar sign (a dynamic
1502                                  * source).
1503                                  */
1504                                 break;
1505                         }
1506                 }
1507
1508                 if (*end == '(') {
1509                         GNodeList sources = LST_INIT;
1510                         if (!Arch_ParseArchive(&start, &sources,
1511                             SCOPE_CMDLINE)) {
1512                                 Parse_Error(PARSE_FATAL,
1513                                     "Error in source archive spec \"%s\"",
1514                                     start);
1515                                 return false;
1516                         }
1517
1518                         while (!Lst_IsEmpty(&sources)) {
1519                                 GNode *gn = Lst_Dequeue(&sources);
1520                                 ApplyDependencySource(targetAttr, gn->name,
1521                                     special);
1522                         }
1523                         Lst_Done(&sources);
1524                         end = start;
1525                 } else {
1526                         if (*end != '\0') {
1527                                 *end = '\0';
1528                                 end++;
1529                         }
1530
1531                         ApplyDependencySource(targetAttr, start, special);
1532                 }
1533                 pp_skip_whitespace(&end);
1534                 start = end;
1535         }
1536         return true;
1537 }
1538
1539 /*
1540  * From a dependency line like 'targets: sources', parse the sources.
1541  *
1542  * See the tests depsrc-*.mk.
1543  */
1544 static void
1545 ParseDependencySources(char *p, GNodeType targetAttr,
1546                        ParseSpecial special, SearchPathList **inout_paths)
1547 {
1548         if (*p == '\0') {
1549                 HandleDependencySourcesEmpty(special, *inout_paths);
1550         } else if (special == SP_MFLAGS) {
1551                 Main_ParseArgLine(p);
1552                 return;
1553         } else if (special == SP_SHELL) {
1554                 if (!Job_ParseShell(p)) {
1555                         Parse_Error(PARSE_FATAL,
1556                             "improper shell specification");
1557                         return;
1558                 }
1559                 return;
1560         } else if (special == SP_NOTPARALLEL || special == SP_SINGLESHELL ||
1561                    special == SP_DELETE_ON_ERROR) {
1562                 return;
1563         }
1564
1565         /* Now go for the sources. */
1566         switch (special) {
1567         case SP_INCLUDES:
1568         case SP_LIBS:
1569         case SP_NOREADONLY:
1570         case SP_NULL:
1571         case SP_OBJDIR:
1572         case SP_PATH:
1573         case SP_READONLY:
1574         case SP_SUFFIXES:
1575         case SP_SYSPATH:
1576                 ParseDependencySourcesSpecial(p, special, *inout_paths);
1577                 if (*inout_paths != NULL) {
1578                         Lst_Free(*inout_paths);
1579                         *inout_paths = NULL;
1580                 }
1581                 if (special == SP_PATH)
1582                         Dir_SetPATH();
1583                 if (special == SP_SYSPATH)
1584                         Dir_SetSYSPATH();
1585                 break;
1586         default:
1587                 assert(*inout_paths == NULL);
1588                 if (!ParseDependencySourcesMundane(p, special, targetAttr))
1589                         return;
1590                 break;
1591         }
1592
1593         MaybeUpdateMainTarget();
1594 }
1595
1596 /*
1597  * Parse a dependency line consisting of targets, followed by a dependency
1598  * operator, optionally followed by sources.
1599  *
1600  * The nodes of the sources are linked as children to the nodes of the
1601  * targets. Nodes are created as necessary.
1602  *
1603  * The operator is applied to each node in the global 'targets' list,
1604  * which is where the nodes found for the targets are kept.
1605  *
1606  * The sources are parsed in much the same way as the targets, except
1607  * that they are expanded using the wildcarding scheme of the C-Shell,
1608  * and a target is created for each expanded word. Each of the resulting
1609  * nodes is then linked to each of the targets as one of its children.
1610  *
1611  * Certain targets and sources such as .PHONY or .PRECIOUS are handled
1612  * specially, see ParseSpecial.
1613  *
1614  * Transformation rules such as '.c.o' are also handled here, see
1615  * Suff_AddTransform.
1616  *
1617  * Upon return, the value of the line is unspecified.
1618  */
1619 static void
1620 ParseDependency(char *line)
1621 {
1622         char *p;
1623         SearchPathList *paths;  /* search paths to alter when parsing a list
1624                                  * of .PATH targets */
1625         GNodeType targetAttr;   /* from special sources */
1626         ParseSpecial special;   /* in special targets, the children are
1627                                  * linked as children of the parent but not
1628                                  * vice versa */
1629         GNodeType op;
1630
1631         DEBUG1(PARSE, "ParseDependency(%s)\n", line);
1632         p = line;
1633         paths = NULL;
1634         targetAttr = OP_NONE;
1635         special = SP_NOT;
1636
1637         if (!ParseDependencyTargets(&p, line, &special, &targetAttr, &paths))
1638                 goto out;
1639
1640         if (!Lst_IsEmpty(targets))
1641                 CheckSpecialMundaneMixture(special);
1642
1643         op = ParseDependencyOp(&p);
1644         if (op == OP_NONE) {
1645                 InvalidLineType(line);
1646                 goto out;
1647         }
1648         ApplyDependencyOperator(op);
1649
1650         pp_skip_whitespace(&p);
1651
1652         ParseDependencySources(p, targetAttr, special, &paths);
1653
1654 out:
1655         if (paths != NULL)
1656                 Lst_Free(paths);
1657 }
1658
1659 /*
1660  * Determine the assignment operator and adjust the end of the variable
1661  * name accordingly.
1662  */
1663 static VarAssign
1664 AdjustVarassignOp(const char *name, const char *nameEnd, const char *op,
1665                   const char *value)
1666 {
1667         VarAssignOp type;
1668         VarAssign va;
1669
1670         if (op > name && op[-1] == '+') {
1671                 op--;
1672                 type = VAR_APPEND;
1673
1674         } else if (op > name && op[-1] == '?') {
1675                 op--;
1676                 type = VAR_DEFAULT;
1677
1678         } else if (op > name && op[-1] == ':') {
1679                 op--;
1680                 type = VAR_SUBST;
1681
1682         } else if (op > name && op[-1] == '!') {
1683                 op--;
1684                 type = VAR_SHELL;
1685
1686         } else {
1687                 type = VAR_NORMAL;
1688 #ifdef SUNSHCMD
1689                 while (op > name && ch_isspace(op[-1]))
1690                         op--;
1691
1692                 if (op - name >= 3 && memcmp(op - 3, ":sh", 3) == 0) {
1693                         op -= 3;
1694                         type = VAR_SHELL;
1695                 }
1696 #endif
1697         }
1698
1699         va.varname = bmake_strsedup(name, nameEnd < op ? nameEnd : op);
1700         va.op = type;
1701         va.value = value;
1702         return va;
1703 }
1704
1705 /*
1706  * Parse a variable assignment, consisting of a single-word variable name,
1707  * optional whitespace, an assignment operator, optional whitespace and the
1708  * variable value.
1709  *
1710  * Note: There is a lexical ambiguity with assignment modifier characters
1711  * in variable names. This routine interprets the character before the =
1712  * as a modifier. Therefore, an assignment like
1713  *      C++=/usr/bin/CC
1714  * is interpreted as "C+ +=" instead of "C++ =".
1715  *
1716  * Used for both lines in a file and command line arguments.
1717  */
1718 static bool
1719 Parse_IsVar(const char *p, VarAssign *out_var)
1720 {
1721         const char *nameStart, *nameEnd, *firstSpace, *eq;
1722         int level = 0;
1723
1724         cpp_skip_hspace(&p);    /* Skip to variable name */
1725
1726         /*
1727          * During parsing, the '+' of the operator '+=' is initially parsed
1728          * as part of the variable name.  It is later corrected, as is the
1729          * ':sh' modifier. Of these two (nameEnd and eq), the earlier one
1730          * determines the actual end of the variable name.
1731          */
1732
1733         nameStart = p;
1734         firstSpace = NULL;
1735
1736         /*
1737          * Scan for one of the assignment operators outside a variable
1738          * expansion.
1739          */
1740         while (*p != '\0') {
1741                 char ch = *p++;
1742                 if (ch == '(' || ch == '{') {
1743                         level++;
1744                         continue;
1745                 }
1746                 if (ch == ')' || ch == '}') {
1747                         level--;
1748                         continue;
1749                 }
1750
1751                 if (level != 0)
1752                         continue;
1753
1754                 if ((ch == ' ' || ch == '\t') && firstSpace == NULL)
1755                         firstSpace = p - 1;
1756                 while (ch == ' ' || ch == '\t')
1757                         ch = *p++;
1758
1759                 if (ch == '\0')
1760                         return false;
1761 #ifdef SUNSHCMD
1762                 if (ch == ':' && p[0] == 's' && p[1] == 'h') {
1763                         p += 2;
1764                         continue;
1765                 }
1766 #endif
1767                 if (ch == '=')
1768                         eq = p - 1;
1769                 else if (*p == '=' &&
1770                     (ch == '+' || ch == ':' || ch == '?' || ch == '!'))
1771                         eq = p;
1772                 else if (firstSpace != NULL)
1773                         return false;
1774                 else
1775                         continue;
1776
1777                 nameEnd = firstSpace != NULL ? firstSpace : eq;
1778                 p = eq + 1;
1779                 cpp_skip_whitespace(&p);
1780                 *out_var = AdjustVarassignOp(nameStart, nameEnd, eq, p);
1781                 return true;
1782         }
1783
1784         return false;
1785 }
1786
1787 /*
1788  * Check for syntax errors such as unclosed expressions or unknown modifiers.
1789  */
1790 static void
1791 VarCheckSyntax(VarAssignOp type, const char *uvalue, GNode *scope)
1792 {
1793         if (opts.strict) {
1794                 if (type != VAR_SUBST && strchr(uvalue, '$') != NULL) {
1795                         char *expandedValue;
1796
1797                         (void)Var_Subst(uvalue, scope, VARE_PARSE_ONLY,
1798                             &expandedValue);
1799                         /* TODO: handle errors */
1800                         free(expandedValue);
1801                 }
1802         }
1803 }
1804
1805 /* Perform a variable assignment that uses the operator ':='. */
1806 static void
1807 VarAssign_EvalSubst(GNode *scope, const char *name, const char *uvalue,
1808                     FStr *out_avalue)
1809 {
1810         char *evalue;
1811
1812         /*
1813          * make sure that we set the variable the first time to nothing
1814          * so that it gets substituted.
1815          *
1816          * TODO: Add a test that demonstrates why this code is needed,
1817          *  apart from making the debug log longer.
1818          *
1819          * XXX: The variable name is expanded up to 3 times.
1820          */
1821         if (!Var_ExistsExpand(scope, name))
1822                 Var_SetExpand(scope, name, "");
1823
1824         (void)Var_Subst(uvalue, scope, VARE_KEEP_DOLLAR_UNDEF, &evalue);
1825         /* TODO: handle errors */
1826
1827         Var_SetExpand(scope, name, evalue);
1828
1829         *out_avalue = FStr_InitOwn(evalue);
1830 }
1831
1832 /* Perform a variable assignment that uses the operator '!='. */
1833 static void
1834 VarAssign_EvalShell(const char *name, const char *uvalue, GNode *scope,
1835                     FStr *out_avalue)
1836 {
1837         FStr cmd;
1838         char *output, *error;
1839
1840         cmd = FStr_InitRefer(uvalue);
1841         Var_Expand(&cmd, SCOPE_CMDLINE, VARE_UNDEFERR);
1842
1843         output = Cmd_Exec(cmd.str, &error);
1844         Var_SetExpand(scope, name, output);
1845         *out_avalue = FStr_InitOwn(output);
1846         if (error != NULL) {
1847                 Parse_Error(PARSE_WARNING, "%s", error);
1848                 free(error);
1849         }
1850
1851         FStr_Done(&cmd);
1852 }
1853
1854 /*
1855  * Perform a variable assignment.
1856  *
1857  * The actual value of the variable is returned in *out_true_avalue.
1858  * Especially for VAR_SUBST and VAR_SHELL this can differ from the literal
1859  * value.
1860  *
1861  * Return whether the assignment was actually performed, which is usually
1862  * the case.  It is only skipped if the operator is '?=' and the variable
1863  * already exists.
1864  */
1865 static bool
1866 VarAssign_Eval(const char *name, VarAssignOp op, const char *uvalue,
1867                GNode *scope, FStr *out_true_avalue)
1868 {
1869         FStr avalue = FStr_InitRefer(uvalue);
1870
1871         if (op == VAR_APPEND)
1872                 Var_AppendExpand(scope, name, uvalue);
1873         else if (op == VAR_SUBST)
1874                 VarAssign_EvalSubst(scope, name, uvalue, &avalue);
1875         else if (op == VAR_SHELL)
1876                 VarAssign_EvalShell(name, uvalue, scope, &avalue);
1877         else {
1878                 /* XXX: The variable name is expanded up to 2 times. */
1879                 if (op == VAR_DEFAULT && Var_ExistsExpand(scope, name))
1880                         return false;
1881
1882                 /* Normal assignment -- just do it. */
1883                 Var_SetExpand(scope, name, uvalue);
1884         }
1885
1886         *out_true_avalue = avalue;
1887         return true;
1888 }
1889
1890 static void
1891 VarAssignSpecial(const char *name, const char *avalue)
1892 {
1893         if (strcmp(name, MAKEOVERRIDES) == 0)
1894                 Main_ExportMAKEFLAGS(false);    /* re-export MAKEFLAGS */
1895         else if (strcmp(name, ".CURDIR") == 0) {
1896                 /*
1897                  * Someone is being (too?) clever...
1898                  * Let's pretend they know what they are doing and
1899                  * re-initialize the 'cur' CachedDir.
1900                  */
1901                 Dir_InitCur(avalue);
1902                 Dir_SetPATH();
1903         } else if (strcmp(name, MAKE_JOB_PREFIX) == 0)
1904                 Job_SetPrefix();
1905         else if (strcmp(name, MAKE_EXPORTED) == 0)
1906                 Var_ExportVars(avalue);
1907 }
1908
1909 /* Perform the variable assignment in the given scope. */
1910 static void
1911 Parse_Var(VarAssign *var, GNode *scope)
1912 {
1913         FStr avalue;            /* actual value (maybe expanded) */
1914
1915         VarCheckSyntax(var->op, var->value, scope);
1916         if (VarAssign_Eval(var->varname, var->op, var->value, scope, &avalue)) {
1917                 VarAssignSpecial(var->varname, avalue.str);
1918                 FStr_Done(&avalue);
1919         }
1920 }
1921
1922
1923 /*
1924  * See if the command possibly calls a sub-make by using the variable
1925  * expressions ${.MAKE}, ${MAKE} or the plain word "make".
1926  */
1927 static bool
1928 MaybeSubMake(const char *cmd)
1929 {
1930         const char *start;
1931
1932         for (start = cmd; *start != '\0'; start++) {
1933                 const char *p = start;
1934                 char endc;
1935
1936                 /* XXX: What if progname != "make"? */
1937                 if (strncmp(p, "make", 4) == 0)
1938                         if (start == cmd || !ch_isalnum(p[-1]))
1939                                 if (!ch_isalnum(p[4]))
1940                                         return true;
1941
1942                 if (*p != '$')
1943                         continue;
1944                 p++;
1945
1946                 if (*p == '{')
1947                         endc = '}';
1948                 else if (*p == '(')
1949                         endc = ')';
1950                 else
1951                         continue;
1952                 p++;
1953
1954                 if (*p == '.')  /* Accept either ${.MAKE} or ${MAKE}. */
1955                         p++;
1956
1957                 if (strncmp(p, "MAKE", 4) == 0 && p[4] == endc)
1958                         return true;
1959         }
1960         return false;
1961 }
1962
1963 /*
1964  * Append the command to the target node.
1965  *
1966  * The node may be marked as a submake node if the command is determined to
1967  * be that.
1968  */
1969 static void
1970 GNode_AddCommand(GNode *gn, char *cmd)
1971 {
1972         /* Add to last (ie current) cohort for :: targets */
1973         if ((gn->type & OP_DOUBLEDEP) && gn->cohorts.last != NULL)
1974                 gn = gn->cohorts.last->datum;
1975
1976         /* if target already supplied, ignore commands */
1977         if (!(gn->type & OP_HAS_COMMANDS)) {
1978                 Lst_Append(&gn->commands, cmd);
1979                 if (MaybeSubMake(cmd))
1980                         gn->type |= OP_SUBMAKE;
1981                 RememberLocation(gn);
1982         } else {
1983 #if 0
1984                 /* XXX: We cannot do this until we fix the tree */
1985                 Lst_Append(&gn->commands, cmd);
1986                 Parse_Error(PARSE_WARNING,
1987                     "overriding commands for target \"%s\"; "
1988                     "previous commands defined at %s: %u ignored",
1989                     gn->name, gn->fname, gn->lineno);
1990 #else
1991                 Parse_Error(PARSE_WARNING,
1992                     "duplicate script for target \"%s\" ignored",
1993                     gn->name);
1994                 ParseErrorInternal(gn, PARSE_WARNING,
1995                     "using previous script for \"%s\" defined here",
1996                     gn->name);
1997 #endif
1998         }
1999 }
2000
2001 /*
2002  * Add a directory to the path searched for included makefiles bracketed
2003  * by double-quotes.
2004  */
2005 void
2006 Parse_AddIncludeDir(const char *dir)
2007 {
2008         (void)SearchPath_Add(parseIncPath, dir);
2009 }
2010
2011
2012 /*
2013  * Parse a directive like '.include' or '.-include'.
2014  *
2015  * .include "user-makefile.mk"
2016  * .include <system-makefile.mk>
2017  */
2018 static void
2019 ParseInclude(char *directive)
2020 {
2021         char endc;              /* '>' or '"' */
2022         char *p;
2023         bool silent = directive[0] != 'i';
2024         FStr file;
2025
2026         p = directive + (silent ? 8 : 7);
2027         pp_skip_hspace(&p);
2028
2029         if (*p != '"' && *p != '<') {
2030                 Parse_Error(PARSE_FATAL,
2031                     ".include filename must be delimited by '\"' or '<'");
2032                 return;
2033         }
2034
2035         if (*p++ == '<')
2036                 endc = '>';
2037         else
2038                 endc = '"';
2039         file = FStr_InitRefer(p);
2040
2041         /* Skip to matching delimiter */
2042         while (*p != '\0' && *p != endc)
2043                 p++;
2044
2045         if (*p != endc) {
2046                 Parse_Error(PARSE_FATAL,
2047                     "Unclosed .include filename. '%c' expected", endc);
2048                 return;
2049         }
2050
2051         *p = '\0';
2052
2053         Var_Expand(&file, SCOPE_CMDLINE, VARE_WANTRES);
2054         IncludeFile(file.str, endc == '>', directive[0] == 'd', silent);
2055         FStr_Done(&file);
2056 }
2057
2058 /*
2059  * Split filename into dirname + basename, then assign these to the
2060  * given variables.
2061  */
2062 static void
2063 SetFilenameVars(const char *filename, const char *dirvar, const char *filevar)
2064 {
2065         const char *slash, *basename;
2066         FStr dirname;
2067
2068         slash = strrchr(filename, '/');
2069         if (slash == NULL) {
2070                 dirname = FStr_InitRefer(curdir);
2071                 basename = filename;
2072         } else {
2073                 dirname = FStr_InitOwn(bmake_strsedup(filename, slash));
2074                 basename = slash + 1;
2075         }
2076
2077         Global_Set(dirvar, dirname.str);
2078         Global_Set(filevar, basename);
2079
2080         DEBUG4(PARSE, "SetFilenameVars: ${%s} = `%s' ${%s} = `%s'\n",
2081             dirvar, dirname.str, filevar, basename);
2082         FStr_Done(&dirname);
2083 }
2084
2085 /*
2086  * Return the immediately including file.
2087  *
2088  * This is made complicated since the .for loop is implemented as a special
2089  * kind of .include; see For_Run.
2090  */
2091 static const char *
2092 GetActuallyIncludingFile(void)
2093 {
2094         size_t i;
2095         const IncludedFile *incs = GetInclude(0);
2096
2097         for (i = includes.len; i >= 2; i--)
2098                 if (incs[i - 1].forLoop == NULL)
2099                         return incs[i - 2].name.str;
2100         return NULL;
2101 }
2102
2103 /* Set .PARSEDIR, .PARSEFILE, .INCLUDEDFROMDIR and .INCLUDEDFROMFILE. */
2104 static void
2105 SetParseFile(const char *filename)
2106 {
2107         const char *including;
2108
2109         SetFilenameVars(filename, ".PARSEDIR", ".PARSEFILE");
2110
2111         including = GetActuallyIncludingFile();
2112         if (including != NULL) {
2113                 SetFilenameVars(including,
2114                     ".INCLUDEDFROMDIR", ".INCLUDEDFROMFILE");
2115         } else {
2116                 Global_Delete(".INCLUDEDFROMDIR");
2117                 Global_Delete(".INCLUDEDFROMFILE");
2118         }
2119 }
2120
2121 static bool
2122 StrContainsWord(const char *str, const char *word)
2123 {
2124         size_t strLen = strlen(str);
2125         size_t wordLen = strlen(word);
2126         const char *p;
2127
2128         if (strLen < wordLen)
2129                 return false;
2130
2131         for (p = str; p != NULL; p = strchr(p, ' ')) {
2132                 if (*p == ' ')
2133                         p++;
2134                 if (p > str + strLen - wordLen)
2135                         return false;
2136
2137                 if (memcmp(p, word, wordLen) == 0 &&
2138                     (p[wordLen] == '\0' || p[wordLen] == ' '))
2139                         return true;
2140         }
2141         return false;
2142 }
2143
2144 /*
2145  * XXX: Searching through a set of words with this linear search is
2146  * inefficient for variables that contain thousands of words.
2147  *
2148  * XXX: The paths in this list don't seem to be normalized in any way.
2149  */
2150 static bool
2151 VarContainsWord(const char *varname, const char *word)
2152 {
2153         FStr val = Var_Value(SCOPE_GLOBAL, varname);
2154         bool found = val.str != NULL && StrContainsWord(val.str, word);
2155         FStr_Done(&val);
2156         return found;
2157 }
2158
2159 /*
2160  * Track the makefiles we read - so makefiles can set dependencies on them.
2161  * Avoid adding anything more than once.
2162  *
2163  * Time complexity: O(n) per call, in total O(n^2), where n is the number
2164  * of makefiles that have been loaded.
2165  */
2166 static void
2167 TrackInput(const char *name)
2168 {
2169         if (!VarContainsWord(MAKE_MAKEFILES, name))
2170                 Global_Append(MAKE_MAKEFILES, name);
2171 }
2172
2173
2174 /* Parse from the given buffer, later return to the current file. */
2175 void
2176 Parse_PushInput(const char *name, unsigned lineno, unsigned readLines,
2177                 Buffer buf, struct ForLoop *forLoop)
2178 {
2179         IncludedFile *curFile;
2180
2181         if (forLoop != NULL)
2182                 name = CurFile()->name.str;
2183         else
2184                 TrackInput(name);
2185
2186         DEBUG3(PARSE, "Parse_PushInput: %s %s, line %u\n",
2187             forLoop != NULL ? ".for loop in": "file", name, lineno);
2188
2189         curFile = Vector_Push(&includes);
2190         curFile->name = FStr_InitOwn(bmake_strdup(name));
2191         curFile->lineno = lineno;
2192         curFile->readLines = readLines;
2193         curFile->forHeadLineno = lineno;
2194         curFile->forBodyReadLines = readLines;
2195         curFile->buf = buf;
2196         curFile->depending = doing_depend;      /* restore this on EOF */
2197         curFile->forLoop = forLoop;
2198
2199         if (forLoop != NULL && !For_NextIteration(forLoop, &curFile->buf))
2200                 abort();        /* see For_Run */
2201
2202         curFile->buf_ptr = curFile->buf.data;
2203         curFile->buf_end = curFile->buf.data + curFile->buf.len;
2204         curFile->condMinDepth = cond_depth;
2205         SetParseFile(name);
2206 }
2207
2208 /* Check if the directive is an include directive. */
2209 static bool
2210 IsInclude(const char *dir, bool sysv)
2211 {
2212         if (dir[0] == 's' || dir[0] == '-' || (dir[0] == 'd' && !sysv))
2213                 dir++;
2214
2215         if (strncmp(dir, "include", 7) != 0)
2216                 return false;
2217
2218         /* Space is not mandatory for BSD .include */
2219         return !sysv || ch_isspace(dir[7]);
2220 }
2221
2222
2223 #ifdef SYSVINCLUDE
2224 /* Check if the line is a SYSV include directive. */
2225 static bool
2226 IsSysVInclude(const char *line)
2227 {
2228         const char *p;
2229
2230         if (!IsInclude(line, true))
2231                 return false;
2232
2233         /* Avoid interpreting a dependency line as an include */
2234         for (p = line; (p = strchr(p, ':')) != NULL;) {
2235
2236                 /* end of line -> it's a dependency */
2237                 if (*++p == '\0')
2238                         return false;
2239
2240                 /* '::' operator or ': ' -> it's a dependency */
2241                 if (*p == ':' || ch_isspace(*p))
2242                         return false;
2243         }
2244         return true;
2245 }
2246
2247 /* Push to another file.  The line points to the word "include". */
2248 static void
2249 ParseTraditionalInclude(char *line)
2250 {
2251         char *cp;               /* current position in file spec */
2252         bool done = false;
2253         bool silent = line[0] != 'i';
2254         char *file = line + (silent ? 8 : 7);
2255         char *all_files;
2256
2257         DEBUG1(PARSE, "ParseTraditionalInclude: %s\n", file);
2258
2259         pp_skip_whitespace(&file);
2260
2261         (void)Var_Subst(file, SCOPE_CMDLINE, VARE_WANTRES, &all_files);
2262         /* TODO: handle errors */
2263
2264         for (file = all_files; !done; file = cp + 1) {
2265                 /* Skip to end of line or next whitespace */
2266                 for (cp = file; *cp != '\0' && !ch_isspace(*cp); cp++)
2267                         continue;
2268
2269                 if (*cp != '\0')
2270                         *cp = '\0';
2271                 else
2272                         done = true;
2273
2274                 IncludeFile(file, false, false, silent);
2275         }
2276
2277         free(all_files);
2278 }
2279 #endif
2280
2281 #ifdef GMAKEEXPORT
2282 /* Parse "export <variable>=<value>", and actually export it. */
2283 static void
2284 ParseGmakeExport(char *line)
2285 {
2286         char *variable = line + 6;
2287         char *value;
2288
2289         DEBUG1(PARSE, "ParseGmakeExport: %s\n", variable);
2290
2291         pp_skip_whitespace(&variable);
2292
2293         for (value = variable; *value != '\0' && *value != '='; value++)
2294                 continue;
2295
2296         if (*value != '=') {
2297                 Parse_Error(PARSE_FATAL,
2298                     "Variable/Value missing from \"export\"");
2299                 return;
2300         }
2301         *value++ = '\0';        /* terminate variable */
2302
2303         /*
2304          * Expand the value before putting it in the environment.
2305          */
2306         (void)Var_Subst(value, SCOPE_CMDLINE, VARE_WANTRES, &value);
2307         /* TODO: handle errors */
2308
2309         setenv(variable, value, 1);
2310         free(value);
2311 }
2312 #endif
2313
2314 /*
2315  * Called when EOF is reached in the current file. If we were reading an
2316  * include file or a .for loop, the includes stack is popped and things set
2317  * up to go back to reading the previous file at the previous location.
2318  *
2319  * Results:
2320  *      true to continue parsing, i.e. it had only reached the end of an
2321  *      included file, false if the main file has been parsed completely.
2322  */
2323 static bool
2324 ParseEOF(void)
2325 {
2326         IncludedFile *curFile = CurFile();
2327
2328         doing_depend = curFile->depending;
2329         if (curFile->forLoop != NULL &&
2330             For_NextIteration(curFile->forLoop, &curFile->buf)) {
2331                 curFile->buf_ptr = curFile->buf.data;
2332                 curFile->buf_end = curFile->buf.data + curFile->buf.len;
2333                 curFile->readLines = curFile->forBodyReadLines;
2334                 return true;
2335         }
2336
2337         Cond_EndFile();
2338
2339         FStr_Done(&curFile->name);
2340         Buf_Done(&curFile->buf);
2341         if (curFile->forLoop != NULL)
2342                 ForLoop_Free(curFile->forLoop);
2343         Vector_Pop(&includes);
2344
2345         if (includes.len == 0) {
2346                 /* We've run out of input */
2347                 Global_Delete(".PARSEDIR");
2348                 Global_Delete(".PARSEFILE");
2349                 Global_Delete(".INCLUDEDFROMDIR");
2350                 Global_Delete(".INCLUDEDFROMFILE");
2351                 return false;
2352         }
2353
2354         curFile = CurFile();
2355         DEBUG2(PARSE, "ParseEOF: returning to file %s, line %u\n",
2356             curFile->name.str, curFile->readLines + 1);
2357
2358         SetParseFile(curFile->name.str);
2359         return true;
2360 }
2361
2362 typedef enum ParseRawLineResult {
2363         PRLR_LINE,
2364         PRLR_EOF,
2365         PRLR_ERROR
2366 } ParseRawLineResult;
2367
2368 /*
2369  * Parse until the end of a line, taking into account lines that end with
2370  * backslash-newline.  The resulting line goes from out_line to out_line_end;
2371  * the line is not null-terminated.
2372  */
2373 static ParseRawLineResult
2374 ParseRawLine(IncludedFile *curFile, char **out_line, char **out_line_end,
2375              char **out_firstBackslash, char **out_commentLineEnd)
2376 {
2377         char *line = curFile->buf_ptr;
2378         char *buf_end = curFile->buf_end;
2379         char *p = line;
2380         char *line_end = line;
2381         char *firstBackslash = NULL;
2382         char *commentLineEnd = NULL;
2383         ParseRawLineResult res = PRLR_LINE;
2384
2385         curFile->readLines++;
2386
2387         for (;;) {
2388                 char ch;
2389
2390                 if (p == buf_end) {
2391                         res = PRLR_EOF;
2392                         break;
2393                 }
2394
2395                 ch = *p;
2396                 if (ch == '\0' || (ch == '\\' && p[1] == '\0')) {
2397                         Parse_Error(PARSE_FATAL, "Zero byte read from file");
2398                         return PRLR_ERROR;
2399                 }
2400
2401                 /* Treat next character after '\' as literal. */
2402                 if (ch == '\\') {
2403                         if (firstBackslash == NULL)
2404                                 firstBackslash = p;
2405                         if (p[1] == '\n') {
2406                                 curFile->readLines++;
2407                                 if (p + 2 == buf_end) {
2408                                         line_end = p;
2409                                         *line_end = '\n';
2410                                         p += 2;
2411                                         continue;
2412                                 }
2413                         }
2414                         p += 2;
2415                         line_end = p;
2416                         assert(p <= buf_end);
2417                         continue;
2418                 }
2419
2420                 /*
2421                  * Remember the first '#' for comment stripping, unless
2422                  * the previous char was '[', as in the modifier ':[#]'.
2423                  */
2424                 if (ch == '#' && commentLineEnd == NULL &&
2425                     !(p > line && p[-1] == '['))
2426                         commentLineEnd = line_end;
2427
2428                 p++;
2429                 if (ch == '\n')
2430                         break;
2431
2432                 /* We are not interested in trailing whitespace. */
2433                 if (!ch_isspace(ch))
2434                         line_end = p;
2435         }
2436
2437         curFile->buf_ptr = p;
2438         *out_line = line;
2439         *out_line_end = line_end;
2440         *out_firstBackslash = firstBackslash;
2441         *out_commentLineEnd = commentLineEnd;
2442         return res;
2443 }
2444
2445 /*
2446  * Beginning at start, unescape '\#' to '#' and replace backslash-newline
2447  * with a single space.
2448  */
2449 static void
2450 UnescapeBackslash(char *line, char *start)
2451 {
2452         const char *src = start;
2453         char *dst = start;
2454         char *spaceStart = line;
2455
2456         for (;;) {
2457                 char ch = *src++;
2458                 if (ch != '\\') {
2459                         if (ch == '\0')
2460                                 break;
2461                         *dst++ = ch;
2462                         continue;
2463                 }
2464
2465                 ch = *src++;
2466                 if (ch == '\0') {
2467                         /* Delete '\\' at the end of the buffer. */
2468                         dst--;
2469                         break;
2470                 }
2471
2472                 /* Delete '\\' from before '#' on non-command lines. */
2473                 if (ch == '#' && line[0] != '\t')
2474                         *dst++ = ch;
2475                 else if (ch == '\n') {
2476                         cpp_skip_hspace(&src);
2477                         *dst++ = ' ';
2478                 } else {
2479                         /* Leave '\\' in the buffer for later. */
2480                         *dst++ = '\\';
2481                         *dst++ = ch;
2482                         /* Keep an escaped ' ' at the line end. */
2483                         spaceStart = dst;
2484                 }
2485         }
2486
2487         /* Delete any trailing spaces - eg from empty continuations */
2488         while (dst > spaceStart && ch_isspace(dst[-1]))
2489                 dst--;
2490         *dst = '\0';
2491 }
2492
2493 typedef enum LineKind {
2494         /*
2495          * Return the next line that is neither empty nor a comment.
2496          * Backslash line continuations are folded into a single space.
2497          * A trailing comment, if any, is discarded.
2498          */
2499         LK_NONEMPTY,
2500
2501         /*
2502          * Return the next line, even if it is empty or a comment.
2503          * Preserve backslash-newline to keep the line numbers correct.
2504          *
2505          * Used in .for loops to collect the body of the loop while waiting
2506          * for the corresponding .endfor.
2507          */
2508         LK_FOR_BODY,
2509
2510         /*
2511          * Return the next line that starts with a dot.
2512          * Backslash line continuations are folded into a single space.
2513          * A trailing comment, if any, is discarded.
2514          *
2515          * Used in .if directives to skip over irrelevant branches while
2516          * waiting for the corresponding .endif.
2517          */
2518         LK_DOT
2519 } LineKind;
2520
2521 /*
2522  * Return the next "interesting" logical line from the current file.  The
2523  * returned string will be freed at the end of including the file.
2524  */
2525 static char *
2526 ReadLowLevelLine(LineKind kind)
2527 {
2528         IncludedFile *curFile = CurFile();
2529         ParseRawLineResult res;
2530         char *line;
2531         char *line_end;
2532         char *firstBackslash;
2533         char *commentLineEnd;
2534
2535         for (;;) {
2536                 curFile->lineno = curFile->readLines + 1;
2537                 res = ParseRawLine(curFile,
2538                     &line, &line_end, &firstBackslash, &commentLineEnd);
2539                 if (res == PRLR_ERROR)
2540                         return NULL;
2541
2542                 if (line == line_end || line == commentLineEnd) {
2543                         if (res == PRLR_EOF)
2544                                 return NULL;
2545                         if (kind != LK_FOR_BODY)
2546                                 continue;
2547                 }
2548
2549                 /* We now have a line of data */
2550                 assert(ch_isspace(*line_end));
2551                 *line_end = '\0';
2552
2553                 if (kind == LK_FOR_BODY)
2554                         return line;    /* Don't join the physical lines. */
2555
2556                 if (kind == LK_DOT && line[0] != '.')
2557                         continue;
2558                 break;
2559         }
2560
2561         if (commentLineEnd != NULL && line[0] != '\t')
2562                 *commentLineEnd = '\0';
2563         if (firstBackslash != NULL)
2564                 UnescapeBackslash(line, firstBackslash);
2565         return line;
2566 }
2567
2568 static bool
2569 SkipIrrelevantBranches(void)
2570 {
2571         const char *line;
2572
2573         while ((line = ReadLowLevelLine(LK_DOT)) != NULL) {
2574                 if (Cond_EvalLine(line) == CR_TRUE)
2575                         return true;
2576                 /*
2577                  * TODO: Check for typos in .elif directives such as .elsif
2578                  * or .elseif.
2579                  *
2580                  * This check will probably duplicate some of the code in
2581                  * ParseLine.  Most of the code there cannot apply, only
2582                  * ParseVarassign and ParseDependencyLine can, and to prevent
2583                  * code duplication, these would need to be called with a
2584                  * flag called onlyCheckSyntax.
2585                  *
2586                  * See directive-elif.mk for details.
2587                  */
2588         }
2589
2590         return false;
2591 }
2592
2593 static bool
2594 ParseForLoop(const char *line)
2595 {
2596         int rval;
2597         unsigned forHeadLineno;
2598         unsigned bodyReadLines;
2599         int forLevel;
2600
2601         rval = For_Eval(line);
2602         if (rval == 0)
2603                 return false;   /* Not a .for line */
2604         if (rval < 0)
2605                 return true;    /* Syntax error - error printed, ignore line */
2606
2607         forHeadLineno = CurFile()->lineno;
2608         bodyReadLines = CurFile()->readLines;
2609
2610         /* Accumulate the loop body until the matching '.endfor'. */
2611         forLevel = 1;
2612         do {
2613                 line = ReadLowLevelLine(LK_FOR_BODY);
2614                 if (line == NULL) {
2615                         Parse_Error(PARSE_FATAL,
2616                             "Unexpected end of file in .for loop");
2617                         break;
2618                 }
2619         } while (For_Accum(line, &forLevel));
2620
2621         For_Run(forHeadLineno, bodyReadLines);
2622         return true;
2623 }
2624
2625 /*
2626  * Read an entire line from the input file.
2627  *
2628  * Empty lines, .if and .for are completely handled by this function,
2629  * leaving only variable assignments, other directives, dependency lines
2630  * and shell commands to the caller.
2631  *
2632  * Return a line without trailing whitespace, or NULL for EOF.  The returned
2633  * string will be freed at the end of including the file.
2634  */
2635 static char *
2636 ReadHighLevelLine(void)
2637 {
2638         char *line;
2639
2640         for (;;) {
2641                 line = ReadLowLevelLine(LK_NONEMPTY);
2642                 if (posix_state == PS_MAYBE_NEXT_LINE)
2643                         posix_state = PS_NOW_OR_NEVER;
2644                 else
2645                         posix_state = PS_TOO_LATE;
2646                 if (line == NULL)
2647                         return NULL;
2648
2649                 if (line[0] != '.')
2650                         return line;
2651
2652                 switch (Cond_EvalLine(line)) {
2653                 case CR_FALSE:  /* May also mean a syntax error. */
2654                         if (!SkipIrrelevantBranches())
2655                                 return NULL;
2656                         continue;
2657                 case CR_TRUE:
2658                         continue;
2659                 case CR_ERROR:  /* Not a conditional line */
2660                         if (ParseForLoop(line))
2661                                 continue;
2662                         break;
2663                 }
2664                 return line;
2665         }
2666 }
2667
2668 static void
2669 FinishDependencyGroup(void)
2670 {
2671         GNodeListNode *ln;
2672
2673         if (targets == NULL)
2674                 return;
2675
2676         for (ln = targets->first; ln != NULL; ln = ln->next) {
2677                 GNode *gn = ln->datum;
2678
2679                 Suff_EndTransform(gn);
2680
2681                 /*
2682                  * Mark the target as already having commands if it does, to
2683                  * keep from having shell commands on multiple dependency
2684                  * lines.
2685                  */
2686                 if (!Lst_IsEmpty(&gn->commands))
2687                         gn->type |= OP_HAS_COMMANDS;
2688         }
2689
2690         Lst_Free(targets);
2691         targets = NULL;
2692 }
2693
2694 /* Add the command to each target from the current dependency spec. */
2695 static void
2696 ParseLine_ShellCommand(const char *p)
2697 {
2698         cpp_skip_whitespace(&p);
2699         if (*p == '\0')
2700                 return;         /* skip empty commands */
2701
2702         if (targets == NULL) {
2703                 Parse_Error(PARSE_FATAL,
2704                     "Unassociated shell command \"%s\"", p);
2705                 return;
2706         }
2707
2708         {
2709                 char *cmd = bmake_strdup(p);
2710                 GNodeListNode *ln;
2711
2712                 for (ln = targets->first; ln != NULL; ln = ln->next) {
2713                         GNode *gn = ln->datum;
2714                         GNode_AddCommand(gn, cmd);
2715                 }
2716 #ifdef CLEANUP
2717                 Lst_Append(&targCmds, cmd);
2718 #endif
2719         }
2720 }
2721
2722 static void
2723 HandleBreak(void)
2724 {
2725         IncludedFile *curFile = CurFile();
2726
2727         if (curFile->forLoop != NULL) {
2728                 /* pretend we reached EOF */
2729                 For_Break(curFile->forLoop);
2730                 cond_depth = CurFile_CondMinDepth();
2731                 ParseEOF();
2732         } else
2733                 Parse_Error(PARSE_FATAL, "break outside of for loop");
2734 }
2735
2736 /*
2737  * See if the line starts with one of the known directives, and if so, handle
2738  * the directive.
2739  */
2740 static bool
2741 ParseDirective(char *line)
2742 {
2743         char *cp = line + 1;
2744         const char *arg;
2745         Substring dir;
2746
2747         pp_skip_whitespace(&cp);
2748         if (IsInclude(cp, false)) {
2749                 ParseInclude(cp);
2750                 return true;
2751         }
2752
2753         dir.start = cp;
2754         while (ch_islower(*cp) || *cp == '-')
2755                 cp++;
2756         dir.end = cp;
2757
2758         if (*cp != '\0' && !ch_isspace(*cp))
2759                 return false;
2760
2761         pp_skip_whitespace(&cp);
2762         arg = cp;
2763
2764         if (Substring_Equals(dir, "break"))
2765                 HandleBreak();
2766         else if (Substring_Equals(dir, "undef"))
2767                 Var_Undef(arg);
2768         else if (Substring_Equals(dir, "export"))
2769                 Var_Export(VEM_PLAIN, arg);
2770         else if (Substring_Equals(dir, "export-env"))
2771                 Var_Export(VEM_ENV, arg);
2772         else if (Substring_Equals(dir, "export-literal"))
2773                 Var_Export(VEM_LITERAL, arg);
2774         else if (Substring_Equals(dir, "unexport"))
2775                 Var_UnExport(false, arg);
2776         else if (Substring_Equals(dir, "unexport-env"))
2777                 Var_UnExport(true, arg);
2778         else if (Substring_Equals(dir, "info"))
2779                 HandleMessage(PARSE_INFO, "info", arg);
2780         else if (Substring_Equals(dir, "warning"))
2781                 HandleMessage(PARSE_WARNING, "warning", arg);
2782         else if (Substring_Equals(dir, "error"))
2783                 HandleMessage(PARSE_FATAL, "error", arg);
2784         else
2785                 return false;
2786         return true;
2787 }
2788
2789 bool
2790 Parse_VarAssign(const char *line, bool finishDependencyGroup, GNode *scope)
2791 {
2792         VarAssign var;
2793
2794         if (!Parse_IsVar(line, &var))
2795                 return false;
2796         if (finishDependencyGroup)
2797                 FinishDependencyGroup();
2798         Parse_Var(&var, scope);
2799         free(var.varname);
2800         return true;
2801 }
2802
2803 static char *
2804 FindSemicolon(char *p)
2805 {
2806         int level = 0;
2807
2808         for (; *p != '\0'; p++) {
2809                 if (*p == '\\' && p[1] != '\0') {
2810                         p++;
2811                         continue;
2812                 }
2813
2814                 if (*p == '$' && (p[1] == '(' || p[1] == '{'))
2815                         level++;
2816                 else if (level > 0 && (*p == ')' || *p == '}'))
2817                         level--;
2818                 else if (level == 0 && *p == ';')
2819                         break;
2820         }
2821         return p;
2822 }
2823
2824 /*
2825  * dependency   -> [target...] op [source...] [';' command]
2826  * op           -> ':' | '::' | '!'
2827  */
2828 static void
2829 ParseDependencyLine(char *line)
2830 {
2831         VarEvalMode emode;
2832         char *expanded_line;
2833         const char *shellcmd = NULL;
2834
2835         /*
2836          * For some reason - probably to make the parser impossible -
2837          * a ';' can be used to separate commands from dependencies.
2838          * Attempt to skip over ';' inside substitution patterns.
2839          */
2840         {
2841                 char *semicolon = FindSemicolon(line);
2842                 if (*semicolon != '\0') {
2843                         /* Terminate the dependency list at the ';' */
2844                         *semicolon = '\0';
2845                         shellcmd = semicolon + 1;
2846                 }
2847         }
2848
2849         /*
2850          * We now know it's a dependency line so it needs to have all
2851          * variables expanded before being parsed.
2852          *
2853          * XXX: Ideally the dependency line would first be split into
2854          * its left-hand side, dependency operator and right-hand side,
2855          * and then each side would be expanded on its own.  This would
2856          * allow for the left-hand side to allow only defined variables
2857          * and to allow variables on the right-hand side to be undefined
2858          * as well.
2859          *
2860          * Parsing the line first would also prevent that targets
2861          * generated from variable expressions are interpreted as the
2862          * dependency operator, such as in "target${:U\:} middle: source",
2863          * in which the middle is interpreted as a source, not a target.
2864          */
2865
2866         /*
2867          * In lint mode, allow undefined variables to appear in dependency
2868          * lines.
2869          *
2870          * Ideally, only the right-hand side would allow undefined variables
2871          * since it is common to have optional dependencies. Having undefined
2872          * variables on the left-hand side is more unusual though.  Since
2873          * both sides are expanded in a single pass, there is not much choice
2874          * what to do here.
2875          *
2876          * In normal mode, it does not matter whether undefined variables are
2877          * allowed or not since as of 2020-09-14, Var_Parse does not print
2878          * any parse errors in such a case. It simply returns the special
2879          * empty string var_Error, which cannot be detected in the result of
2880          * Var_Subst.
2881          */
2882         emode = opts.strict ? VARE_WANTRES : VARE_UNDEFERR;
2883         (void)Var_Subst(line, SCOPE_CMDLINE, emode, &expanded_line);
2884         /* TODO: handle errors */
2885
2886         /* Need a fresh list for the target nodes */
2887         if (targets != NULL)
2888                 Lst_Free(targets);
2889         targets = Lst_New();
2890
2891         ParseDependency(expanded_line);
2892         free(expanded_line);
2893
2894         if (shellcmd != NULL)
2895                 ParseLine_ShellCommand(shellcmd);
2896 }
2897
2898 static void
2899 ParseLine(char *line)
2900 {
2901         /*
2902          * Lines that begin with '.' can be pretty much anything:
2903          *      - directives like '.include' or '.if',
2904          *      - suffix rules like '.c.o:',
2905          *      - dependencies for filenames that start with '.',
2906          *      - variable assignments like '.tmp=value'.
2907          */
2908         if (line[0] == '.' && ParseDirective(line))
2909                 return;
2910
2911         if (line[0] == '\t') {
2912                 ParseLine_ShellCommand(line + 1);
2913                 return;
2914         }
2915
2916 #ifdef SYSVINCLUDE
2917         if (IsSysVInclude(line)) {
2918                 /*
2919                  * It's an S3/S5-style "include".
2920                  */
2921                 ParseTraditionalInclude(line);
2922                 return;
2923         }
2924 #endif
2925
2926 #ifdef GMAKEEXPORT
2927         if (strncmp(line, "export", 6) == 0 && ch_isspace(line[6]) &&
2928             strchr(line, ':') == NULL) {
2929                 /*
2930                  * It's a Gmake "export".
2931                  */
2932                 ParseGmakeExport(line);
2933                 return;
2934         }
2935 #endif
2936
2937         if (Parse_VarAssign(line, true, SCOPE_GLOBAL))
2938                 return;
2939
2940         FinishDependencyGroup();
2941
2942         ParseDependencyLine(line);
2943 }
2944
2945 /*
2946  * Parse a top-level makefile, incorporating its content into the global
2947  * dependency graph.
2948  */
2949 void
2950 Parse_File(const char *name, int fd)
2951 {
2952         char *line;
2953         Buffer buf;
2954
2955         buf = LoadFile(name, fd != -1 ? fd : STDIN_FILENO);
2956         if (fd != -1)
2957                 (void)close(fd);
2958
2959         assert(targets == NULL);
2960
2961         Parse_PushInput(name, 1, 0, buf, NULL);
2962
2963         do {
2964                 while ((line = ReadHighLevelLine()) != NULL) {
2965                         DEBUG2(PARSE, "Parsing line %u: %s\n",
2966                             CurFile()->lineno, line);
2967                         ParseLine(line);
2968                 }
2969                 /* Reached EOF, but it may be just EOF of an include file. */
2970         } while (ParseEOF());
2971
2972         FinishDependencyGroup();
2973
2974         if (parseErrors != 0) {
2975                 (void)fflush(stdout);
2976                 (void)fprintf(stderr,
2977                     "%s: Fatal errors encountered -- cannot continue\n",
2978                     progname);
2979                 PrintOnError(NULL, "");
2980                 exit(1);
2981         }
2982 }
2983
2984 /* Initialize the parsing module. */
2985 void
2986 Parse_Init(void)
2987 {
2988         mainNode = NULL;
2989         parseIncPath = SearchPath_New();
2990         sysIncPath = SearchPath_New();
2991         defSysIncPath = SearchPath_New();
2992         Vector_Init(&includes, sizeof(IncludedFile));
2993 }
2994
2995 /* Clean up the parsing module. */
2996 void
2997 Parse_End(void)
2998 {
2999 #ifdef CLEANUP
3000         Lst_DoneCall(&targCmds, free);
3001         assert(targets == NULL);
3002         SearchPath_Free(defSysIncPath);
3003         SearchPath_Free(sysIncPath);
3004         SearchPath_Free(parseIncPath);
3005         assert(includes.len == 0);
3006         Vector_Done(&includes);
3007 #endif
3008 }
3009
3010
3011 /*
3012  * Return a list containing the single main target to create.
3013  * If no such target exists, we Punt with an obnoxious error message.
3014  */
3015 void
3016 Parse_MainName(GNodeList *mainList)
3017 {
3018         if (mainNode == NULL)
3019                 Punt("no target to make.");
3020
3021         Lst_Append(mainList, mainNode);
3022         if (mainNode->type & OP_DOUBLEDEP)
3023                 Lst_AppendAll(mainList, &mainNode->cohorts);
3024
3025         Global_Append(".TARGETS", mainNode->name);
3026 }
3027
3028 int
3029 Parse_NumErrors(void)
3030 {
3031         return parseErrors;
3032 }