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