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