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