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