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