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