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