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