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