[BACK]Return to parse.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.bin / make

Annotation of src/usr.bin/make/parse.c, Revision 1.624

1.624   ! rillig      1: /*     $NetBSD: parse.c,v 1.623 2022/01/07 09:19:43 rillig Exp $       */
1.15      christos    2:
1.1       cgd         3: /*
1.27      christos    4:  * Copyright (c) 1988, 1989, 1990, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
1.94      agc         6:  *
                      7:  * This code is derived from software contributed to Berkeley by
                      8:  * Adam de Boor.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. Neither the name of the University nor the names of its contributors
                     19:  *    may be used to endorse or promote products derived from this software
                     20:  *    without specific prior written permission.
                     21:  *
                     22:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     23:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     24:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     25:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     26:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     27:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     28:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     29:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     30:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     31:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     32:  * SUCH DAMAGE.
                     33:  */
                     34:
                     35: /*
1.1       cgd        36:  * Copyright (c) 1989 by Berkeley Softworks
                     37:  * All rights reserved.
                     38:  *
                     39:  * This code is derived from software contributed to Berkeley by
                     40:  * Adam de Boor.
                     41:  *
                     42:  * Redistribution and use in source and binary forms, with or without
                     43:  * modification, are permitted provided that the following conditions
                     44:  * are met:
                     45:  * 1. Redistributions of source code must retain the above copyright
                     46:  *    notice, this list of conditions and the following disclaimer.
                     47:  * 2. Redistributions in binary form must reproduce the above copyright
                     48:  *    notice, this list of conditions and the following disclaimer in the
                     49:  *    documentation and/or other materials provided with the distribution.
                     50:  * 3. All advertising materials mentioning features or use of this software
                     51:  *    must display the following acknowledgement:
                     52:  *     This product includes software developed by the University of
                     53:  *     California, Berkeley and its contributors.
                     54:  * 4. Neither the name of the University nor the names of its contributors
                     55:  *    may be used to endorse or promote products derived from this software
                     56:  *    without specific prior written permission.
                     57:  *
                     58:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     59:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     60:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     61:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     62:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     63:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     64:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     65:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     66:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     67:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     68:  * SUCH DAMAGE.
                     69:  */
                     70:
1.402     rillig     71: /*
                     72:  * Parsing of makefiles.
                     73:  *
                     74:  * Parse_File is the main entry point and controls most of the other
                     75:  * functions in this module.
1.1       cgd        76:  *
                     77:  * Interface:
1.402     rillig     78:  *     Parse_Init      Initialize the module
1.338     rillig     79:  *
1.383     rillig     80:  *     Parse_End       Clean up the module
1.338     rillig     81:  *
1.402     rillig     82:  *     Parse_File      Parse a top-level makefile.  Included files are
1.537     rillig     83:  *                     handled by IncludeFile instead.
1.402     rillig     84:  *
1.609     rillig     85:  *     Parse_VarAssign
                     86:  *                     Try to parse the given line as a variable assignment.
                     87:  *                     Used by MainParseArgs to determine if an argument is
                     88:  *                     a target or a variable assignment.  Used internally
                     89:  *                     for pretty much the same thing.
1.402     rillig     90:  *
                     91:  *     Parse_Error     Report a parse error, a warning or an informational
                     92:  *                     message.
1.338     rillig     93:  *
1.609     rillig     94:  *     Parse_MainName  Returns a list of the single main target to create.
1.1       cgd        95:  */
                     96:
1.170     dholland   97: #include <sys/types.h>
1.171     dholland   98: #include <sys/stat.h>
1.84      wiz        99: #include <errno.h>
1.5       cgd       100: #include <stdarg.h>
1.225     maya      101: #include <stdint.h>
1.84      wiz       102:
1.1       cgd       103: #include "make.h"
1.5       cgd       104: #include "dir.h"
                    105: #include "job.h"
1.1       cgd       106: #include "pathnames.h"
                    107:
1.303     rillig    108: /*     "@(#)parse.c    8.3 (Berkeley) 3/19/94" */
1.624   ! rillig    109: MAKE_RCSID("$NetBSD: parse.c,v 1.623 2022/01/07 09:19:43 rillig Exp $");
1.166     dholland  110:
1.1       cgd       111: /*
1.166     dholland  112:  * Structure for a file being read ("included file")
1.1       cgd       113:  */
                    114: typedef struct IFile {
1.576     rillig    115:        FStr name;              /* absolute or relative to the cwd */
1.469     rillig    116:        int lineno;             /* current line number in file */
1.618     rillig    117:        int forBodyLineno;      /* start of the .for loop body, 0-based */
1.469     rillig    118:        unsigned int cond_depth; /* 'if' nesting when file opened */
1.618     rillig    119:        bool depending;         /* state of doing_depend on EOF */
1.469     rillig    120:
1.618     rillig    121:        Buffer buf;             /* the file's content or the body of the .for
                    122:                                 * loop; always ends with '\n' */
1.469     rillig    123:        char *buf_ptr;          /* next char to be read */
1.571     rillig    124:        char *buf_end;          /* buf_end[-1] == '\n' */
1.469     rillig    125:
1.616     rillig    126:        struct ForLoop *forLoop;
1.5       cgd       127: } IFile;
1.1       cgd       128:
1.166     dholland  129: /*
                    130:  * Tokens for target attributes
1.1       cgd       131:  */
1.386     rillig    132: typedef enum ParseSpecial {
1.469     rillig    133:        SP_ATTRIBUTE,   /* Generic attribute */
                    134:        SP_BEGIN,       /* .BEGIN */
                    135:        SP_DEFAULT,     /* .DEFAULT */
                    136:        SP_DELETE_ON_ERROR, /* .DELETE_ON_ERROR */
                    137:        SP_END,         /* .END */
                    138:        SP_ERROR,       /* .ERROR */
                    139:        SP_IGNORE,      /* .IGNORE */
                    140:        SP_INCLUDES,    /* .INCLUDES; not mentioned in the manual page */
                    141:        SP_INTERRUPT,   /* .INTERRUPT */
                    142:        SP_LIBS,        /* .LIBS; not mentioned in the manual page */
1.589     rillig    143:        SP_MAIN,        /* .MAIN and no user-specified targets to make */
1.469     rillig    144:        SP_META,        /* .META */
                    145:        SP_MFLAGS,      /* .MFLAGS or .MAKEFLAGS */
                    146:        SP_NOMETA,      /* .NOMETA */
                    147:        SP_NOMETA_CMP,  /* .NOMETA_CMP */
                    148:        SP_NOPATH,      /* .NOPATH */
                    149:        SP_NOT,         /* Not special */
                    150:        SP_NOTPARALLEL, /* .NOTPARALLEL or .NO_PARALLEL */
                    151:        SP_NULL,        /* .NULL; not mentioned in the manual page */
                    152:        SP_OBJDIR,      /* .OBJDIR */
                    153:        SP_ORDER,       /* .ORDER */
                    154:        SP_PARALLEL,    /* .PARALLEL; not mentioned in the manual page */
                    155:        SP_PATH,        /* .PATH or .PATH.suffix */
                    156:        SP_PHONY,       /* .PHONY */
1.48      sjg       157: #ifdef POSIX
1.469     rillig    158:        SP_POSIX,       /* .POSIX; not mentioned in the manual page */
1.48      sjg       159: #endif
1.469     rillig    160:        SP_PRECIOUS,    /* .PRECIOUS */
                    161:        SP_SHELL,       /* .SHELL */
                    162:        SP_SILENT,      /* .SILENT */
                    163:        SP_SINGLESHELL, /* .SINGLESHELL; not mentioned in the manual page */
                    164:        SP_STALE,       /* .STALE */
                    165:        SP_SUFFIXES,    /* .SUFFIXES */
                    166:        SP_WAIT         /* .WAIT */
1.1       cgd       167: } ParseSpecial;
                    168:
1.368     rillig    169: typedef List SearchPathList;
1.392     rillig    170: typedef ListNode SearchPathListNode;
1.368     rillig    171:
1.166     dholland  172: /*
1.589     rillig    173:  * The main target to create. This is the first target defined in any of the
                    174:  * makefiles.
1.166     dholland  175:  */
                    176: static GNode *mainNode;
                    177:
1.524     rillig    178: /*
                    179:  * During parsing, the targets from the left-hand side of the currently
1.415     rillig    180:  * active dependency line, or NULL if the current line does not belong to a
                    181:  * dependency line, for example because it is a variable assignment.
1.318     rillig    182:  *
1.524     rillig    183:  * See unit-tests/deptgt.mk, keyword "parse.c:targets".
                    184:  */
1.322     rillig    185: static GNodeList *targets;
1.166     dholland  186:
                    187: #ifdef CLEANUP
1.524     rillig    188: /*
                    189:  * All shell commands for all targets, in no particular order and possibly
1.372     rillig    190:  * with duplicates.  Kept in a separate list since the commands from .USE or
                    191:  * .USEBEFORE nodes are shared with other GNodes, thereby giving up the
1.524     rillig    192:  * easily understandable ownership over the allocated strings.
                    193:  */
1.461     rillig    194: static StringList targCmds = LST_INIT;
1.166     dholland  195: #endif
                    196:
                    197: /*
1.152     dsl       198:  * Predecessor node for handling .ORDER. Initialized to NULL when .ORDER
1.1       cgd       199:  * seen, then set to each successive source on the line.
                    200:  */
1.407     rillig    201: static GNode *order_pred;
1.1       cgd       202:
1.166     dholland  203: /* number of fatal errors */
1.561     rillig    204: static int parseErrors = 0;
1.166     dholland  205:
                    206: /*
1.532     rillig    207:  * The include chain of makefiles.  At index 0 is the top-level makefile from
                    208:  * the command line, followed by the included files or .for loops, up to and
                    209:  * including the current file.
                    210:  *
                    211:  * See PrintStackTrace for how to interpret the data.
1.319     rillig    212:  */
1.408     rillig    213: static Vector /* of IFile */ includes;
1.400     rillig    214:
1.549     rillig    215: SearchPath *parseIncPath;      /* directories for "..." includes */
                    216: SearchPath *sysIncPath;                /* directories for <...> includes */
1.414     rillig    217: SearchPath *defSysIncPath;     /* default for sysIncPath */
1.166     dholland  218:
1.1       cgd       219: /*
                    220:  * The parseKeywords table is searched using binary search when deciding
                    221:  * if a target or source is special. The 'spec' field is the ParseSpecial
1.404     rillig    222:  * type of the keyword (SP_NOT if the keyword isn't special as a target) while
1.1       cgd       223:  * the 'op' field is the operator to apply to the list of targets if the
                    224:  * keyword is used as a source ("0" if the keyword isn't special as a source)
                    225:  */
1.168     dholland  226: static const struct {
1.590     rillig    227:        const char name[17];
                    228:        ParseSpecial special;   /* when used as a target */
                    229:        GNodeType targetAttr;   /* when used as a source */
1.1       cgd       230: } parseKeywords[] = {
1.466     rillig    231:     { ".BEGIN",                SP_BEGIN,       OP_NONE },
                    232:     { ".DEFAULT",      SP_DEFAULT,     OP_NONE },
                    233:     { ".DELETE_ON_ERROR", SP_DELETE_ON_ERROR, OP_NONE },
                    234:     { ".END",          SP_END,         OP_NONE },
                    235:     { ".ERROR",                SP_ERROR,       OP_NONE },
1.404     rillig    236:     { ".EXEC",         SP_ATTRIBUTE,   OP_EXEC },
                    237:     { ".IGNORE",       SP_IGNORE,      OP_IGNORE },
1.466     rillig    238:     { ".INCLUDES",     SP_INCLUDES,    OP_NONE },
                    239:     { ".INTERRUPT",    SP_INTERRUPT,   OP_NONE },
1.404     rillig    240:     { ".INVISIBLE",    SP_ATTRIBUTE,   OP_INVISIBLE },
                    241:     { ".JOIN",         SP_ATTRIBUTE,   OP_JOIN },
1.466     rillig    242:     { ".LIBS",         SP_LIBS,        OP_NONE },
1.404     rillig    243:     { ".MADE",         SP_ATTRIBUTE,   OP_MADE },
1.466     rillig    244:     { ".MAIN",         SP_MAIN,        OP_NONE },
1.404     rillig    245:     { ".MAKE",         SP_ATTRIBUTE,   OP_MAKE },
1.466     rillig    246:     { ".MAKEFLAGS",    SP_MFLAGS,      OP_NONE },
1.404     rillig    247:     { ".META",         SP_META,        OP_META },
1.466     rillig    248:     { ".MFLAGS",       SP_MFLAGS,      OP_NONE },
1.404     rillig    249:     { ".NOMETA",       SP_NOMETA,      OP_NOMETA },
                    250:     { ".NOMETA_CMP",   SP_NOMETA_CMP,  OP_NOMETA_CMP },
                    251:     { ".NOPATH",       SP_NOPATH,      OP_NOPATH },
                    252:     { ".NOTMAIN",      SP_ATTRIBUTE,   OP_NOTMAIN },
1.466     rillig    253:     { ".NOTPARALLEL",  SP_NOTPARALLEL, OP_NONE },
                    254:     { ".NO_PARALLEL",  SP_NOTPARALLEL, OP_NONE },
                    255:     { ".NULL",         SP_NULL,        OP_NONE },
                    256:     { ".OBJDIR",       SP_OBJDIR,      OP_NONE },
1.404     rillig    257:     { ".OPTIONAL",     SP_ATTRIBUTE,   OP_OPTIONAL },
1.466     rillig    258:     { ".ORDER",                SP_ORDER,       OP_NONE },
                    259:     { ".PARALLEL",     SP_PARALLEL,    OP_NONE },
                    260:     { ".PATH",         SP_PATH,        OP_NONE },
1.404     rillig    261:     { ".PHONY",                SP_PHONY,       OP_PHONY },
1.48      sjg       262: #ifdef POSIX
1.466     rillig    263:     { ".POSIX",                SP_POSIX,       OP_NONE },
1.48      sjg       264: #endif
1.404     rillig    265:     { ".PRECIOUS",     SP_PRECIOUS,    OP_PRECIOUS },
                    266:     { ".RECURSIVE",    SP_ATTRIBUTE,   OP_MAKE },
1.466     rillig    267:     { ".SHELL",                SP_SHELL,       OP_NONE },
1.404     rillig    268:     { ".SILENT",       SP_SILENT,      OP_SILENT },
1.466     rillig    269:     { ".SINGLESHELL",  SP_SINGLESHELL, OP_NONE },
                    270:     { ".STALE",                SP_STALE,       OP_NONE },
                    271:     { ".SUFFIXES",     SP_SUFFIXES,    OP_NONE },
1.404     rillig    272:     { ".USE",          SP_ATTRIBUTE,   OP_USE },
                    273:     { ".USEBEFORE",    SP_ATTRIBUTE,   OP_USEBEFORE },
1.466     rillig    274:     { ".WAIT",         SP_WAIT,        OP_NONE },
1.1       cgd       275: };
                    276:
1.170     dholland  277:
1.618     rillig    278: static IFile *
                    279: GetInclude(size_t i)
                    280: {
                    281:        return Vector_Get(&includes, i);
                    282: }
                    283:
                    284: /* The file that is currently being read. */
                    285: static IFile *
                    286: CurFile(void)
                    287: {
                    288:        return GetInclude(includes.len - 1);
                    289: }
                    290:
1.616     rillig    291: static Buffer
1.414     rillig    292: loadfile(const char *path, int fd)
                    293: {
1.522     rillig    294:        ssize_t n;
                    295:        Buffer buf;
1.612     rillig    296:        size_t bufSize;
                    297:        struct stat st;
1.414     rillig    298:
1.612     rillig    299:        bufSize = fstat(fd, &st) == 0 && S_ISREG(st.st_mode) &&
1.620     rillig    300:                  st.st_size >= 1 && st.st_size <= 0x3fffffff
1.612     rillig    301:            ? (size_t)st.st_size : 1024;
                    302:        Buf_InitSize(&buf, bufSize);
1.170     dholland  303:
1.428     rillig    304:        for (;;) {
1.522     rillig    305:                if (buf.len == buf.cap) {
                    306:                        if (buf.cap > 0x1fffffff) {
1.221     riastrad  307:                                errno = EFBIG;
                    308:                                Error("%s: file too large", path);
1.518     rillig    309:                                exit(2); /* Not 1 so -q can distinguish error */
1.221     riastrad  310:                        }
1.523     rillig    311:                        Buf_Expand(&buf);
1.170     dholland  312:                }
1.522     rillig    313:                assert(buf.len < buf.cap);
                    314:                n = read(fd, buf.data + buf.len, buf.cap - buf.len);
                    315:                if (n < 0) {
1.170     dholland  316:                        Error("%s: read error: %s", path, strerror(errno));
1.518     rillig    317:                        exit(2);        /* Not 1 so -q can distinguish error */
1.170     dholland  318:                }
1.522     rillig    319:                if (n == 0)
1.170     dholland  320:                        break;
1.430     rillig    321:
1.522     rillig    322:                buf.len += (size_t)n;
1.170     dholland  323:        }
1.522     rillig    324:        assert(buf.len <= buf.cap);
1.170     dholland  325:
1.522     rillig    326:        if (!Buf_EndsWith(&buf, '\n'))
                    327:                Buf_AddByte(&buf, '\n');
1.170     dholland  328:
1.616     rillig    329:        return buf;
1.170     dholland  330: }
                    331:
1.532     rillig    332: static void
                    333: PrintStackTrace(void)
                    334: {
                    335:        const IFile *entries;
                    336:        size_t i, n;
                    337:
1.612     rillig    338:        if (!DEBUG(PARSE))
1.532     rillig    339:                return;
                    340:
                    341:        entries = GetInclude(0);
                    342:        n = includes.len;
                    343:        if (n == 0)
                    344:                return;
                    345:        n--;                    /* This entry is already in the diagnostic. */
                    346:
                    347:        /*
1.618     rillig    348:         * For the IFiles with forLoop, lineno is the number of completely
                    349:         * parsed lines, which is right after the corresponding .endfor.  The
                    350:         * intuitive line number comes from first_lineno instead, which
                    351:         * points at the start of the .for loop.
1.532     rillig    352:         *
                    353:         * To make the stack trace intuitive, the entry below each chain of
                    354:         * .for loop entries must be ignored completely since neither its
                    355:         * lineno nor its first_lineno is useful.  Instead, the topmost of
                    356:         * each chain of .for loop entries needs to be printed twice, once
                    357:         * with its first_lineno and once with its lineno.
                    358:         */
                    359:
                    360:        for (i = n; i-- > 0;) {
                    361:                const IFile *entry = entries + i;
1.576     rillig    362:                const char *fname = entry->name.str;
1.532     rillig    363:                char dirbuf[MAXPATHLEN + 1];
                    364:
                    365:                if (fname[0] != '/' && strcmp(fname, "(stdin)") != 0)
                    366:                        fname = realpath(fname, dirbuf);
                    367:
1.617     rillig    368:                if (entries[i + 1 < n ? i + 1 : i].forLoop == NULL)
1.532     rillig    369:                        debug_printf("\tin .include from %s:%d\n",
                    370:                            fname, entry->lineno);
1.617     rillig    371:                if (entry->forLoop != NULL)
1.532     rillig    372:                        debug_printf("\tin .for loop from %s:%d\n",
1.618     rillig    373:                            fname, entry->forBodyLineno - 1 + 1);
1.532     rillig    374:        }
                    375: }
1.77      christos  376:
1.279     rillig    377: /* Check if the current character is escaped on the current line. */
1.553     rillig    378: static bool
1.602     rillig    379: IsEscaped(const char *line, const char *p)
1.77      christos  380: {
1.553     rillig    381:        bool active = false;
1.594     rillig    382:        while (p > line && *--p == '\\')
1.469     rillig    383:                active = !active;
1.594     rillig    384:        return active;
1.77      christos  385: }
                    386:
1.524     rillig    387: /*
                    388:  * Add the filename and lineno to the GNode so that we remember where it
                    389:  * was first defined.
                    390:  */
1.278     rillig    391: static void
1.562     rillig    392: RememberLocation(GNode *gn)
1.278     rillig    393: {
1.469     rillig    394:        IFile *curFile = CurFile();
1.576     rillig    395:        gn->fname = Str_Intern(curFile->name.str);
1.469     rillig    396:        gn->lineno = curFile->lineno;
1.278     rillig    397: }
                    398:
1.524     rillig    399: /*
                    400:  * Look in the table of keywords for one matching the given string.
                    401:  * Return the index of the keyword, or -1 if it isn't there.
                    402:  */
1.1       cgd       403: static int
1.602     rillig    404: FindKeyword(const char *str)
1.1       cgd       405: {
1.469     rillig    406:        int start = 0;
                    407:        int end = sizeof parseKeywords / sizeof parseKeywords[0] - 1;
1.1       cgd       408:
1.611     rillig    409:        while (start <= end) {
1.469     rillig    410:                int curr = start + (end - start) / 2;
                    411:                int diff = strcmp(str, parseKeywords[curr].name);
                    412:
                    413:                if (diff == 0)
                    414:                        return curr;
                    415:                if (diff < 0)
                    416:                        end = curr - 1;
                    417:                else
                    418:                        start = curr + 1;
1.611     rillig    419:        }
1.430     rillig    420:
1.469     rillig    421:        return -1;
1.1       cgd       422: }
                    423:
1.291     rillig    424: static void
1.441     rillig    425: PrintLocation(FILE *f, const char *fname, size_t lineno)
1.291     rillig    426: {
1.469     rillig    427:        char dirbuf[MAXPATHLEN + 1];
1.505     rillig    428:        FStr dir, base;
1.291     rillig    429:
1.622     rillig    430:        if (fname[0] == '/' || strcmp(fname, "(stdin)") == 0) {
1.481     rillig    431:                (void)fprintf(f, "\"%s\" line %u: ", fname, (unsigned)lineno);
1.299     rillig    432:                return;
                    433:        }
1.291     rillig    434:
1.548     rillig    435:        dir = Var_Value(SCOPE_GLOBAL, ".PARSEDIR");
1.505     rillig    436:        if (dir.str == NULL)
                    437:                dir.str = ".";
                    438:        if (dir.str[0] != '/')
                    439:                dir.str = realpath(dir.str, dirbuf);
                    440:
1.548     rillig    441:        base = Var_Value(SCOPE_GLOBAL, ".PARSEFILE");
1.505     rillig    442:        if (base.str == NULL)
                    443:                base.str = str_basename(fname);
                    444:
                    445:        (void)fprintf(f, "\"%s/%s\" line %u: ",
                    446:            dir.str, base.str, (unsigned)lineno);
                    447:
                    448:        FStr_Done(&base);
                    449:        FStr_Done(&dir);
1.291     rillig    450: }
                    451:
1.38      christos  452: static void
1.441     rillig    453: ParseVErrorInternal(FILE *f, const char *fname, size_t lineno,
1.398     rillig    454:                    ParseErrorLevel type, const char *fmt, va_list ap)
1.38      christos  455: {
1.553     rillig    456:        static bool fatal_warning_error_printed = false;
1.56      christos  457:
1.148     sjg       458:        (void)fprintf(f, "%s: ", progname);
1.63      christos  459:
1.441     rillig    460:        if (fname != NULL)
                    461:                PrintLocation(f, fname, lineno);
1.38      christos  462:        if (type == PARSE_WARNING)
1.127     dsl       463:                (void)fprintf(f, "warning: ");
                    464:        (void)vfprintf(f, fmt, ap);
                    465:        (void)fprintf(f, "\n");
                    466:        (void)fflush(f);
1.300     rillig    467:
1.621     rillig    468:        if (type == PARSE_FATAL)
                    469:                parseErrors++;
                    470:        if (type == PARSE_WARNING && opts.parseWarnFatal) {
                    471:                if (!fatal_warning_error_printed) {
                    472:                        Error("parsing warnings being treated as errors");
                    473:                        fatal_warning_error_printed = true;
                    474:                }
                    475:                parseErrors++;
1.56      christos  476:        }
1.532     rillig    477:
                    478:        PrintStackTrace();
1.38      christos  479: }
                    480:
1.203     joerg     481: static void
1.441     rillig    482: ParseErrorInternal(const char *fname, size_t lineno,
                    483:                   ParseErrorLevel type, const char *fmt, ...)
1.203     joerg     484: {
                    485:        va_list ap;
                    486:
1.441     rillig    487:        (void)fflush(stdout);
1.203     joerg     488:        va_start(ap, fmt);
1.441     rillig    489:        ParseVErrorInternal(stderr, fname, lineno, type, fmt, ap);
1.203     joerg     490:        va_end(ap);
                    491:
1.622     rillig    492:        if (opts.debug_file != stdout && opts.debug_file != stderr) {
1.203     joerg     493:                va_start(ap, fmt);
1.441     rillig    494:                ParseVErrorInternal(opts.debug_file, fname, lineno, type,
1.469     rillig    495:                    fmt, ap);
1.203     joerg     496:                va_end(ap);
                    497:        }
                    498: }
                    499:
1.524     rillig    500: /*
                    501:  * Print a parse error message, including location information.
1.441     rillig    502:  *
                    503:  * If the level is PARSE_FATAL, continue parsing until the end of the
                    504:  * current top-level makefile, then exit (see Parse_File).
1.38      christos  505:  *
1.524     rillig    506:  * Fmt is given without a trailing newline.
                    507:  */
1.1       cgd       508: void
1.398     rillig    509: Parse_Error(ParseErrorLevel type, const char *fmt, ...)
1.1       cgd       510: {
                    511:        va_list ap;
1.156     dsl       512:        const char *fname;
                    513:        size_t lineno;
1.84      wiz       514:
1.408     rillig    515:        if (includes.len == 0) {
1.156     dsl       516:                fname = NULL;
                    517:                lineno = 0;
                    518:        } else {
1.408     rillig    519:                IFile *curFile = CurFile();
1.576     rillig    520:                fname = curFile->name.str;
1.369     rillig    521:                lineno = (size_t)curFile->lineno;
1.148     sjg       522:        }
1.156     dsl       523:
                    524:        va_start(ap, fmt);
1.163     sjg       525:        (void)fflush(stdout);
1.156     dsl       526:        ParseVErrorInternal(stderr, fname, lineno, type, fmt, ap);
1.1       cgd       527:        va_end(ap);
1.127     dsl       528:
1.622     rillig    529:        if (opts.debug_file != stdout && opts.debug_file != stderr) {
1.127     dsl       530:                va_start(ap, fmt);
1.401     rillig    531:                ParseVErrorInternal(opts.debug_file, fname, lineno, type,
1.469     rillig    532:                    fmt, ap);
1.127     dsl       533:                va_end(ap);
                    534:        }
1.1       cgd       535: }
                    536:
1.161     sjg       537:
1.524     rillig    538: /*
1.602     rillig    539:  * Handle an .info, .warning or .error directive.  For an .error directive,
                    540:  * exit immediately.
1.524     rillig    541:  */
1.503     rillig    542: static void
1.602     rillig    543: HandleMessage(ParseErrorLevel level, const char *levelName, const char *umsg)
1.161     sjg       544: {
1.475     rillig    545:        char *xmsg;
1.469     rillig    546:
1.503     rillig    547:        if (umsg[0] == '\0') {
                    548:                Parse_Error(PARSE_FATAL, "Missing argument for \".%s\"",
                    549:                    levelName);
                    550:                return;
                    551:        }
1.469     rillig    552:
1.545     rillig    553:        (void)Var_Subst(umsg, SCOPE_CMDLINE, VARE_WANTRES, &xmsg);
1.469     rillig    554:        /* TODO: handle errors */
                    555:
1.475     rillig    556:        Parse_Error(level, "%s", xmsg);
                    557:        free(xmsg);
1.469     rillig    558:
1.475     rillig    559:        if (level == PARSE_FATAL) {
1.469     rillig    560:                PrintOnError(NULL, NULL);
                    561:                exit(1);
                    562:        }
1.161     sjg       563: }
                    564:
1.524     rillig    565: /*
                    566:  * Add the child to the parent's children.
1.1       cgd       567:  *
1.382     rillig    568:  * Additionally, add the parent to the child's parents, but only if the
                    569:  * target is not special.  An example for such a special target is .END,
1.524     rillig    570:  * which does not need to be informed once the child target has been made.
                    571:  */
1.382     rillig    572: static void
1.553     rillig    573: LinkSource(GNode *pgn, GNode *cgn, bool isSpecial)
1.382     rillig    574: {
1.469     rillig    575:        if ((pgn->type & OP_DOUBLEDEP) && !Lst_IsEmpty(&pgn->cohorts))
                    576:                pgn = pgn->cohorts.last->datum;
1.316     rillig    577:
1.469     rillig    578:        Lst_Append(&pgn->children, cgn);
                    579:        pgn->unmade++;
1.316     rillig    580:
1.469     rillig    581:        /* Special targets like .END don't need any children. */
                    582:        if (!isSpecial)
                    583:                Lst_Append(&cgn->parents, pgn);
                    584:
                    585:        if (DEBUG(PARSE)) {
1.586     rillig    586:                debug_printf("# LinkSource: added child %s - %s\n",
                    587:                    pgn->name, cgn->name);
1.469     rillig    588:                Targ_PrintNode(pgn, 0);
                    589:                Targ_PrintNode(cgn, 0);
                    590:        }
1.1       cgd       591: }
                    592:
1.382     rillig    593: /* Add the node to each target from the current dependency group. */
                    594: static void
1.553     rillig    595: LinkToTargets(GNode *gn, bool isSpecial)
1.382     rillig    596: {
1.469     rillig    597:        GNodeListNode *ln;
                    598:
                    599:        for (ln = targets->first; ln != NULL; ln = ln->next)
                    600:                LinkSource(ln->datum, gn, isSpecial);
1.382     rillig    601: }
                    602:
1.553     rillig    603: static bool
1.337     rillig    604: TryApplyDependencyOperator(GNode *gn, GNodeType op)
1.1       cgd       605: {
                    606:        /*
1.469     rillig    607:         * If the node occurred on the left-hand side of a dependency and the
                    608:         * operator also defines a dependency, they must match.
1.1       cgd       609:         */
1.469     rillig    610:        if ((op & OP_OPMASK) && (gn->type & OP_OPMASK) &&
                    611:            ((op & OP_OPMASK) != (gn->type & OP_OPMASK))) {
                    612:                Parse_Error(PARSE_FATAL, "Inconsistent operator for %s",
                    613:                    gn->name);
1.553     rillig    614:                return false;
1.469     rillig    615:        }
                    616:
                    617:        if (op == OP_DOUBLEDEP && (gn->type & OP_OPMASK) == OP_DOUBLEDEP) {
                    618:                /*
                    619:                 * If the node was of the left-hand side of a '::' operator,
                    620:                 * we need to create a new instance of it for the children
                    621:                 * and commands on this dependency line since each of these
                    622:                 * dependency groups has its own attributes and commands,
                    623:                 * separate from the others.
                    624:                 *
                    625:                 * The new instance is placed on the 'cohorts' list of the
                    626:                 * initial one (note the initial one is not on its own
                    627:                 * cohorts list) and the new instance is linked to all
                    628:                 * parents of the initial instance.
                    629:                 */
                    630:                GNode *cohort;
1.27      christos  631:
1.469     rillig    632:                /*
                    633:                 * Propagate copied bits to the initial node.  They'll be
                    634:                 * propagated back to the rest of the cohorts later.
                    635:                 */
                    636:                gn->type |= op & ~OP_OPMASK;
1.33      mycroft   637:
1.469     rillig    638:                cohort = Targ_NewInternalNode(gn->name);
                    639:                if (doing_depend)
1.562     rillig    640:                        RememberLocation(cohort);
1.469     rillig    641:                /*
                    642:                 * Make the cohort invisible as well to avoid duplicating it
                    643:                 * into other variables. True, parents of this target won't
                    644:                 * tend to do anything with their local variables, but better
                    645:                 * safe than sorry.
                    646:                 *
                    647:                 * (I think this is pointless now, since the relevant list
                    648:                 * traversals will no longer see this node anyway. -mycroft)
                    649:                 */
                    650:                cohort->type = op | OP_INVISIBLE;
                    651:                Lst_Append(&gn->cohorts, cohort);
                    652:                cohort->centurion = gn;
                    653:                gn->unmade_cohorts++;
                    654:                snprintf(cohort->cohort_num, sizeof cohort->cohort_num, "#%d",
                    655:                    (unsigned int)gn->unmade_cohorts % 1000000);
                    656:        } else {
                    657:                /*
                    658:                 * We don't want to nuke any previous flags (whatever they
                    659:                 * were) so we just OR the new operator into the old.
                    660:                 */
                    661:                gn->type |= op;
                    662:        }
1.33      mycroft   663:
1.553     rillig    664:        return true;
1.337     rillig    665: }
                    666:
                    667: static void
                    668: ApplyDependencyOperator(GNodeType op)
                    669: {
1.469     rillig    670:        GNodeListNode *ln;
                    671:
                    672:        for (ln = targets->first; ln != NULL; ln = ln->next)
                    673:                if (!TryApplyDependencyOperator(ln->datum, op))
                    674:                        break;
1.1       cgd       675: }
                    676:
1.467     rillig    677: /*
                    678:  * We add a .WAIT node in the dependency list. After any dynamic dependencies
                    679:  * (and filename globbing) have happened, it is given a dependency on each
                    680:  * previous child, back until the previous .WAIT node. The next child won't
                    681:  * be scheduled until the .WAIT node is built.
                    682:  *
                    683:  * We give each .WAIT node a unique name (mainly for diagnostics).
                    684:  */
                    685: static void
1.593     rillig    686: ApplyDependencySourceWait(bool isSpecial)
1.467     rillig    687: {
                    688:        static int wait_number = 0;
                    689:        char wait_src[16];
                    690:        GNode *gn;
                    691:
                    692:        snprintf(wait_src, sizeof wait_src, ".WAIT_%u", ++wait_number);
                    693:        gn = Targ_NewInternalNode(wait_src);
                    694:        if (doing_depend)
1.562     rillig    695:                RememberLocation(gn);
1.467     rillig    696:        gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN;
                    697:        LinkToTargets(gn, isSpecial);
                    698:
                    699: }
                    700:
1.553     rillig    701: static bool
1.593     rillig    702: ApplyDependencySourceKeyword(const char *src, ParseSpecial special)
1.1       cgd       703: {
1.468     rillig    704:        int keywd;
1.590     rillig    705:        GNodeType targetAttr;
1.1       cgd       706:
1.468     rillig    707:        if (*src != '.' || !ch_isupper(src[1]))
1.553     rillig    708:                return false;
1.468     rillig    709:
1.602     rillig    710:        keywd = FindKeyword(src);
1.468     rillig    711:        if (keywd == -1)
1.553     rillig    712:                return false;
1.468     rillig    713:
1.590     rillig    714:        targetAttr = parseKeywords[keywd].targetAttr;
                    715:        if (targetAttr != OP_NONE) {
                    716:                ApplyDependencyOperator(targetAttr);
1.553     rillig    717:                return true;
1.468     rillig    718:        }
1.590     rillig    719:        if (parseKeywords[keywd].special == SP_WAIT) {
1.593     rillig    720:                ApplyDependencySourceWait(special != SP_NOT);
1.553     rillig    721:                return true;
1.1       cgd       722:        }
1.553     rillig    723:        return false;
1.368     rillig    724: }
1.18      christos  725:
1.368     rillig    726: static void
1.593     rillig    727: ApplyDependencySourceMain(const char *src)
1.368     rillig    728: {
1.469     rillig    729:        /*
1.549     rillig    730:         * In a line like ".MAIN: source1 source2", add all sources to the
                    731:         * list of things to create, but only if the user didn't specify a
                    732:         * target on the command line and .MAIN occurs for the first time.
1.469     rillig    733:         *
1.602     rillig    734:         * See HandleDependencyTargetSpecial, branch SP_MAIN.
1.469     rillig    735:         * See unit-tests/cond-func-make-main.mk.
                    736:         */
                    737:        Lst_Append(&opts.create, bmake_strdup(src));
                    738:        /*
                    739:         * Add the name to the .TARGETS variable as well, so the user can
                    740:         * employ that, if desired.
                    741:         */
1.542     rillig    742:        Global_Append(".TARGETS", src);
1.368     rillig    743: }
1.18      christos  744:
1.368     rillig    745: static void
1.593     rillig    746: ApplyDependencySourceOrder(const char *src)
1.368     rillig    747: {
1.469     rillig    748:        GNode *gn;
                    749:        /*
                    750:         * Create proper predecessor/successor links between the previous
                    751:         * source and the current one.
                    752:         */
                    753:        gn = Targ_GetNode(src);
                    754:        if (doing_depend)
1.562     rillig    755:                RememberLocation(gn);
1.469     rillig    756:        if (order_pred != NULL) {
                    757:                Lst_Append(&order_pred->order_succ, gn);
                    758:                Lst_Append(&gn->order_pred, order_pred);
                    759:                if (DEBUG(PARSE)) {
1.586     rillig    760:                        debug_printf(
1.592     rillig    761:                            "# .ORDER forces '%s' to be made before '%s'\n",
1.586     rillig    762:                            order_pred->name, gn->name);
1.469     rillig    763:                        Targ_PrintNode(order_pred, 0);
                    764:                        Targ_PrintNode(gn, 0);
                    765:                }
                    766:        }
                    767:        /*
                    768:         * The current source now becomes the predecessor for the next one.
                    769:         */
                    770:        order_pred = gn;
1.368     rillig    771: }
                    772:
                    773: static void
1.593     rillig    774: ApplyDependencySourceOther(const char *src, GNodeType targetAttr,
1.587     rillig    775:                           ParseSpecial special)
1.368     rillig    776: {
1.469     rillig    777:        GNode *gn;
                    778:
                    779:        /*
1.549     rillig    780:         * The source is not an attribute, so find/create a node for it.
                    781:         * After that, apply any operator to it from a special target or
                    782:         * link it to its parents, as appropriate.
1.469     rillig    783:         *
1.549     rillig    784:         * In the case of a source that was the object of a '::' operator,
1.469     rillig    785:         * the attribute is applied to all of its instances (as kept in
                    786:         * the 'cohorts' list of the node) or all the cohorts are linked
                    787:         * to all the targets.
                    788:         */
1.363     rillig    789:
1.469     rillig    790:        /* Find/create the 'src' node and attach to all targets */
                    791:        gn = Targ_GetNode(src);
                    792:        if (doing_depend)
1.562     rillig    793:                RememberLocation(gn);
1.590     rillig    794:        if (targetAttr != OP_NONE)
                    795:                gn->type |= targetAttr;
1.469     rillig    796:        else
1.587     rillig    797:                LinkToTargets(gn, special != SP_NOT);
1.1       cgd       798: }
                    799:
1.469     rillig    800: /*
                    801:  * Given the name of a source in a dependency line, figure out if it is an
1.590     rillig    802:  * attribute (such as .SILENT) and if so, apply it to all targets. Otherwise
1.368     rillig    803:  * decide if there is some attribute which should be applied *to* the source
                    804:  * because of some special target (such as .PHONY) and apply it if so.
1.590     rillig    805:  * Otherwise, make the source a child of the targets.
1.368     rillig    806:  */
                    807: static void
1.593     rillig    808: ApplyDependencySource(GNodeType targetAttr, const char *src,
1.590     rillig    809:                      ParseSpecial special)
1.368     rillig    810: {
1.593     rillig    811:        if (ApplyDependencySourceKeyword(src, special))
1.469     rillig    812:                return;
1.368     rillig    813:
1.587     rillig    814:        if (special == SP_MAIN)
1.593     rillig    815:                ApplyDependencySourceMain(src);
1.587     rillig    816:        else if (special == SP_ORDER)
1.593     rillig    817:                ApplyDependencySourceOrder(src);
1.469     rillig    818:        else
1.593     rillig    819:                ApplyDependencySourceOther(src, targetAttr, special);
1.368     rillig    820: }
                    821:
1.469     rillig    822: /*
                    823:  * If we have yet to decide on a main target to make, in the absence of any
1.335     rillig    824:  * user input, we want the first target on the first dependency line that is
1.469     rillig    825:  * actually a real target (i.e. isn't a .USE or .EXEC rule) to be made.
                    826:  */
1.335     rillig    827: static void
                    828: FindMainTarget(void)
1.1       cgd       829: {
1.469     rillig    830:        GNodeListNode *ln;
1.335     rillig    831:
1.469     rillig    832:        if (mainNode != NULL)
                    833:                return;
1.335     rillig    834:
1.469     rillig    835:        for (ln = targets->first; ln != NULL; ln = ln->next) {
                    836:                GNode *gn = ln->datum;
1.589     rillig    837:                if (GNode_IsMainCandidate(gn)) {
1.469     rillig    838:                        DEBUG1(MAKE, "Setting main node to \"%s\"\n", gn->name);
                    839:                        mainNode = gn;
                    840:                        Targ_SetMain(gn);
                    841:                        return;
                    842:                }
1.335     rillig    843:        }
1.1       cgd       844: }
                    845:
1.311     rillig    846: static void
1.602     rillig    847: InvalidLineType(const char *lstart)
1.311     rillig    848: {
1.469     rillig    849:        if ((strncmp(lstart, "<<<<<<", 6) == 0) ||
                    850:            (strncmp(lstart, "======", 6) == 0) ||
                    851:            (strncmp(lstart, ">>>>>>", 6) == 0))
                    852:                Parse_Error(PARSE_FATAL,
1.563     rillig    853:                    "Makefile appears to contain unresolved CVS/RCS/??? merge conflicts");
1.469     rillig    854:        else if (lstart[0] == '.') {
                    855:                const char *dirstart = lstart + 1;
                    856:                const char *dirend;
                    857:                cpp_skip_whitespace(&dirstart);
                    858:                dirend = dirstart;
                    859:                while (ch_isalnum(*dirend) || *dirend == '-')
                    860:                        dirend++;
                    861:                Parse_Error(PARSE_FATAL, "Unknown directive \"%.*s\"",
1.311     rillig    862:                    (int)(dirend - dirstart), dirstart);
1.469     rillig    863:        } else
1.535     rillig    864:                Parse_Error(PARSE_FATAL, "Invalid line type");
1.311     rillig    865: }
                    866:
1.314     rillig    867: static void
1.599     rillig    868: ParseDependencyTargetWord(char **pp, const char *lstart)
1.314     rillig    869: {
1.469     rillig    870:        const char *cp = *pp;
                    871:
                    872:        while (*cp != '\0') {
                    873:                if ((ch_isspace(*cp) || *cp == '!' || *cp == ':' ||
                    874:                     *cp == '(') &&
1.602     rillig    875:                    !IsEscaped(lstart, cp))
1.469     rillig    876:                        break;
1.314     rillig    877:
1.469     rillig    878:                if (*cp == '$') {
                    879:                        /*
                    880:                         * Must be a dynamic source (would have been expanded
1.619     rillig    881:                         * otherwise).
1.469     rillig    882:                         *
                    883:                         * There should be no errors in this, as they would
                    884:                         * have been discovered in the initial Var_Subst and
                    885:                         * we wouldn't be here.
                    886:                         */
1.624   ! rillig    887:                        FStr val;
1.314     rillig    888:
1.624   ! rillig    889:                        (void)Var_Parse(&cp, SCOPE_CMDLINE,
        !           890:                            VARE_PARSE_ONLY, &val);
        !           891:                        FStr_Done(&val);
1.469     rillig    892:                } else
                    893:                        cp++;
                    894:        }
1.314     rillig    895:
1.599     rillig    896:        *pp += cp - *pp;
1.314     rillig    897: }
                    898:
1.559     rillig    899: /*
                    900:  * Handle special targets like .PATH, .DEFAULT, .BEGIN, .ORDER.
                    901:  *
                    902:  * See the tests deptgt-*.mk.
                    903:  */
1.368     rillig    904: static void
1.602     rillig    905: HandleDependencyTargetSpecial(const char *targetName,
                    906:                              ParseSpecial *inout_special,
                    907:                              SearchPathList **inout_paths)
1.368     rillig    908: {
1.587     rillig    909:        switch (*inout_special) {
1.469     rillig    910:        case SP_PATH:
                    911:                if (*inout_paths == NULL)
                    912:                        *inout_paths = Lst_New();
                    913:                Lst_Append(*inout_paths, &dirSearchPath);
                    914:                break;
                    915:        case SP_MAIN:
                    916:                /*
                    917:                 * Allow targets from the command line to override the
                    918:                 * .MAIN node.
                    919:                 */
                    920:                if (!Lst_IsEmpty(&opts.create))
1.587     rillig    921:                        *inout_special = SP_NOT;
1.469     rillig    922:                break;
                    923:        case SP_BEGIN:
                    924:        case SP_END:
                    925:        case SP_STALE:
                    926:        case SP_ERROR:
                    927:        case SP_INTERRUPT: {
1.530     rillig    928:                GNode *gn = Targ_GetNode(targetName);
1.469     rillig    929:                if (doing_depend)
1.562     rillig    930:                        RememberLocation(gn);
1.469     rillig    931:                gn->type |= OP_NOTMAIN | OP_SPECIAL;
                    932:                Lst_Append(targets, gn);
                    933:                break;
                    934:        }
                    935:        case SP_DEFAULT: {
                    936:                /*
                    937:                 * Need to create a node to hang commands on, but we don't
                    938:                 * want it in the graph, nor do we want it to be the Main
                    939:                 * Target. We claim the node is a transformation rule to make
                    940:                 * life easier later, when we'll use Make_HandleUse to
                    941:                 * actually apply the .DEFAULT commands.
                    942:                 */
                    943:                GNode *gn = GNode_New(".DEFAULT");
                    944:                gn->type |= OP_NOTMAIN | OP_TRANSFORM;
                    945:                Lst_Append(targets, gn);
                    946:                defaultNode = gn;
                    947:                break;
                    948:        }
                    949:        case SP_DELETE_ON_ERROR:
1.553     rillig    950:                deleteOnError = true;
1.469     rillig    951:                break;
                    952:        case SP_NOTPARALLEL:
                    953:                opts.maxJobs = 1;
                    954:                break;
                    955:        case SP_SINGLESHELL:
1.553     rillig    956:                opts.compatMake = true;
1.469     rillig    957:                break;
                    958:        case SP_ORDER:
                    959:                order_pred = NULL;
                    960:                break;
                    961:        default:
                    962:                break;
                    963:        }
1.368     rillig    964: }
                    965:
1.553     rillig    966: static bool
1.602     rillig    967: HandleDependencyTargetPath(const char *suffixName,
                    968:                           SearchPathList **inout_paths)
1.368     rillig    969: {
1.469     rillig    970:        SearchPath *path;
1.368     rillig    971:
1.530     rillig    972:        path = Suff_GetPath(suffixName);
1.469     rillig    973:        if (path == NULL) {
                    974:                Parse_Error(PARSE_FATAL,
1.530     rillig    975:                    "Suffix '%s' not defined (yet)", suffixName);
1.553     rillig    976:                return false;
1.469     rillig    977:        }
1.430     rillig    978:
1.469     rillig    979:        if (*inout_paths == NULL)
                    980:                *inout_paths = Lst_New();
                    981:        Lst_Append(*inout_paths, path);
1.430     rillig    982:
1.553     rillig    983:        return true;
1.368     rillig    984: }
                    985:
                    986: /*
1.587     rillig    987:  * See if it's a special target and if so set inout_special to match it.
1.364     rillig    988:  */
1.553     rillig    989: static bool
1.602     rillig    990: HandleDependencyTarget(const char *targetName,
                    991:                       ParseSpecial *inout_special,
                    992:                       GNodeType *inout_targetAttr,
                    993:                       SearchPathList **inout_paths)
1.364     rillig    994: {
1.469     rillig    995:        int keywd;
                    996:
1.530     rillig    997:        if (!(targetName[0] == '.' && ch_isupper(targetName[1])))
1.553     rillig    998:                return true;
1.469     rillig    999:
                   1000:        /*
                   1001:         * See if the target is a special target that must have it
                   1002:         * or its sources handled specially.
                   1003:         */
1.602     rillig   1004:        keywd = FindKeyword(targetName);
1.469     rillig   1005:        if (keywd != -1) {
1.587     rillig   1006:                if (*inout_special == SP_PATH &&
1.590     rillig   1007:                    parseKeywords[keywd].special != SP_PATH) {
1.469     rillig   1008:                        Parse_Error(PARSE_FATAL, "Mismatched special targets");
1.553     rillig   1009:                        return false;
1.469     rillig   1010:                }
                   1011:
1.590     rillig   1012:                *inout_special = parseKeywords[keywd].special;
                   1013:                *inout_targetAttr = parseKeywords[keywd].targetAttr;
1.469     rillig   1014:
1.602     rillig   1015:                HandleDependencyTargetSpecial(targetName, inout_special,
1.469     rillig   1016:                    inout_paths);
1.364     rillig   1017:
1.530     rillig   1018:        } else if (strncmp(targetName, ".PATH", 5) == 0) {
1.587     rillig   1019:                *inout_special = SP_PATH;
1.602     rillig   1020:                if (!HandleDependencyTargetPath(targetName + 5, inout_paths))
1.553     rillig   1021:                        return false;
1.469     rillig   1022:        }
1.553     rillig   1023:        return true;
1.368     rillig   1024: }
                   1025:
                   1026: static void
1.602     rillig   1027: HandleDependencyTargetMundane(char *targetName)
1.368     rillig   1028: {
1.595     rillig   1029:        StringList targetNames = LST_INIT;
                   1030:
1.530     rillig   1031:        if (Dir_HasWildcards(targetName)) {
1.469     rillig   1032:                SearchPath *emptyPath = SearchPath_New();
1.595     rillig   1033:                SearchPath_Expand(emptyPath, targetName, &targetNames);
1.469     rillig   1034:                SearchPath_Free(emptyPath);
1.595     rillig   1035:        } else
                   1036:                Lst_Append(&targetNames, targetName);
1.368     rillig   1037:
1.595     rillig   1038:        while (!Lst_IsEmpty(&targetNames)) {
                   1039:                char *targName = Lst_Dequeue(&targetNames);
1.469     rillig   1040:                GNode *gn = Suff_IsTransform(targName)
1.368     rillig   1041:                    ? Suff_AddTransform(targName)
                   1042:                    : Targ_GetNode(targName);
1.469     rillig   1043:                if (doing_depend)
1.562     rillig   1044:                        RememberLocation(gn);
1.368     rillig   1045:
1.469     rillig   1046:                Lst_Append(targets, gn);
                   1047:        }
1.368     rillig   1048: }
                   1049:
                   1050: static void
1.603     rillig   1051: SkipExtraTargets(char **pp, const char *lstart)
1.368     rillig   1052: {
1.553     rillig   1053:        bool warning = false;
1.603     rillig   1054:        const char *cp = *pp;
1.368     rillig   1055:
1.469     rillig   1056:        while (*cp != '\0') {
1.602     rillig   1057:                if (!IsEscaped(lstart, cp) && (*cp == '!' || *cp == ':'))
1.469     rillig   1058:                        break;
1.602     rillig   1059:                if (IsEscaped(lstart, cp) || (*cp != ' ' && *cp != '\t'))
1.553     rillig   1060:                        warning = true;
1.469     rillig   1061:                cp++;
                   1062:        }
                   1063:        if (warning)
                   1064:                Parse_Error(PARSE_WARNING, "Extra target ignored");
1.430     rillig   1065:
1.603     rillig   1066:        *pp += cp - *pp;
1.368     rillig   1067: }
                   1068:
                   1069: static void
1.587     rillig   1070: ParseDependencyCheckSpecial(ParseSpecial special)
1.368     rillig   1071: {
1.587     rillig   1072:        switch (special) {
1.469     rillig   1073:        case SP_DEFAULT:
                   1074:        case SP_STALE:
                   1075:        case SP_BEGIN:
                   1076:        case SP_END:
                   1077:        case SP_ERROR:
                   1078:        case SP_INTERRUPT:
                   1079:                /*
                   1080:                 * These create nodes on which to hang commands, so targets
                   1081:                 * shouldn't be empty.
                   1082:                 */
                   1083:        case SP_NOT:
1.583     rillig   1084:                /*
                   1085:                 * Nothing special here -- targets can be empty if it wants.
                   1086:                 */
1.469     rillig   1087:                break;
1.582     rillig   1088:        default:
                   1089:                Parse_Error(PARSE_WARNING,
                   1090:                    "Special and mundane targets don't mix. "
                   1091:                    "Mundane ones ignored");
                   1092:                break;
1.469     rillig   1093:        }
1.368     rillig   1094: }
                   1095:
1.560     rillig   1096: /*
                   1097:  * In a dependency line like 'targets: sources' or 'targets! sources', parse
                   1098:  * the operator ':', '::' or '!' from between the targets and the sources.
                   1099:  */
1.578     rillig   1100: static GNodeType
                   1101: ParseDependencyOp(char **pp)
1.368     rillig   1102: {
1.578     rillig   1103:        if (**pp == '!')
                   1104:                return (*pp)++, OP_FORCE;
                   1105:        if ((*pp)[1] == ':')
                   1106:                return (*pp) += 2, OP_DOUBLEDEP;
                   1107:        else
                   1108:                return (*pp)++, OP_DEPENDS;
1.368     rillig   1109: }
1.364     rillig   1110:
1.368     rillig   1111: static void
1.392     rillig   1112: ClearPaths(SearchPathList *paths)
                   1113: {
1.469     rillig   1114:        if (paths != NULL) {
                   1115:                SearchPathListNode *ln;
                   1116:                for (ln = paths->first; ln != NULL; ln = ln->next)
                   1117:                        SearchPath_Clear(ln->datum);
                   1118:        }
1.392     rillig   1119:
1.469     rillig   1120:        Dir_SetPATH();
1.392     rillig   1121: }
                   1122:
1.558     rillig   1123: /*
                   1124:  * Several special targets take different actions if present with no
                   1125:  * sources:
                   1126:  *     a .SUFFIXES line with no sources clears out all old suffixes
                   1127:  *     a .PRECIOUS line makes all targets precious
                   1128:  *     a .IGNORE line ignores errors for all targets
                   1129:  *     a .SILENT line creates silence when making all targets
                   1130:  *     a .PATH removes all directories from the search path(s).
                   1131:  */
1.392     rillig   1132: static void
1.587     rillig   1133: ParseDependencySourcesEmpty(ParseSpecial special, SearchPathList *paths)
1.368     rillig   1134: {
1.587     rillig   1135:        switch (special) {
1.469     rillig   1136:        case SP_SUFFIXES:
                   1137:                Suff_ClearSuffixes();
                   1138:                break;
                   1139:        case SP_PRECIOUS:
1.553     rillig   1140:                allPrecious = true;
1.469     rillig   1141:                break;
                   1142:        case SP_IGNORE:
1.553     rillig   1143:                opts.ignoreErrors = true;
1.469     rillig   1144:                break;
                   1145:        case SP_SILENT:
1.584     rillig   1146:                opts.silent = true;
1.469     rillig   1147:                break;
                   1148:        case SP_PATH:
                   1149:                ClearPaths(paths);
                   1150:                break;
1.368     rillig   1151: #ifdef POSIX
1.469     rillig   1152:        case SP_POSIX:
1.540     rillig   1153:                Global_Set("%POSIX", "1003.2");
1.469     rillig   1154:                break;
1.368     rillig   1155: #endif
1.469     rillig   1156:        default:
                   1157:                break;
                   1158:        }
1.368     rillig   1159: }
1.364     rillig   1160:
1.393     rillig   1161: static void
                   1162: AddToPaths(const char *dir, SearchPathList *paths)
                   1163: {
1.469     rillig   1164:        if (paths != NULL) {
                   1165:                SearchPathListNode *ln;
                   1166:                for (ln = paths->first; ln != NULL; ln = ln->next)
1.529     rillig   1167:                        (void)SearchPath_Add(ln->datum, dir);
1.469     rillig   1168:        }
1.393     rillig   1169: }
                   1170:
1.368     rillig   1171: /*
1.610     rillig   1172:  * If the target was one that doesn't take files as its sources but takes
                   1173:  * something like suffixes, we take each space-separated word on the line as
                   1174:  * a something and deal with it accordingly.
1.368     rillig   1175:  */
                   1176: static void
1.622     rillig   1177: ParseDependencySourceSpecial(ParseSpecial special, const char *word,
1.556     rillig   1178:                             SearchPathList *paths)
1.368     rillig   1179: {
1.587     rillig   1180:        switch (special) {
1.469     rillig   1181:        case SP_SUFFIXES:
                   1182:                Suff_AddSuffix(word, &mainNode);
                   1183:                break;
                   1184:        case SP_PATH:
                   1185:                AddToPaths(word, paths);
                   1186:                break;
                   1187:        case SP_INCLUDES:
                   1188:                Suff_AddInclude(word);
                   1189:                break;
                   1190:        case SP_LIBS:
                   1191:                Suff_AddLib(word);
                   1192:                break;
                   1193:        case SP_NULL:
                   1194:                Suff_SetNull(word);
                   1195:                break;
                   1196:        case SP_OBJDIR:
1.553     rillig   1197:                Main_SetObjdir(false, "%s", word);
1.469     rillig   1198:                break;
                   1199:        default:
                   1200:                break;
                   1201:        }
1.368     rillig   1202: }
1.364     rillig   1203:
1.553     rillig   1204: static bool
1.601     rillig   1205: ApplyDependencyTarget(char *name, char *nameEnd, ParseSpecial *inout_special,
                   1206:                      GNodeType *inout_targetAttr,
                   1207:                      SearchPathList **inout_paths)
                   1208: {
                   1209:        char savec = *nameEnd;
                   1210:        *nameEnd = '\0';
                   1211:
1.602     rillig   1212:        if (!HandleDependencyTarget(name, inout_special,
1.601     rillig   1213:            inout_targetAttr, inout_paths))
                   1214:                return false;
                   1215:
                   1216:        if (*inout_special == SP_NOT && *name != '\0')
1.602     rillig   1217:                HandleDependencyTargetMundane(name);
1.601     rillig   1218:        else if (*inout_special == SP_PATH && *name != '.' && *name != '\0')
                   1219:                Parse_Error(PARSE_WARNING, "Extra target (%s) ignored", name);
                   1220:
                   1221:        *nameEnd = savec;
                   1222:        return true;
                   1223: }
                   1224:
                   1225: static bool
1.556     rillig   1226: ParseDependencyTargets(char **inout_cp,
                   1227:                       const char *lstart,
1.587     rillig   1228:                       ParseSpecial *inout_special,
1.590     rillig   1229:                       GNodeType *inout_targetAttr,
1.595     rillig   1230:                       SearchPathList **inout_paths)
1.368     rillig   1231: {
1.469     rillig   1232:        char *cp;
1.598     rillig   1233:        char *tgt = *inout_cp;
1.469     rillig   1234:
                   1235:        for (;;) {
                   1236:                /* Find the end of the next word. */
                   1237:                cp = tgt;
1.599     rillig   1238:                ParseDependencyTargetWord(&cp, lstart);
1.469     rillig   1239:
                   1240:                /*
                   1241:                 * If the word is followed by a left parenthesis, it's the
1.596     rillig   1242:                 * name of one or more files inside an archive.
1.469     rillig   1243:                 */
1.602     rillig   1244:                if (!IsEscaped(lstart, cp) && *cp == '(') {
1.545     rillig   1245:                        if (!Arch_ParseArchive(&tgt, targets, SCOPE_CMDLINE)) {
1.469     rillig   1246:                                Parse_Error(PARSE_FATAL,
                   1247:                                    "Error in archive specification: \"%s\"",
                   1248:                                    tgt);
1.553     rillig   1249:                                return false;
1.469     rillig   1250:                        }
                   1251:
                   1252:                        cp = tgt;
                   1253:                        continue;
                   1254:                }
1.444     rillig   1255:
1.469     rillig   1256:                if (*cp == '\0') {
1.602     rillig   1257:                        InvalidLineType(lstart);
1.553     rillig   1258:                        return false;
1.469     rillig   1259:                }
1.27      christos 1260:
1.601     rillig   1261:                if (!ApplyDependencyTarget(tgt, cp, inout_special,
1.590     rillig   1262:                    inout_targetAttr, inout_paths))
1.553     rillig   1263:                        return false;
1.118     dsl      1264:
1.587     rillig   1265:                if (*inout_special != SP_NOT && *inout_special != SP_PATH)
1.603     rillig   1266:                        SkipExtraTargets(&cp, lstart);
1.469     rillig   1267:                else
                   1268:                        pp_skip_whitespace(&cp);
1.368     rillig   1269:
1.469     rillig   1270:                tgt = cp;
                   1271:                if (*tgt == '\0')
                   1272:                        break;
1.602     rillig   1273:                if ((*tgt == '!' || *tgt == ':') && !IsEscaped(lstart, tgt))
1.469     rillig   1274:                        break;
                   1275:        }
1.430     rillig   1276:
1.469     rillig   1277:        *inout_cp = cp;
1.553     rillig   1278:        return true;
1.368     rillig   1279: }
1.27      christos 1280:
1.368     rillig   1281: static void
1.597     rillig   1282: ParseDependencySourcesSpecial(char *start,
1.587     rillig   1283:                              ParseSpecial special, SearchPathList *paths)
1.368     rillig   1284: {
1.469     rillig   1285:        char savec;
1.204     dholland 1286:
1.469     rillig   1287:        while (*start != '\0') {
1.597     rillig   1288:                char *end = start;
1.469     rillig   1289:                while (*end != '\0' && !ch_isspace(*end))
                   1290:                        end++;
                   1291:                savec = *end;
                   1292:                *end = '\0';
1.587     rillig   1293:                ParseDependencySourceSpecial(special, start, paths);
1.469     rillig   1294:                *end = savec;
                   1295:                if (savec != '\0')
                   1296:                        end++;
                   1297:                pp_skip_whitespace(&end);
                   1298:                start = end;
                   1299:        }
1.368     rillig   1300: }
                   1301:
1.553     rillig   1302: static bool
1.597     rillig   1303: ParseDependencySourcesMundane(char *start,
1.590     rillig   1304:                              ParseSpecial special, GNodeType targetAttr)
1.368     rillig   1305: {
1.469     rillig   1306:        while (*start != '\0') {
1.597     rillig   1307:                char *end = start;
1.367     rillig   1308:                /*
1.469     rillig   1309:                 * The targets take real sources, so we must beware of archive
                   1310:                 * specifications (i.e. things with left parentheses in them)
                   1311:                 * and handle them accordingly.
1.367     rillig   1312:                 */
1.469     rillig   1313:                for (; *end != '\0' && !ch_isspace(*end); end++) {
                   1314:                        if (*end == '(' && end > start && end[-1] != '$') {
                   1315:                                /*
                   1316:                                 * Only stop for a left parenthesis if it
                   1317:                                 * isn't at the start of a word (that'll be
                   1318:                                 * for variable changes later) and isn't
                   1319:                                 * preceded by a dollar sign (a dynamic
                   1320:                                 * source).
                   1321:                                 */
                   1322:                                break;
                   1323:                        }
                   1324:                }
1.368     rillig   1325:
1.469     rillig   1326:                if (*end == '(') {
                   1327:                        GNodeList sources = LST_INIT;
1.545     rillig   1328:                        if (!Arch_ParseArchive(&start, &sources,
                   1329:                            SCOPE_CMDLINE)) {
1.469     rillig   1330:                                Parse_Error(PARSE_FATAL,
                   1331:                                    "Error in source archive spec \"%s\"",
                   1332:                                    start);
1.553     rillig   1333:                                return false;
1.469     rillig   1334:                        }
1.368     rillig   1335:
1.469     rillig   1336:                        while (!Lst_IsEmpty(&sources)) {
                   1337:                                GNode *gn = Lst_Dequeue(&sources);
1.593     rillig   1338:                                ApplyDependencySource(targetAttr, gn->name,
1.590     rillig   1339:                                    special);
1.469     rillig   1340:                        }
                   1341:                        Lst_Done(&sources);
                   1342:                        end = start;
                   1343:                } else {
                   1344:                        if (*end != '\0') {
                   1345:                                *end = '\0';
                   1346:                                end++;
                   1347:                        }
1.368     rillig   1348:
1.593     rillig   1349:                        ApplyDependencySource(targetAttr, start, special);
1.469     rillig   1350:                }
                   1351:                pp_skip_whitespace(&end);
                   1352:                start = end;
1.368     rillig   1353:        }
1.553     rillig   1354:        return true;
1.368     rillig   1355: }
1.1       cgd      1356:
1.559     rillig   1357: /*
                   1358:  * In a dependency line like 'targets: sources', parse the sources.
                   1359:  *
                   1360:  * See the tests depsrc-*.mk.
                   1361:  */
1.558     rillig   1362: static void
1.597     rillig   1363: ParseDependencySources(char *p, GNodeType targetAttr,
1.587     rillig   1364:                       ParseSpecial special, SearchPathList **inout_paths)
1.558     rillig   1365: {
1.597     rillig   1366:        if (*p == '\0') {
1.587     rillig   1367:                ParseDependencySourcesEmpty(special, *inout_paths);
                   1368:        } else if (special == SP_MFLAGS) {
1.597     rillig   1369:                Main_ParseArgLine(p);
1.558     rillig   1370:                /*
                   1371:                 * Set the initial character to a null-character so the loop
                   1372:                 * to get sources won't get anything.
                   1373:                 */
1.597     rillig   1374:                *p = '\0';
1.587     rillig   1375:        } else if (special == SP_SHELL) {
1.597     rillig   1376:                if (!Job_ParseShell(p)) {
1.558     rillig   1377:                        Parse_Error(PARSE_FATAL,
                   1378:                            "improper shell specification");
                   1379:                        return;
                   1380:                }
1.597     rillig   1381:                *p = '\0';
1.587     rillig   1382:        } else if (special == SP_NOTPARALLEL || special == SP_SINGLESHELL ||
                   1383:                   special == SP_DELETE_ON_ERROR) {
1.597     rillig   1384:                *p = '\0';
1.558     rillig   1385:        }
                   1386:
                   1387:        /* Now go for the sources. */
1.587     rillig   1388:        if (special == SP_SUFFIXES || special == SP_PATH ||
                   1389:            special == SP_INCLUDES || special == SP_LIBS ||
                   1390:            special == SP_NULL || special == SP_OBJDIR) {
1.597     rillig   1391:                ParseDependencySourcesSpecial(p, special, *inout_paths);
1.558     rillig   1392:                if (*inout_paths != NULL) {
                   1393:                        Lst_Free(*inout_paths);
                   1394:                        *inout_paths = NULL;
                   1395:                }
1.587     rillig   1396:                if (special == SP_PATH)
1.558     rillig   1397:                        Dir_SetPATH();
                   1398:        } else {
                   1399:                assert(*inout_paths == NULL);
1.597     rillig   1400:                if (!ParseDependencySourcesMundane(p, special, targetAttr))
1.558     rillig   1401:                        return;
                   1402:        }
                   1403:
                   1404:        FindMainTarget();
                   1405: }
                   1406:
1.524     rillig   1407: /*
                   1408:  * Parse a dependency line consisting of targets, followed by a dependency
1.368     rillig   1409:  * operator, optionally followed by sources.
                   1410:  *
                   1411:  * The nodes of the sources are linked as children to the nodes of the
                   1412:  * targets. Nodes are created as necessary.
                   1413:  *
                   1414:  * The operator is applied to each node in the global 'targets' list,
1.585     rillig   1415:  * which is where the nodes found for the targets are kept.
1.368     rillig   1416:  *
                   1417:  * The sources are parsed in much the same way as the targets, except
                   1418:  * that they are expanded using the wildcarding scheme of the C-Shell,
1.441     rillig   1419:  * and a target is created for each expanded word. Each of the resulting
                   1420:  * nodes is then linked to each of the targets as one of its children.
1.368     rillig   1421:  *
                   1422:  * Certain targets and sources such as .PHONY or .PRECIOUS are handled
1.585     rillig   1423:  * specially, see ParseSpecial.
1.368     rillig   1424:  *
1.585     rillig   1425:  * Transformation rules such as '.c.o' are also handled here, see
                   1426:  * Suff_AddTransform.
1.441     rillig   1427:  *
                   1428:  * Upon return, the value of the line is unspecified.
1.368     rillig   1429:  */
                   1430: static void
1.556     rillig   1431: ParseDependency(char *line)
1.368     rillig   1432: {
1.600     rillig   1433:        char *p;
1.583     rillig   1434:        SearchPathList *paths;  /* search paths to alter when parsing a list
                   1435:                                 * of .PATH targets */
1.590     rillig   1436:        GNodeType targetAttr;   /* from special sources */
1.600     rillig   1437:        ParseSpecial special;   /* in special targets, the children are
                   1438:                                 * linked as children of the parent but not
                   1439:                                 * vice versa */
1.469     rillig   1440:
1.556     rillig   1441:        DEBUG1(PARSE, "ParseDependency(%s)\n", line);
1.600     rillig   1442:        p = line;
                   1443:        paths = NULL;
1.590     rillig   1444:        targetAttr = OP_NONE;
1.600     rillig   1445:        special = SP_NOT;
1.469     rillig   1446:
1.600     rillig   1447:        if (!ParseDependencyTargets(&p, line, &special, &targetAttr, &paths))
1.469     rillig   1448:                goto out;
                   1449:
                   1450:        if (!Lst_IsEmpty(targets))
1.587     rillig   1451:                ParseDependencyCheckSpecial(special);
1.469     rillig   1452:
1.600     rillig   1453:        ApplyDependencyOperator(ParseDependencyOp(&p));
1.469     rillig   1454:
1.600     rillig   1455:        pp_skip_whitespace(&p);
1.469     rillig   1456:
1.600     rillig   1457:        ParseDependencySources(p, targetAttr, special, &paths);
1.1       cgd      1458:
1.112     christos 1459: out:
1.469     rillig   1460:        if (paths != NULL)
                   1461:                Lst_Free(paths);
1.1       cgd      1462: }
                   1463:
1.605     rillig   1464: typedef enum VarAssignOp {
                   1465:        VAR_NORMAL,             /* = */
                   1466:        VAR_APPEND,             /* += */
                   1467:        VAR_DEFAULT,            /* ?= */
                   1468:        VAR_SUBST,              /* := */
                   1469:        VAR_SHELL               /* != or :sh= */
                   1470: } VarAssignOp;
                   1471:
                   1472: typedef struct VarAssign {
                   1473:        char *varname;          /* unexpanded */
                   1474:        VarAssignOp op;
                   1475:        const char *value;      /* unexpanded */
                   1476: } VarAssign;
                   1477:
1.469     rillig   1478: /*
                   1479:  * Determine the assignment operator and adjust the end of the variable
                   1480:  * name accordingly.
                   1481:  */
1.606     rillig   1482: static VarAssign
                   1483: AdjustVarassignOp(const char *name, const char *nameEnd, const char *op,
                   1484:                  const char *value)
1.388     rillig   1485: {
1.469     rillig   1486:        VarAssignOp type;
1.606     rillig   1487:        VarAssign va;
1.469     rillig   1488:
                   1489:        if (op > name && op[-1] == '+') {
1.579     rillig   1490:                op--;
1.469     rillig   1491:                type = VAR_APPEND;
                   1492:
                   1493:        } else if (op > name && op[-1] == '?') {
                   1494:                op--;
                   1495:                type = VAR_DEFAULT;
                   1496:
                   1497:        } else if (op > name && op[-1] == ':') {
                   1498:                op--;
                   1499:                type = VAR_SUBST;
                   1500:
                   1501:        } else if (op > name && op[-1] == '!') {
                   1502:                op--;
                   1503:                type = VAR_SHELL;
1.388     rillig   1504:
1.469     rillig   1505:        } else {
                   1506:                type = VAR_NORMAL;
1.388     rillig   1507: #ifdef SUNSHCMD
1.469     rillig   1508:                while (op > name && ch_isspace(op[-1]))
                   1509:                        op--;
1.388     rillig   1510:
1.608     rillig   1511:                if (op - name >= 3 && memcmp(op - 3, ":sh", 3) == 0) {
1.579     rillig   1512:                        op -= 3;
1.469     rillig   1513:                        type = VAR_SHELL;
                   1514:                }
                   1515: #endif
1.388     rillig   1516:        }
                   1517:
1.606     rillig   1518:        va.varname = bmake_strsedup(name, nameEnd < op ? nameEnd : op);
                   1519:        va.op = type;
                   1520:        va.value = value;
                   1521:        return va;
1.388     rillig   1522: }
                   1523:
1.469     rillig   1524: /*
                   1525:  * Parse a variable assignment, consisting of a single-word variable name,
1.368     rillig   1526:  * optional whitespace, an assignment operator, optional whitespace and the
                   1527:  * variable value.
1.84      wiz      1528:  *
1.410     rillig   1529:  * Note: There is a lexical ambiguity with assignment modifier characters
                   1530:  * in variable names. This routine interprets the character before the =
                   1531:  * as a modifier. Therefore, an assignment like
                   1532:  *     C++=/usr/bin/CC
                   1533:  * is interpreted as "C+ +=" instead of "C++ =".
                   1534:  *
1.469     rillig   1535:  * Used for both lines in a file and command line arguments.
                   1536:  */
1.605     rillig   1537: static bool
1.368     rillig   1538: Parse_IsVar(const char *p, VarAssign *out_var)
1.1       cgd      1539: {
1.606     rillig   1540:        const char *nameStart;
                   1541:        const char *nameEnd;
                   1542:        const char *eq;
1.469     rillig   1543:        const char *firstSpace = NULL;
                   1544:        int level = 0;
                   1545:
                   1546:        cpp_skip_hspace(&p);    /* Skip to variable name */
                   1547:
                   1548:        /*
                   1549:         * During parsing, the '+' of the '+=' operator is initially parsed
                   1550:         * as part of the variable name.  It is later corrected, as is the
                   1551:         * ':sh' modifier. Of these two (nameEnd and op), the earlier one
                   1552:         * determines the actual end of the variable name.
                   1553:         */
1.606     rillig   1554:        nameStart = p;
1.368     rillig   1555: #ifdef CLEANUP
1.606     rillig   1556:        nameEnd = NULL;
                   1557:        eq = NULL;
1.368     rillig   1558: #endif
1.356     rillig   1559:
1.469     rillig   1560:        /*
                   1561:         * Scan for one of the assignment operators outside a variable
                   1562:         * expansion.
                   1563:         */
                   1564:        while (*p != '\0') {
                   1565:                char ch = *p++;
                   1566:                if (ch == '(' || ch == '{') {
                   1567:                        level++;
                   1568:                        continue;
                   1569:                }
                   1570:                if (ch == ')' || ch == '}') {
                   1571:                        level--;
                   1572:                        continue;
                   1573:                }
                   1574:
                   1575:                if (level != 0)
                   1576:                        continue;
                   1577:
                   1578:                if (ch == ' ' || ch == '\t')
                   1579:                        if (firstSpace == NULL)
                   1580:                                firstSpace = p - 1;
                   1581:                while (ch == ' ' || ch == '\t')
                   1582:                        ch = *p++;
1.368     rillig   1583:
1.191     sjg      1584: #ifdef SUNSHCMD
1.469     rillig   1585:                if (ch == ':' && p[0] == 's' && p[1] == 'h') {
                   1586:                        p += 2;
                   1587:                        continue;
                   1588:                }
                   1589: #endif
1.607     rillig   1590:                if (ch == '=')
1.606     rillig   1591:                        eq = p - 1;
1.607     rillig   1592:                else if (*p == '=' &&
                   1593:                    (ch == '+' || ch == ':' || ch == '?' || ch == '!'))
1.606     rillig   1594:                        eq = p;
1.607     rillig   1595:                else if (firstSpace != NULL)
1.553     rillig   1596:                        return false;
1.607     rillig   1597:                else
                   1598:                        continue;
                   1599:
                   1600:                nameEnd = firstSpace != NULL ? firstSpace : eq;
                   1601:                p = eq + 1;
                   1602:                cpp_skip_whitespace(&p);
                   1603:                *out_var = AdjustVarassignOp(nameStart, nameEnd, eq, p);
                   1604:                return true;
1.191     sjg      1605:        }
1.1       cgd      1606:
1.553     rillig   1607:        return false;
1.1       cgd      1608: }
                   1609:
1.469     rillig   1610: /*
                   1611:  * Check for syntax errors such as unclosed expressions or unknown modifiers.
                   1612:  */
1.368     rillig   1613: static void
1.546     rillig   1614: VarCheckSyntax(VarAssignOp type, const char *uvalue, GNode *scope)
1.368     rillig   1615: {
1.515     rillig   1616:        if (opts.strict) {
1.469     rillig   1617:                if (type != VAR_SUBST && strchr(uvalue, '$') != NULL) {
                   1618:                        char *expandedValue;
                   1619:
1.551     rillig   1620:                        (void)Var_Subst(uvalue, scope, VARE_PARSE_ONLY,
1.469     rillig   1621:                            &expandedValue);
                   1622:                        /* TODO: handle errors */
                   1623:                        free(expandedValue);
                   1624:                }
1.243     sjg      1625:        }
1.368     rillig   1626: }
                   1627:
1.390     rillig   1628: static void
1.548     rillig   1629: VarAssign_EvalSubst(GNode *scope, const char *name, const char *uvalue,
1.506     rillig   1630:                    FStr *out_avalue)
1.390     rillig   1631: {
1.469     rillig   1632:        char *evalue;
                   1633:
                   1634:        /*
                   1635:         * make sure that we set the variable the first time to nothing
1.538     rillig   1636:         * so that it gets substituted.
                   1637:         *
                   1638:         * TODO: Add a test that demonstrates why this code is needed,
                   1639:         *  apart from making the debug log longer.
1.469     rillig   1640:         */
1.548     rillig   1641:        if (!Var_ExistsExpand(scope, name))
                   1642:                Var_SetExpand(scope, name, "");
1.469     rillig   1643:
1.552     rillig   1644:        (void)Var_Subst(uvalue, scope, VARE_KEEP_DOLLAR_UNDEF, &evalue);
1.469     rillig   1645:        /* TODO: handle errors */
1.520     rillig   1646:
1.548     rillig   1647:        Var_SetExpand(scope, name, evalue);
1.390     rillig   1648:
1.536     rillig   1649:        *out_avalue = FStr_InitOwn(evalue);
1.390     rillig   1650: }
                   1651:
                   1652: static void
1.546     rillig   1653: VarAssign_EvalShell(const char *name, const char *uvalue, GNode *scope,
1.506     rillig   1654:                    FStr *out_avalue)
1.390     rillig   1655: {
1.507     rillig   1656:        FStr cmd;
                   1657:        const char *errfmt;
1.469     rillig   1658:        char *cmdOut;
                   1659:
1.507     rillig   1660:        cmd = FStr_InitRefer(uvalue);
                   1661:        if (strchr(cmd.str, '$') != NULL) {
                   1662:                char *expanded;
1.552     rillig   1663:                (void)Var_Subst(cmd.str, SCOPE_CMDLINE, VARE_UNDEFERR,
                   1664:                    &expanded);
1.469     rillig   1665:                /* TODO: handle errors */
1.507     rillig   1666:                cmd = FStr_InitOwn(expanded);
1.469     rillig   1667:        }
                   1668:
1.507     rillig   1669:        cmdOut = Cmd_Exec(cmd.str, &errfmt);
1.548     rillig   1670:        Var_SetExpand(scope, name, cmdOut);
1.506     rillig   1671:        *out_avalue = FStr_InitOwn(cmdOut);
1.390     rillig   1672:
1.469     rillig   1673:        if (errfmt != NULL)
1.509     rillig   1674:                Parse_Error(PARSE_WARNING, errfmt, cmd.str);
1.390     rillig   1675:
1.507     rillig   1676:        FStr_Done(&cmd);
1.390     rillig   1677: }
                   1678:
1.524     rillig   1679: /*
                   1680:  * Perform a variable assignment.
1.391     rillig   1681:  *
1.554     rillig   1682:  * The actual value of the variable is returned in *out_true_avalue.
1.538     rillig   1683:  * Especially for VAR_SUBST and VAR_SHELL this can differ from the literal
                   1684:  * value.
                   1685:  *
                   1686:  * Return whether the assignment was actually performed, which is usually
                   1687:  * the case.  It is only skipped if the operator is '?=' and the variable
                   1688:  * already exists.
1.524     rillig   1689:  */
1.553     rillig   1690: static bool
1.391     rillig   1691: VarAssign_Eval(const char *name, VarAssignOp op, const char *uvalue,
1.554     rillig   1692:               GNode *scope, FStr *out_true_avalue)
1.368     rillig   1693: {
1.506     rillig   1694:        FStr avalue = FStr_InitRefer(uvalue);
1.469     rillig   1695:
                   1696:        if (op == VAR_APPEND)
1.548     rillig   1697:                Var_AppendExpand(scope, name, uvalue);
1.469     rillig   1698:        else if (op == VAR_SUBST)
1.548     rillig   1699:                VarAssign_EvalSubst(scope, name, uvalue, &avalue);
1.469     rillig   1700:        else if (op == VAR_SHELL)
1.546     rillig   1701:                VarAssign_EvalShell(name, uvalue, scope, &avalue);
1.469     rillig   1702:        else {
1.548     rillig   1703:                if (op == VAR_DEFAULT && Var_ExistsExpand(scope, name))
1.553     rillig   1704:                        return false;
1.353     rillig   1705:
1.469     rillig   1706:                /* Normal assignment -- just do it. */
1.548     rillig   1707:                Var_SetExpand(scope, name, uvalue);
1.469     rillig   1708:        }
                   1709:
1.554     rillig   1710:        *out_true_avalue = avalue;
1.553     rillig   1711:        return true;
1.368     rillig   1712: }
                   1713:
                   1714: static void
                   1715: VarAssignSpecial(const char *name, const char *avalue)
                   1716: {
1.469     rillig   1717:        if (strcmp(name, MAKEOVERRIDES) == 0)
1.583     rillig   1718:                Main_ExportMAKEFLAGS(false);    /* re-export MAKEFLAGS */
1.469     rillig   1719:        else if (strcmp(name, ".CURDIR") == 0) {
                   1720:                /*
                   1721:                 * Someone is being (too?) clever...
                   1722:                 * Let's pretend they know what they are doing and
                   1723:                 * re-initialize the 'cur' CachedDir.
                   1724:                 */
                   1725:                Dir_InitCur(avalue);
                   1726:                Dir_SetPATH();
                   1727:        } else if (strcmp(name, MAKE_JOB_PREFIX) == 0)
                   1728:                Job_SetPrefix();
                   1729:        else if (strcmp(name, MAKE_EXPORTED) == 0)
1.473     rillig   1730:                Var_ExportVars(avalue);
1.368     rillig   1731: }
                   1732:
1.579     rillig   1733: /* Perform the variable assignment in the given scope. */
1.605     rillig   1734: static void
1.556     rillig   1735: Parse_Var(VarAssign *var, GNode *scope)
1.368     rillig   1736: {
1.583     rillig   1737:        FStr avalue;            /* actual value (maybe expanded) */
1.368     rillig   1738:
1.546     rillig   1739:        VarCheckSyntax(var->op, var->value, scope);
                   1740:        if (VarAssign_Eval(var->varname, var->op, var->value, scope, &avalue)) {
1.506     rillig   1741:                VarAssignSpecial(var->varname, avalue.str);
                   1742:                FStr_Done(&avalue);
                   1743:        }
1.368     rillig   1744:
1.469     rillig   1745:        free(var->varname);
1.1       cgd      1746: }
1.23      christos 1747:
1.200     christos 1748:
1.524     rillig   1749: /*
                   1750:  * See if the command possibly calls a sub-make by using the variable
                   1751:  * expressions ${.MAKE}, ${MAKE} or the plain word "make".
                   1752:  */
1.553     rillig   1753: static bool
1.432     rillig   1754: MaybeSubMake(const char *cmd)
1.195     christos 1755: {
1.469     rillig   1756:        const char *start;
1.432     rillig   1757:
1.469     rillig   1758:        for (start = cmd; *start != '\0'; start++) {
                   1759:                const char *p = start;
                   1760:                char endc;
                   1761:
                   1762:                /* XXX: What if progname != "make"? */
1.579     rillig   1763:                if (strncmp(p, "make", 4) == 0)
1.469     rillig   1764:                        if (start == cmd || !ch_isalnum(p[-1]))
                   1765:                                if (!ch_isalnum(p[4]))
1.553     rillig   1766:                                        return true;
1.469     rillig   1767:
                   1768:                if (*p != '$')
                   1769:                        continue;
                   1770:                p++;
                   1771:
                   1772:                if (*p == '{')
                   1773:                        endc = '}';
                   1774:                else if (*p == '(')
                   1775:                        endc = ')';
                   1776:                else
                   1777:                        continue;
                   1778:                p++;
1.432     rillig   1779:
1.469     rillig   1780:                if (*p == '.')  /* Accept either ${.MAKE} or ${MAKE}. */
                   1781:                        p++;
1.432     rillig   1782:
1.619     rillig   1783:                if (strncmp(p, "MAKE", 4) == 0 && p[4] == endc)
                   1784:                        return true;
1.469     rillig   1785:        }
1.553     rillig   1786:        return false;
1.195     christos 1787: }
                   1788:
1.524     rillig   1789: /*
                   1790:  * Append the command to the target node.
1.1       cgd      1791:  *
1.327     rillig   1792:  * The node may be marked as a submake node if the command is determined to
1.524     rillig   1793:  * be that.
                   1794:  */
1.327     rillig   1795: static void
1.593     rillig   1796: GNode_AddCommand(GNode *gn, char *cmd)
1.9       jtc      1797: {
1.469     rillig   1798:        /* Add to last (ie current) cohort for :: targets */
                   1799:        if ((gn->type & OP_DOUBLEDEP) && gn->cohorts.last != NULL)
                   1800:                gn = gn->cohorts.last->datum;
                   1801:
                   1802:        /* if target already supplied, ignore commands */
                   1803:        if (!(gn->type & OP_HAS_COMMANDS)) {
                   1804:                Lst_Append(&gn->commands, cmd);
                   1805:                if (MaybeSubMake(cmd))
                   1806:                        gn->type |= OP_SUBMAKE;
1.562     rillig   1807:                RememberLocation(gn);
1.469     rillig   1808:        } else {
1.327     rillig   1809: #if 0
1.469     rillig   1810:                /* XXX: We cannot do this until we fix the tree */
                   1811:                Lst_Append(&gn->commands, cmd);
                   1812:                Parse_Error(PARSE_WARNING,
                   1813:                    "overriding commands for target \"%s\"; "
                   1814:                    "previous commands defined at %s: %d ignored",
                   1815:                    gn->name, gn->fname, gn->lineno);
1.203     joerg    1816: #else
1.469     rillig   1817:                Parse_Error(PARSE_WARNING,
1.374     rillig   1818:                    "duplicate script for target \"%s\" ignored",
                   1819:                    gn->name);
1.469     rillig   1820:                ParseErrorInternal(gn->fname, (size_t)gn->lineno, PARSE_WARNING,
                   1821:                    "using previous script for \"%s\" defined here",
                   1822:                    gn->name);
1.203     joerg    1823: #endif
1.469     rillig   1824:        }
1.1       cgd      1825: }
                   1826:
1.469     rillig   1827: /*
                   1828:  * Add a directory to the path searched for included makefiles bracketed
                   1829:  * by double-quotes.
                   1830:  */
1.1       cgd      1831: void
1.344     rillig   1832: Parse_AddIncludeDir(const char *dir)
1.1       cgd      1833: {
1.529     rillig   1834:        (void)SearchPath_Add(parseIncPath, dir);
1.1       cgd      1835: }
                   1836:
1.524     rillig   1837: /*
                   1838:  * Handle one of the .[-ds]include directives by remembering the current file
1.441     rillig   1839:  * and pushing the included file on the stack.  After the included file has
1.574     rillig   1840:  * finished, parsing continues with the including file; see Parse_PushInput
1.441     rillig   1841:  * and ParseEOF.
                   1842:  *
                   1843:  * System includes are looked up in sysIncPath, any other includes are looked
                   1844:  * up in the parsedir and then in the directories specified by the -I command
                   1845:  * line options.
1.1       cgd      1846:  */
                   1847: static void
1.567     rillig   1848: IncludeFile(const char *file, bool isSystem, bool depinc, bool silent)
1.1       cgd      1849: {
1.616     rillig   1850:        Buffer buf;
1.469     rillig   1851:        char *fullname;         /* full pathname of file */
                   1852:        char *newName;
                   1853:        char *slash, *incdir;
                   1854:        int fd;
                   1855:        int i;
                   1856:
                   1857:        fullname = file[0] == '/' ? bmake_strdup(file) : NULL;
                   1858:
                   1859:        if (fullname == NULL && !isSystem) {
                   1860:                /*
                   1861:                 * Include files contained in double-quotes are first searched
                   1862:                 * relative to the including file's location. We don't want to
                   1863:                 * cd there, of course, so we just tack on the old file's
                   1864:                 * leading path components and call Dir_FindFile to see if
                   1865:                 * we can locate the file.
                   1866:                 */
                   1867:
1.576     rillig   1868:                incdir = bmake_strdup(CurFile()->name.str);
1.469     rillig   1869:                slash = strrchr(incdir, '/');
                   1870:                if (slash != NULL) {
                   1871:                        *slash = '\0';
                   1872:                        /*
                   1873:                         * Now do lexical processing of leading "../" on the
                   1874:                         * filename.
                   1875:                         */
                   1876:                        for (i = 0; strncmp(file + i, "../", 3) == 0; i += 3) {
                   1877:                                slash = strrchr(incdir + 1, '/');
                   1878:                                if (slash == NULL || strcmp(slash, "/..") == 0)
                   1879:                                        break;
                   1880:                                *slash = '\0';
                   1881:                        }
                   1882:                        newName = str_concat3(incdir, "/", file + i);
                   1883:                        fullname = Dir_FindFile(newName, parseIncPath);
                   1884:                        if (fullname == NULL)
                   1885:                                fullname = Dir_FindFile(newName,
                   1886:                                    &dirSearchPath);
                   1887:                        free(newName);
                   1888:                }
                   1889:                free(incdir);
                   1890:
                   1891:                if (fullname == NULL) {
                   1892:                        /*
                   1893:                         * Makefile wasn't found in same directory as included
                   1894:                         * makefile.
                   1895:                         *
                   1896:                         * Search for it first on the -I search path, then on
                   1897:                         * the .PATH search path, if not found in a -I
                   1898:                         * directory. If we have a suffix-specific path, we
                   1899:                         * should use that.
                   1900:                         */
                   1901:                        const char *suff;
                   1902:                        SearchPath *suffPath = NULL;
                   1903:
1.516     rillig   1904:                        if ((suff = strrchr(file, '.')) != NULL) {
1.469     rillig   1905:                                suffPath = Suff_GetPath(suff);
                   1906:                                if (suffPath != NULL)
                   1907:                                        fullname = Dir_FindFile(file, suffPath);
                   1908:                        }
                   1909:                        if (fullname == NULL) {
                   1910:                                fullname = Dir_FindFile(file, parseIncPath);
                   1911:                                if (fullname == NULL)
                   1912:                                        fullname = Dir_FindFile(file,
                   1913:                                            &dirSearchPath);
                   1914:                        }
                   1915:                }
1.1       cgd      1916:        }
1.140     dsl      1917:
1.469     rillig   1918:        /* Looking for a system file or file still not found */
1.142     sjg      1919:        if (fullname == NULL) {
1.469     rillig   1920:                /*
                   1921:                 * Look for it on the system path
                   1922:                 */
1.531     rillig   1923:                SearchPath *path = Lst_IsEmpty(&sysIncPath->dirs)
                   1924:                    ? defSysIncPath : sysIncPath;
1.469     rillig   1925:                fullname = Dir_FindFile(file, path);
                   1926:        }
                   1927:
                   1928:        if (fullname == NULL) {
                   1929:                if (!silent)
                   1930:                        Parse_Error(PARSE_FATAL, "Could not find %s", file);
                   1931:                return;
                   1932:        }
                   1933:
                   1934:        /* Actually open the file... */
                   1935:        fd = open(fullname, O_RDONLY);
                   1936:        if (fd == -1) {
                   1937:                if (!silent)
                   1938:                        Parse_Error(PARSE_FATAL, "Cannot open %s", fullname);
                   1939:                free(fullname);
                   1940:                return;
                   1941:        }
                   1942:
1.616     rillig   1943:        buf = loadfile(fullname, fd);
1.613     rillig   1944:        (void)close(fd);
1.469     rillig   1945:
1.616     rillig   1946:        Parse_PushInput(fullname, 0, buf, NULL);
1.469     rillig   1947:        if (depinc)
                   1948:                doing_depend = depinc;  /* only turn it on */
1.575     rillig   1949:        free(fullname);
1.123     dsl      1950: }
                   1951:
1.566     rillig   1952: /*
                   1953:  * Parse a directive like '.include' or '.-include'.
                   1954:  *
                   1955:  * .include "user-makefile.mk"
                   1956:  * .include <system-makefile.mk>
                   1957:  */
1.123     dsl      1958: static void
1.556     rillig   1959: ParseInclude(char *directive)
1.123     dsl      1960: {
1.567     rillig   1961:        char endc;              /* '>' or '"' */
                   1962:        char *p;
1.553     rillig   1963:        bool silent = directive[0] != 'i';
1.566     rillig   1964:        FStr file;
1.123     dsl      1965:
1.566     rillig   1966:        p = directive + (silent ? 8 : 7);
                   1967:        pp_skip_hspace(&p);
1.123     dsl      1968:
1.566     rillig   1969:        if (*p != '"' && *p != '<') {
1.469     rillig   1970:                Parse_Error(PARSE_FATAL,
1.374     rillig   1971:                    ".include filename must be delimited by '\"' or '<'");
1.469     rillig   1972:                return;
                   1973:        }
1.123     dsl      1974:
1.566     rillig   1975:        if (*p++ == '<')
1.469     rillig   1976:                endc = '>';
                   1977:        else
                   1978:                endc = '"';
1.566     rillig   1979:        file = FStr_InitRefer(p);
1.469     rillig   1980:
                   1981:        /* Skip to matching delimiter */
1.566     rillig   1982:        while (*p != '\0' && *p != endc)
                   1983:                p++;
1.123     dsl      1984:
1.566     rillig   1985:        if (*p != endc) {
1.469     rillig   1986:                Parse_Error(PARSE_FATAL,
1.441     rillig   1987:                    "Unclosed .include filename. '%c' expected", endc);
1.469     rillig   1988:                return;
                   1989:        }
1.430     rillig   1990:
1.566     rillig   1991:        *p = '\0';
1.123     dsl      1992:
1.567     rillig   1993:        if (strchr(file.str, '$') != NULL) {
                   1994:                char *xfile;
                   1995:                Var_Subst(file.str, SCOPE_CMDLINE, VARE_WANTRES, &xfile);
                   1996:                /* TODO: handle errors */
                   1997:                file = FStr_InitOwn(xfile);
                   1998:        }
1.123     dsl      1999:
1.567     rillig   2000:        IncludeFile(file.str, endc == '>', directive[0] == 'd', silent);
                   2001:        FStr_Done(&file);
1.1       cgd      2002: }
                   2003:
1.524     rillig   2004: /*
                   2005:  * Split filename into dirname + basename, then assign these to the
                   2006:  * given variables.
                   2007:  */
1.193     christos 2008: static void
1.281     rillig   2009: SetFilenameVars(const char *filename, const char *dirvar, const char *filevar)
1.193     christos 2010: {
1.550     rillig   2011:        const char *slash, *basename;
                   2012:        FStr dirname;
1.469     rillig   2013:
                   2014:        slash = strrchr(filename, '/');
                   2015:        if (slash == NULL) {
1.550     rillig   2016:                dirname = FStr_InitRefer(curdir);
1.469     rillig   2017:                basename = filename;
                   2018:        } else {
1.550     rillig   2019:                dirname = FStr_InitOwn(bmake_strsedup(filename, slash));
1.469     rillig   2020:                basename = slash + 1;
                   2021:        }
1.281     rillig   2022:
1.568     rillig   2023:        Global_Set(dirvar, dirname.str);
                   2024:        Global_Set(filevar, basename);
1.469     rillig   2025:
1.586     rillig   2026:        DEBUG4(PARSE, "SetFilenameVars: ${%s} = `%s' ${%s} = `%s'\n",
                   2027:            dirvar, dirname.str, filevar, basename);
1.550     rillig   2028:        FStr_Done(&dirname);
1.281     rillig   2029: }
                   2030:
1.469     rillig   2031: /*
                   2032:  * Return the immediately including file.
1.281     rillig   2033:  *
                   2034:  * This is made complicated since the .for loop is implemented as a special
1.469     rillig   2035:  * kind of .include; see For_Run.
                   2036:  */
1.281     rillig   2037: static const char *
                   2038: GetActuallyIncludingFile(void)
                   2039: {
1.469     rillig   2040:        size_t i;
                   2041:        const IFile *incs = GetInclude(0);
1.193     christos 2042:
1.469     rillig   2043:        for (i = includes.len; i >= 2; i--)
1.617     rillig   2044:                if (incs[i - 1].forLoop == NULL)
1.576     rillig   2045:                        return incs[i - 2].name.str;
1.469     rillig   2046:        return NULL;
1.193     christos 2047: }
1.281     rillig   2048:
1.285     rillig   2049: /* Set .PARSEDIR, .PARSEFILE, .INCLUDEDFROMDIR and .INCLUDEDFROMFILE. */
1.44      aidan    2050: static void
1.593     rillig   2051: SetParseFile(const char *filename)
1.44      aidan    2052: {
1.469     rillig   2053:        const char *including;
1.44      aidan    2054:
1.469     rillig   2055:        SetFilenameVars(filename, ".PARSEDIR", ".PARSEFILE");
1.281     rillig   2056:
1.469     rillig   2057:        including = GetActuallyIncludingFile();
                   2058:        if (including != NULL) {
                   2059:                SetFilenameVars(including,
                   2060:                    ".INCLUDEDFROMDIR", ".INCLUDEDFROMFILE");
                   2061:        } else {
1.547     rillig   2062:                Global_Delete(".INCLUDEDFROMDIR");
                   2063:                Global_Delete(".INCLUDEDFROMFILE");
1.469     rillig   2064:        }
1.44      aidan    2065: }
                   2066:
1.553     rillig   2067: static bool
1.418     rillig   2068: StrContainsWord(const char *str, const char *word)
                   2069: {
1.469     rillig   2070:        size_t strLen = strlen(str);
                   2071:        size_t wordLen = strlen(word);
1.588     rillig   2072:        const char *p;
1.469     rillig   2073:
                   2074:        if (strLen < wordLen)
1.585     rillig   2075:                return false;
1.469     rillig   2076:
                   2077:        for (p = str; p != NULL; p = strchr(p, ' ')) {
                   2078:                if (*p == ' ')
                   2079:                        p++;
1.588     rillig   2080:                if (p > str + strLen - wordLen)
1.585     rillig   2081:                        return false;
1.469     rillig   2082:
                   2083:                if (memcmp(p, word, wordLen) == 0 &&
                   2084:                    (p[wordLen] == '\0' || p[wordLen] == ' '))
1.553     rillig   2085:                        return true;
1.469     rillig   2086:        }
1.553     rillig   2087:        return false;
1.469     rillig   2088: }
                   2089:
                   2090: /*
                   2091:  * XXX: Searching through a set of words with this linear search is
                   2092:  * inefficient for variables that contain thousands of words.
                   2093:  *
                   2094:  * XXX: The paths in this list don't seem to be normalized in any way.
                   2095:  */
1.553     rillig   2096: static bool
1.418     rillig   2097: VarContainsWord(const char *varname, const char *word)
                   2098: {
1.548     rillig   2099:        FStr val = Var_Value(SCOPE_GLOBAL, varname);
1.553     rillig   2100:        bool found = val.str != NULL && StrContainsWord(val.str, word);
1.505     rillig   2101:        FStr_Done(&val);
1.469     rillig   2102:        return found;
1.418     rillig   2103: }
                   2104:
1.524     rillig   2105: /*
                   2106:  * Track the makefiles we read - so makefiles can set dependencies on them.
1.441     rillig   2107:  * Avoid adding anything more than once.
                   2108:  *
                   2109:  * Time complexity: O(n) per call, in total O(n^2), where n is the number
1.524     rillig   2110:  * of makefiles that have been loaded.
                   2111:  */
1.184     sjg      2112: static void
1.593     rillig   2113: TrackInput(const char *name)
1.184     sjg      2114: {
1.469     rillig   2115:        if (!VarContainsWord(MAKE_MAKEFILES, name))
1.542     rillig   2116:                Global_Append(MAKE_MAKEFILES, name);
1.184     sjg      2117: }
1.137     sjg      2118:
1.44      aidan    2119:
1.469     rillig   2120: /*
                   2121:  * Start parsing from the given source.
1.5       cgd      2122:  *
1.469     rillig   2123:  * The given file is added to the includes stack.
                   2124:  */
1.5       cgd      2125: void
1.616     rillig   2126: Parse_PushInput(const char *name, int lineno, Buffer buf,
                   2127:                struct ForLoop *forLoop)
1.5       cgd      2128: {
1.469     rillig   2129:        IFile *curFile;
                   2130:
1.617     rillig   2131:        if (forLoop != NULL)
1.576     rillig   2132:                name = CurFile()->name.str;
1.469     rillig   2133:        else
1.593     rillig   2134:                TrackInput(name);
1.469     rillig   2135:
1.574     rillig   2136:        DEBUG3(PARSE, "Parse_PushInput: %s %s, line %d\n",
1.617     rillig   2137:            forLoop != NULL ? ".for loop in": "file", name, lineno);
1.5       cgd      2138:
1.469     rillig   2139:        curFile = Vector_Push(&includes);
1.576     rillig   2140:        curFile->name = FStr_InitOwn(bmake_strdup(name));
1.496     rillig   2141:        curFile->lineno = lineno;
1.618     rillig   2142:        curFile->forBodyLineno = lineno;
1.616     rillig   2143:        curFile->buf = buf;
1.469     rillig   2144:        curFile->depending = doing_depend;      /* restore this on EOF */
1.616     rillig   2145:        curFile->forLoop = forLoop;
1.469     rillig   2146:
1.616     rillig   2147:        if (forLoop != NULL && !For_NextIteration(forLoop, &curFile->buf))
                   2148:                abort();        /* see For_Run */
1.469     rillig   2149:
1.616     rillig   2150:        curFile->buf_ptr = curFile->buf.data;
                   2151:        curFile->buf_end = curFile->buf.data + curFile->buf.len;
1.469     rillig   2152:        curFile->cond_depth = Cond_save_depth();
1.593     rillig   2153:        SetParseFile(name);
1.5       cgd      2154: }
                   2155:
1.375     rillig   2156: /* Check if the directive is an include directive. */
1.553     rillig   2157: static bool
                   2158: IsInclude(const char *dir, bool sysv)
1.228     christos 2159: {
1.298     rillig   2160:        if (dir[0] == 's' || dir[0] == '-' || (dir[0] == 'd' && !sysv))
                   2161:                dir++;
1.228     christos 2162:
1.298     rillig   2163:        if (strncmp(dir, "include", 7) != 0)
1.553     rillig   2164:                return false;
1.228     christos 2165:
1.248     rillig   2166:        /* Space is not mandatory for BSD .include */
1.298     rillig   2167:        return !sysv || ch_isspace(dir[7]);
1.228     christos 2168: }
                   2169:
                   2170:
1.5       cgd      2171: #ifdef SYSVINCLUDE
1.284     rillig   2172: /* Check if the line is a SYSV include directive. */
1.553     rillig   2173: static bool
1.228     christos 2174: IsSysVInclude(const char *line)
                   2175: {
                   2176:        const char *p;
                   2177:
1.553     rillig   2178:        if (!IsInclude(line, true))
                   2179:                return false;
1.228     christos 2180:
1.375     rillig   2181:        /* Avoid interpreting a dependency line as an include */
1.228     christos 2182:        for (p = line; (p = strchr(p, ':')) != NULL;) {
1.430     rillig   2183:
                   2184:                /* end of line -> it's a dependency */
                   2185:                if (*++p == '\0')
1.553     rillig   2186:                        return false;
1.430     rillig   2187:
                   2188:                /* '::' operator or ': ' -> it's a dependency */
                   2189:                if (*p == ':' || ch_isspace(*p))
1.553     rillig   2190:                        return false;
1.228     christos 2191:        }
1.553     rillig   2192:        return true;
1.228     christos 2193: }
                   2194:
1.284     rillig   2195: /* Push to another file.  The line points to the word "include". */
1.5       cgd      2196: static void
1.84      wiz      2197: ParseTraditionalInclude(char *line)
1.5       cgd      2198: {
1.469     rillig   2199:        char *cp;               /* current position in file spec */
1.553     rillig   2200:        bool done = false;
                   2201:        bool silent = line[0] != 'i';
1.469     rillig   2202:        char *file = line + (silent ? 8 : 7);
                   2203:        char *all_files;
                   2204:
1.586     rillig   2205:        DEBUG1(PARSE, "ParseTraditionalInclude: %s\n", file);
1.469     rillig   2206:
                   2207:        pp_skip_whitespace(&file);
                   2208:
1.545     rillig   2209:        (void)Var_Subst(file, SCOPE_CMDLINE, VARE_WANTRES, &all_files);
1.469     rillig   2210:        /* TODO: handle errors */
                   2211:
                   2212:        for (file = all_files; !done; file = cp + 1) {
                   2213:                /* Skip to end of line or next whitespace */
                   2214:                for (cp = file; *cp != '\0' && !ch_isspace(*cp); cp++)
                   2215:                        continue;
                   2216:
                   2217:                if (*cp != '\0')
                   2218:                        *cp = '\0';
                   2219:                else
1.553     rillig   2220:                        done = true;
1.38      christos 2221:
1.553     rillig   2222:                IncludeFile(file, false, false, silent);
1.469     rillig   2223:        }
1.580     rillig   2224:
1.469     rillig   2225:        free(all_files);
1.5       cgd      2226: }
                   2227: #endif
                   2228:
1.183     sjg      2229: #ifdef GMAKEEXPORT
1.375     rillig   2230: /* Parse "export <variable>=<value>", and actually export it. */
1.182     christos 2231: static void
                   2232: ParseGmakeExport(char *line)
                   2233: {
1.469     rillig   2234:        char *variable = line + 6;
                   2235:        char *value;
1.182     christos 2236:
1.586     rillig   2237:        DEBUG1(PARSE, "ParseGmakeExport: %s\n", variable);
1.182     christos 2238:
1.469     rillig   2239:        pp_skip_whitespace(&variable);
1.182     christos 2240:
1.526     rillig   2241:        for (value = variable; *value != '\0' && *value != '='; value++)
1.469     rillig   2242:                continue;
1.182     christos 2243:
1.469     rillig   2244:        if (*value != '=') {
                   2245:                Parse_Error(PARSE_FATAL,
1.284     rillig   2246:                    "Variable/Value missing from \"export\"");
1.469     rillig   2247:                return;
                   2248:        }
                   2249:        *value++ = '\0';        /* terminate variable */
1.323     rillig   2250:
1.469     rillig   2251:        /*
                   2252:         * Expand the value before putting it in the environment.
                   2253:         */
1.545     rillig   2254:        (void)Var_Subst(value, SCOPE_CMDLINE, VARE_WANTRES, &value);
1.469     rillig   2255:        /* TODO: handle errors */
                   2256:
                   2257:        setenv(variable, value, 1);
                   2258:        free(value);
1.182     christos 2259: }
                   2260: #endif
                   2261:
1.469     rillig   2262: /*
                   2263:  * Called when EOF is reached in the current file. If we were reading an
1.441     rillig   2264:  * include file or a .for loop, the includes stack is popped and things set
                   2265:  * up to go back to reading the previous file at the previous location.
1.1       cgd      2266:  *
                   2267:  * Results:
1.553     rillig   2268:  *     true to continue parsing, i.e. it had only reached the end of an
                   2269:  *     included file, false if the main file has been parsed completely.
1.1       cgd      2270:  */
1.553     rillig   2271: static bool
1.123     dsl      2272: ParseEOF(void)
1.1       cgd      2273: {
1.469     rillig   2274:        IFile *curFile = CurFile();
                   2275:
1.616     rillig   2276:        doing_depend = curFile->depending;
                   2277:        if (curFile->forLoop != NULL &&
                   2278:            For_NextIteration(curFile->forLoop, &curFile->buf)) {
                   2279:                curFile->buf_ptr = curFile->buf.data;
                   2280:                curFile->buf_end = curFile->buf.data + curFile->buf.len;
1.618     rillig   2281:                curFile->lineno = curFile->forBodyLineno;
1.616     rillig   2282:                return true;
1.615     rillig   2283:        }
1.469     rillig   2284:
1.583     rillig   2285:        /*
                   2286:         * Ensure the makefile (or .for loop) didn't have mismatched
                   2287:         * conditionals.
                   2288:         */
1.469     rillig   2289:        Cond_restore_depth(curFile->cond_depth);
                   2290:
1.576     rillig   2291:        FStr_Done(&curFile->name);
1.616     rillig   2292:        Buf_Done(&curFile->buf);
1.469     rillig   2293:        Vector_Pop(&includes);
1.155     dsl      2294:
1.469     rillig   2295:        if (includes.len == 0) {
                   2296:                /* We've run out of input */
1.547     rillig   2297:                Global_Delete(".PARSEDIR");
                   2298:                Global_Delete(".PARSEFILE");
                   2299:                Global_Delete(".INCLUDEDFROMDIR");
                   2300:                Global_Delete(".INCLUDEDFROMFILE");
1.553     rillig   2301:                return false;
1.469     rillig   2302:        }
1.170     dholland 2303:
1.469     rillig   2304:        curFile = CurFile();
                   2305:        DEBUG2(PARSE, "ParseEOF: returning to file %s, line %d\n",
1.576     rillig   2306:            curFile->name.str, curFile->lineno);
1.1       cgd      2307:
1.593     rillig   2308:        SetParseFile(curFile->name.str);
1.553     rillig   2309:        return true;
1.1       cgd      2310: }
                   2311:
1.493     rillig   2312: typedef enum ParseRawLineResult {
                   2313:        PRLR_LINE,
                   2314:        PRLR_EOF,
                   2315:        PRLR_ERROR
                   2316: } ParseRawLineResult;
                   2317:
1.489     rillig   2318: /*
1.492     rillig   2319:  * Parse until the end of a line, taking into account lines that end with
1.571     rillig   2320:  * backslash-newline.  The resulting line goes from out_line to out_line_end;
                   2321:  * the line is not null-terminated.
1.489     rillig   2322:  */
1.493     rillig   2323: static ParseRawLineResult
                   2324: ParseRawLine(IFile *curFile, char **out_line, char **out_line_end,
                   2325:             char **out_firstBackslash, char **out_firstComment)
1.489     rillig   2326: {
1.493     rillig   2327:        char *line = curFile->buf_ptr;
1.570     rillig   2328:        char *buf_end = curFile->buf_end;
1.492     rillig   2329:        char *p = line;
1.489     rillig   2330:        char *line_end = line;
1.492     rillig   2331:        char *firstBackslash = NULL;
                   2332:        char *firstComment = NULL;
1.493     rillig   2333:        ParseRawLineResult res = PRLR_LINE;
1.489     rillig   2334:
1.493     rillig   2335:        curFile->lineno++;
1.490     rillig   2336:
1.489     rillig   2337:        for (;;) {
1.492     rillig   2338:                char ch;
                   2339:
1.570     rillig   2340:                if (p == buf_end) {
1.493     rillig   2341:                        res = PRLR_EOF;
1.489     rillig   2342:                        break;
                   2343:                }
                   2344:
1.492     rillig   2345:                ch = *p;
1.489     rillig   2346:                if (ch == '\0' ||
1.570     rillig   2347:                    (ch == '\\' && p + 1 < buf_end && p[1] == '\0')) {
1.492     rillig   2348:                        Parse_Error(PARSE_FATAL, "Zero byte read from file");
1.493     rillig   2349:                        return PRLR_ERROR;
1.489     rillig   2350:                }
                   2351:
1.492     rillig   2352:                /* Treat next character after '\' as literal. */
1.489     rillig   2353:                if (ch == '\\') {
1.492     rillig   2354:                        if (firstBackslash == NULL)
                   2355:                                firstBackslash = p;
1.511     rillig   2356:                        if (p[1] == '\n') {
1.493     rillig   2357:                                curFile->lineno++;
1.570     rillig   2358:                                if (p + 2 == buf_end) {
1.511     rillig   2359:                                        line_end = p;
                   2360:                                        *line_end = '\n';
                   2361:                                        p += 2;
                   2362:                                        continue;
                   2363:                                }
                   2364:                        }
1.492     rillig   2365:                        p += 2;
                   2366:                        line_end = p;
1.570     rillig   2367:                        assert(p <= buf_end);
1.489     rillig   2368:                        continue;
                   2369:                }
                   2370:
                   2371:                /*
1.492     rillig   2372:                 * Remember the first '#' for comment stripping, unless
                   2373:                 * the previous char was '[', as in the modifier ':[#]'.
                   2374:                 */
                   2375:                if (ch == '#' && firstComment == NULL &&
                   2376:                    !(p > line && p[-1] == '['))
                   2377:                        firstComment = line_end;
1.489     rillig   2378:
1.492     rillig   2379:                p++;
1.489     rillig   2380:                if (ch == '\n')
                   2381:                        break;
                   2382:
                   2383:                /* We are not interested in trailing whitespace. */
                   2384:                if (!ch_isspace(ch))
1.492     rillig   2385:                        line_end = p;
1.489     rillig   2386:        }
                   2387:
1.490     rillig   2388:        *out_line = line;
1.493     rillig   2389:        curFile->buf_ptr = p;
1.489     rillig   2390:        *out_line_end = line_end;
1.492     rillig   2391:        *out_firstBackslash = firstBackslash;
                   2392:        *out_firstComment = firstComment;
1.493     rillig   2393:        return res;
1.489     rillig   2394: }
                   2395:
1.491     rillig   2396: /*
                   2397:  * Beginning at start, unescape '\#' to '#' and replace backslash-newline
                   2398:  * with a single space.
                   2399:  */
1.485     rillig   2400: static void
1.508     rillig   2401: UnescapeBackslash(char *line, char *start)
1.487     rillig   2402: {
1.491     rillig   2403:        char *src = start;
                   2404:        char *dst = start;
                   2405:        char *spaceStart = line;
1.485     rillig   2406:
                   2407:        for (;;) {
1.491     rillig   2408:                char ch = *src++;
1.485     rillig   2409:                if (ch != '\\') {
                   2410:                        if (ch == '\0')
                   2411:                                break;
1.491     rillig   2412:                        *dst++ = ch;
1.485     rillig   2413:                        continue;
                   2414:                }
                   2415:
1.491     rillig   2416:                ch = *src++;
1.485     rillig   2417:                if (ch == '\0') {
                   2418:                        /* Delete '\\' at end of buffer */
1.491     rillig   2419:                        dst--;
1.485     rillig   2420:                        break;
                   2421:                }
                   2422:
                   2423:                /* Delete '\\' from before '#' on non-command lines */
                   2424:                if (ch == '#' && line[0] != '\t') {
1.491     rillig   2425:                        *dst++ = ch;
1.485     rillig   2426:                        continue;
                   2427:                }
                   2428:
                   2429:                if (ch != '\n') {
                   2430:                        /* Leave '\\' in buffer for later */
1.491     rillig   2431:                        *dst++ = '\\';
1.485     rillig   2432:                        /*
                   2433:                         * Make sure we don't delete an escaped ' ' from the
                   2434:                         * line end.
                   2435:                         */
1.491     rillig   2436:                        spaceStart = dst + 1;
                   2437:                        *dst++ = ch;
1.485     rillig   2438:                        continue;
                   2439:                }
                   2440:
                   2441:                /*
                   2442:                 * Escaped '\n' -- replace following whitespace with a single
                   2443:                 * ' '.
                   2444:                 */
1.491     rillig   2445:                pp_skip_hspace(&src);
                   2446:                *dst++ = ' ';
1.485     rillig   2447:        }
                   2448:
1.487     rillig   2449:        /* Delete any trailing spaces - eg from empty continuations */
1.491     rillig   2450:        while (dst > spaceStart && ch_isspace(dst[-1]))
                   2451:                dst--;
                   2452:        *dst = '\0';
1.485     rillig   2453: }
                   2454:
1.593     rillig   2455: typedef enum LineKind {
1.495     rillig   2456:        /*
1.498     rillig   2457:         * Return the next line that is neither empty nor a comment.
1.495     rillig   2458:         * Backslash line continuations are folded into a single space.
                   2459:         * A trailing comment, if any, is discarded.
                   2460:         */
1.593     rillig   2461:        LK_NONEMPTY,
1.495     rillig   2462:
                   2463:        /*
1.498     rillig   2464:         * Return the next line, even if it is empty or a comment.
1.499     rillig   2465:         * Preserve backslash-newline to keep the line numbers correct.
1.495     rillig   2466:         *
                   2467:         * Used in .for loops to collect the body of the loop while waiting
                   2468:         * for the corresponding .endfor.
                   2469:         */
1.593     rillig   2470:        LK_FOR_BODY,
1.495     rillig   2471:
                   2472:        /*
1.499     rillig   2473:         * Return the next line that starts with a dot.
1.495     rillig   2474:         * Backslash line continuations are folded into a single space.
                   2475:         * A trailing comment, if any, is discarded.
                   2476:         *
                   2477:         * Used in .if directives to skip over irrelevant branches while
                   2478:         * waiting for the corresponding .endif.
                   2479:         */
1.593     rillig   2480:        LK_DOT
                   2481: } LineKind;
1.127     dsl      2482:
1.498     rillig   2483: /* Return the next "interesting" logical line from the current file. */
1.127     dsl      2484: static char *
1.593     rillig   2485: ReadLowLevelLine(LineKind kind)
1.5       cgd      2486: {
1.493     rillig   2487:        IFile *curFile = CurFile();
1.469     rillig   2488:        char *line;
                   2489:        char *line_end;
1.492     rillig   2490:        char *firstBackslash;
                   2491:        char *firstComment;
1.469     rillig   2492:
1.127     dsl      2493:        for (;;) {
1.493     rillig   2494:                ParseRawLineResult res = ParseRawLine(curFile,
                   2495:                    &line, &line_end, &firstBackslash, &firstComment);
                   2496:                if (res == PRLR_ERROR)
1.489     rillig   2497:                        return NULL;
1.27      christos 2498:
1.492     rillig   2499:                if (line_end == line || firstComment == line) {
1.493     rillig   2500:                        if (res == PRLR_EOF)
1.469     rillig   2501:                                return NULL;
1.593     rillig   2502:                        if (kind != LK_FOR_BODY)
1.494     rillig   2503:                                continue;
1.469     rillig   2504:                }
1.5       cgd      2505:
1.469     rillig   2506:                /* We now have a line of data */
1.514     rillig   2507:                assert(ch_isspace(*line_end));
1.469     rillig   2508:                *line_end = '\0';
1.5       cgd      2509:
1.593     rillig   2510:                if (kind == LK_FOR_BODY)
1.499     rillig   2511:                        return line;    /* Don't join the physical lines. */
1.5       cgd      2512:
1.593     rillig   2513:                if (kind == LK_DOT && line[0] != '.')
1.499     rillig   2514:                        continue;
1.127     dsl      2515:                break;
                   2516:        }
1.5       cgd      2517:
1.583     rillig   2518:        /* Ignore anything after a non-escaped '#' in non-commands. */
1.512     rillig   2519:        if (firstComment != NULL && line[0] != '\t')
                   2520:                *firstComment = '\0';
1.469     rillig   2521:
                   2522:        /* If we didn't see a '\\' then the in-situ data is fine. */
1.492     rillig   2523:        if (firstBackslash == NULL)
1.469     rillig   2524:                return line;
                   2525:
                   2526:        /* Remove escapes from '\n' and '#' */
1.492     rillig   2527:        UnescapeBackslash(line, firstBackslash);
1.27      christos 2528:
1.469     rillig   2529:        return line;
1.5       cgd      2530: }
1.1       cgd      2531:
1.553     rillig   2532: static bool
1.593     rillig   2533: SkipIrrelevantBranches(void)
1.501     rillig   2534: {
                   2535:        char *line;
                   2536:
1.593     rillig   2537:        while ((line = ReadLowLevelLine(LK_DOT)) != NULL) {
1.604     rillig   2538:                if (Cond_EvalLine(line) == CR_TRUE)
1.501     rillig   2539:                        break;
                   2540:                /*
                   2541:                 * TODO: Check for typos in .elif directives
                   2542:                 * such as .elsif or .elseif.
                   2543:                 *
                   2544:                 * This check will probably duplicate some of
                   2545:                 * the code in ParseLine.  Most of the code
                   2546:                 * there cannot apply, only ParseVarassign and
1.555     rillig   2547:                 * ParseDependencyLine can, and to prevent code
1.501     rillig   2548:                 * duplication, these would need to be called
                   2549:                 * with a flag called onlyCheckSyntax.
                   2550:                 *
                   2551:                 * See directive-elif.mk for details.
                   2552:                 */
                   2553:        }
                   2554:
                   2555:        return line != NULL;
                   2556: }
                   2557:
1.553     rillig   2558: static bool
1.500     rillig   2559: ParseForLoop(const char *line)
                   2560: {
                   2561:        int rval;
                   2562:        int firstLineno;
                   2563:
                   2564:        rval = For_Eval(line);
                   2565:        if (rval == 0)
1.553     rillig   2566:                return false;   /* Not a .for line */
1.500     rillig   2567:        if (rval < 0)
1.553     rillig   2568:                return true;    /* Syntax error - error printed, ignore line */
1.500     rillig   2569:
                   2570:        firstLineno = CurFile()->lineno;
                   2571:
1.616     rillig   2572:        /* Accumulate the loop body until the matching '.endfor'. */
1.500     rillig   2573:        do {
1.593     rillig   2574:                line = ReadLowLevelLine(LK_FOR_BODY);
1.500     rillig   2575:                if (line == NULL) {
                   2576:                        Parse_Error(PARSE_FATAL,
1.572     rillig   2577:                            "Unexpected end of file in .for loop");
1.500     rillig   2578:                        break;
                   2579:                }
                   2580:        } while (For_Accum(line));
                   2581:
1.616     rillig   2582:        For_Run(firstLineno);
                   2583:        return true;
1.500     rillig   2584: }
                   2585:
1.469     rillig   2586: /*
1.482     rillig   2587:  * Read an entire line from the input file.
                   2588:  *
                   2589:  * Empty lines, .if and .for are completely handled by this function,
                   2590:  * leaving only variable assignments, other directives, dependency lines
                   2591:  * and shell commands to the caller.
1.1       cgd      2592:  *
                   2593:  * Results:
1.482     rillig   2594:  *     A line without its newline and without any trailing whitespace,
                   2595:  *     or NULL.
1.1       cgd      2596:  */
                   2597: static char *
1.593     rillig   2598: ReadHighLevelLine(void)
1.1       cgd      2599: {
1.500     rillig   2600:        char *line;
1.469     rillig   2601:
                   2602:        for (;;) {
1.593     rillig   2603:                line = ReadLowLevelLine(LK_NONEMPTY);
1.469     rillig   2604:                if (line == NULL)
                   2605:                        return NULL;
                   2606:
                   2607:                if (line[0] != '.')
                   2608:                        return line;
                   2609:
                   2610:                switch (Cond_EvalLine(line)) {
1.604     rillig   2611:                case CR_FALSE:  /* May also mean a syntax error. */
1.593     rillig   2612:                        if (!SkipIrrelevantBranches())
1.482     rillig   2613:                                return NULL;
1.469     rillig   2614:                        continue;
1.604     rillig   2615:                case CR_TRUE:
1.469     rillig   2616:                        continue;
1.604     rillig   2617:                case CR_ERROR:  /* Not a conditional line */
1.500     rillig   2618:                        if (ParseForLoop(line))
1.469     rillig   2619:                                continue;
1.500     rillig   2620:                        break;
1.469     rillig   2621:                }
                   2622:                return line;
1.1       cgd      2623:        }
                   2624: }
                   2625:
1.331     rillig   2626: static void
1.329     rillig   2627: FinishDependencyGroup(void)
1.1       cgd      2628: {
1.469     rillig   2629:        GNodeListNode *ln;
1.430     rillig   2630:
1.469     rillig   2631:        if (targets == NULL)
                   2632:                return;
1.371     rillig   2633:
1.469     rillig   2634:        for (ln = targets->first; ln != NULL; ln = ln->next) {
                   2635:                GNode *gn = ln->datum;
1.371     rillig   2636:
1.469     rillig   2637:                Suff_EndTransform(gn);
1.371     rillig   2638:
1.469     rillig   2639:                /*
                   2640:                 * Mark the target as already having commands if it does, to
                   2641:                 * keep from having shell commands on multiple dependency
                   2642:                 * lines.
                   2643:                 */
                   2644:                if (!Lst_IsEmpty(&gn->commands))
                   2645:                        gn->type |= OP_HAS_COMMANDS;
                   2646:        }
1.430     rillig   2647:
1.469     rillig   2648:        Lst_Free(targets);
                   2649:        targets = NULL;
1.1       cgd      2650: }
1.27      christos 2651:
1.327     rillig   2652: /* Add the command to each target from the current dependency spec. */
1.326     rillig   2653: static void
1.375     rillig   2654: ParseLine_ShellCommand(const char *p)
1.326     rillig   2655: {
1.469     rillig   2656:        cpp_skip_whitespace(&p);
                   2657:        if (*p == '\0')
                   2658:                return;         /* skip empty commands */
1.327     rillig   2659:
1.469     rillig   2660:        if (targets == NULL) {
                   2661:                Parse_Error(PARSE_FATAL,
                   2662:                    "Unassociated shell command \"%s\"", p);
                   2663:                return;
                   2664:        }
1.327     rillig   2665:
1.469     rillig   2666:        {
                   2667:                char *cmd = bmake_strdup(p);
                   2668:                GNodeListNode *ln;
                   2669:
                   2670:                for (ln = targets->first; ln != NULL; ln = ln->next) {
                   2671:                        GNode *gn = ln->datum;
1.593     rillig   2672:                        GNode_AddCommand(gn, cmd);
1.469     rillig   2673:                }
1.326     rillig   2674: #ifdef CLEANUP
1.469     rillig   2675:                Lst_Append(&targCmds, cmd);
1.326     rillig   2676: #endif
1.469     rillig   2677:        }
1.326     rillig   2678: }
1.1       cgd      2679:
1.474     rillig   2680: /*
1.477     rillig   2681:  * See if the line starts with one of the known directives, and if so, handle
                   2682:  * the directive.
1.474     rillig   2683:  */
1.553     rillig   2684: static bool
1.379     rillig   2685: ParseDirective(char *line)
                   2686: {
1.474     rillig   2687:        char *cp = line + 1;
1.569     rillig   2688:        const char *arg;
                   2689:        Substring dir;
1.474     rillig   2690:
                   2691:        pp_skip_whitespace(&cp);
1.553     rillig   2692:        if (IsInclude(cp, false)) {
1.556     rillig   2693:                ParseInclude(cp);
1.553     rillig   2694:                return true;
1.474     rillig   2695:        }
1.379     rillig   2696:
1.569     rillig   2697:        dir.start = cp;
1.475     rillig   2698:        while (ch_isalpha(*cp) || *cp == '-')
                   2699:                cp++;
1.569     rillig   2700:        dir.end = cp;
1.475     rillig   2701:
                   2702:        if (*cp != '\0' && !ch_isspace(*cp))
1.553     rillig   2703:                return false;
1.475     rillig   2704:
                   2705:        pp_skip_whitespace(&cp);
                   2706:        arg = cp;
                   2707:
1.581     rillig   2708:        if (Substring_Equals(dir, "undef"))
1.569     rillig   2709:                Var_Undef(arg);
1.581     rillig   2710:        else if (Substring_Equals(dir, "export"))
1.517     rillig   2711:                Var_Export(VEM_PLAIN, arg);
1.581     rillig   2712:        else if (Substring_Equals(dir, "export-env"))
1.517     rillig   2713:                Var_Export(VEM_ENV, arg);
1.581     rillig   2714:        else if (Substring_Equals(dir, "export-literal"))
1.476     rillig   2715:                Var_Export(VEM_LITERAL, arg);
1.581     rillig   2716:        else if (Substring_Equals(dir, "unexport"))
1.553     rillig   2717:                Var_UnExport(false, arg);
1.581     rillig   2718:        else if (Substring_Equals(dir, "unexport-env"))
1.553     rillig   2719:                Var_UnExport(true, arg);
1.581     rillig   2720:        else if (Substring_Equals(dir, "info"))
1.602     rillig   2721:                HandleMessage(PARSE_INFO, "info", arg);
1.581     rillig   2722:        else if (Substring_Equals(dir, "warning"))
1.602     rillig   2723:                HandleMessage(PARSE_WARNING, "warning", arg);
1.581     rillig   2724:        else if (Substring_Equals(dir, "error"))
1.602     rillig   2725:                HandleMessage(PARSE_FATAL, "error", arg);
1.581     rillig   2726:        else
                   2727:                return false;
                   2728:        return true;
1.379     rillig   2729: }
                   2730:
1.605     rillig   2731: bool
                   2732: Parse_VarAssign(const char *line, bool finishDependencyGroup, GNode *scope)
1.379     rillig   2733: {
1.469     rillig   2734:        VarAssign var;
1.430     rillig   2735:
1.469     rillig   2736:        if (!Parse_IsVar(line, &var))
1.553     rillig   2737:                return false;
1.605     rillig   2738:        if (finishDependencyGroup)
                   2739:                FinishDependencyGroup();
                   2740:        Parse_Var(&var, scope);
1.553     rillig   2741:        return true;
1.379     rillig   2742: }
                   2743:
1.380     rillig   2744: static char *
                   2745: FindSemicolon(char *p)
                   2746: {
1.469     rillig   2747:        int level = 0;
                   2748:
                   2749:        for (; *p != '\0'; p++) {
                   2750:                if (*p == '\\' && p[1] != '\0') {
                   2751:                        p++;
                   2752:                        continue;
                   2753:                }
1.380     rillig   2754:
1.469     rillig   2755:                if (*p == '$' && (p[1] == '(' || p[1] == '{'))
                   2756:                        level++;
                   2757:                else if (level > 0 && (*p == ')' || *p == '}'))
                   2758:                        level--;
                   2759:                else if (level == 0 && *p == ';')
                   2760:                        break;
                   2761:        }
                   2762:        return p;
1.380     rillig   2763: }
                   2764:
1.524     rillig   2765: /*
1.557     rillig   2766:  * dependency  -> target... op [source...] [';' command]
1.524     rillig   2767:  * op          -> ':' | '::' | '!'
                   2768:  */
1.379     rillig   2769: static void
1.555     rillig   2770: ParseDependencyLine(char *line)
1.379     rillig   2771: {
1.557     rillig   2772:        VarEvalMode emode;
1.469     rillig   2773:        char *expanded_line;
                   2774:        const char *shellcmd = NULL;
                   2775:
                   2776:        /*
                   2777:         * For some reason - probably to make the parser impossible -
                   2778:         * a ';' can be used to separate commands from dependencies.
                   2779:         * Attempt to avoid ';' inside substitution patterns.
                   2780:         */
                   2781:        {
                   2782:                char *semicolon = FindSemicolon(line);
                   2783:                if (*semicolon != '\0') {
                   2784:                        /* Terminate the dependency list at the ';' */
                   2785:                        *semicolon = '\0';
                   2786:                        shellcmd = semicolon + 1;
                   2787:                }
                   2788:        }
1.379     rillig   2789:
1.469     rillig   2790:        /*
                   2791:         * We now know it's a dependency line so it needs to have all
                   2792:         * variables expanded before being parsed.
                   2793:         *
                   2794:         * XXX: Ideally the dependency line would first be split into
                   2795:         * its left-hand side, dependency operator and right-hand side,
                   2796:         * and then each side would be expanded on its own.  This would
                   2797:         * allow for the left-hand side to allow only defined variables
                   2798:         * and to allow variables on the right-hand side to be undefined
                   2799:         * as well.
                   2800:         *
                   2801:         * Parsing the line first would also prevent that targets
                   2802:         * generated from variable expressions are interpreted as the
                   2803:         * dependency operator, such as in "target${:U\:} middle: source",
                   2804:         * in which the middle is interpreted as a source, not a target.
                   2805:         */
                   2806:
1.583     rillig   2807:        /*
                   2808:         * In lint mode, allow undefined variables to appear in dependency
                   2809:         * lines.
1.469     rillig   2810:         *
1.583     rillig   2811:         * Ideally, only the right-hand side would allow undefined variables
                   2812:         * since it is common to have optional dependencies. Having undefined
                   2813:         * variables on the left-hand side is more unusual though.  Since
                   2814:         * both sides are expanded in a single pass, there is not much choice
                   2815:         * what to do here.
1.469     rillig   2816:         *
1.583     rillig   2817:         * In normal mode, it does not matter whether undefined variables are
                   2818:         * allowed or not since as of 2020-09-14, Var_Parse does not print
                   2819:         * any parse errors in such a case. It simply returns the special
                   2820:         * empty string var_Error, which cannot be detected in the result of
                   2821:         * Var_Subst.
                   2822:         */
1.557     rillig   2823:        emode = opts.strict ? VARE_WANTRES : VARE_UNDEFERR;
                   2824:        (void)Var_Subst(line, SCOPE_CMDLINE, emode, &expanded_line);
1.469     rillig   2825:        /* TODO: handle errors */
                   2826:
                   2827:        /* Need a fresh list for the target nodes */
                   2828:        if (targets != NULL)
                   2829:                Lst_Free(targets);
                   2830:        targets = Lst_New();
1.379     rillig   2831:
1.556     rillig   2832:        ParseDependency(expanded_line);
1.469     rillig   2833:        free(expanded_line);
1.380     rillig   2834:
1.469     rillig   2835:        if (shellcmd != NULL)
                   2836:                ParseLine_ShellCommand(shellcmd);
1.379     rillig   2837: }
                   2838:
1.381     rillig   2839: static void
                   2840: ParseLine(char *line)
                   2841: {
1.477     rillig   2842:        /*
                   2843:         * Lines that begin with '.' can be pretty much anything:
                   2844:         *      - directives like '.include' or '.if',
                   2845:         *      - suffix rules like '.c.o:',
                   2846:         *      - dependencies for filenames that start with '.',
                   2847:         *      - variable assignments like '.tmp=value'.
                   2848:         */
1.474     rillig   2849:        if (line[0] == '.' && ParseDirective(line))
1.469     rillig   2850:                return;
1.381     rillig   2851:
1.478     rillig   2852:        if (line[0] == '\t') {
1.469     rillig   2853:                ParseLine_ShellCommand(line + 1);
                   2854:                return;
                   2855:        }
1.381     rillig   2856:
                   2857: #ifdef SYSVINCLUDE
1.469     rillig   2858:        if (IsSysVInclude(line)) {
                   2859:                /*
                   2860:                 * It's an S3/S5-style "include".
                   2861:                 */
                   2862:                ParseTraditionalInclude(line);
                   2863:                return;
                   2864:        }
1.381     rillig   2865: #endif
                   2866:
                   2867: #ifdef GMAKEEXPORT
1.469     rillig   2868:        if (strncmp(line, "export", 6) == 0 && ch_isspace(line[6]) &&
                   2869:            strchr(line, ':') == NULL) {
                   2870:                /*
                   2871:                 * It's a Gmake "export".
                   2872:                 */
                   2873:                ParseGmakeExport(line);
                   2874:                return;
                   2875:        }
1.381     rillig   2876: #endif
                   2877:
1.605     rillig   2878:        if (Parse_VarAssign(line, true, SCOPE_GLOBAL))
1.469     rillig   2879:                return;
1.381     rillig   2880:
1.469     rillig   2881:        FinishDependencyGroup();
1.381     rillig   2882:
1.555     rillig   2883:        ParseDependencyLine(line);
1.381     rillig   2884: }
                   2885:
1.469     rillig   2886: /*
                   2887:  * Parse a top-level makefile, incorporating its content into the global
1.441     rillig   2888:  * dependency graph.
1.1       cgd      2889:  */
                   2890: void
1.125     dsl      2891: Parse_File(const char *name, int fd)
1.1       cgd      2892: {
1.613     rillig   2893:        char *line;
1.616     rillig   2894:        Buffer buf;
1.170     dholland 2895:
1.616     rillig   2896:        buf = loadfile(name, fd != -1 ? fd : STDIN_FILENO);
1.613     rillig   2897:        if (fd != -1)
                   2898:                (void)close(fd);
1.1       cgd      2899:
1.469     rillig   2900:        assert(targets == NULL);
1.44      aidan    2901:
1.616     rillig   2902:        Parse_PushInput(name, 0, buf, NULL);
1.1       cgd      2903:
1.469     rillig   2904:        do {
1.593     rillig   2905:                while ((line = ReadHighLevelLine()) != NULL) {
1.591     rillig   2906:                        DEBUG2(PARSE, "Parsing line %d: %s\n",
1.469     rillig   2907:                            CurFile()->lineno, line);
                   2908:                        ParseLine(line);
                   2909:                }
                   2910:                /* Reached EOF, but it may be just EOF of an include file. */
                   2911:        } while (ParseEOF());
1.1       cgd      2912:
1.469     rillig   2913:        FinishDependencyGroup();
1.328     rillig   2914:
1.561     rillig   2915:        if (parseErrors != 0) {
1.469     rillig   2916:                (void)fflush(stdout);
                   2917:                (void)fprintf(stderr,
                   2918:                    "%s: Fatal errors encountered -- cannot continue",
                   2919:                    progname);
                   2920:                PrintOnError(NULL, NULL);
                   2921:                exit(1);
                   2922:        }
1.1       cgd      2923: }
                   2924:
1.383     rillig   2925: /* Initialize the parsing module. */
1.5       cgd      2926: void
1.84      wiz      2927: Parse_Init(void)
1.1       cgd      2928: {
1.469     rillig   2929:        mainNode = NULL;
                   2930:        parseIncPath = SearchPath_New();
                   2931:        sysIncPath = SearchPath_New();
                   2932:        defSysIncPath = SearchPath_New();
                   2933:        Vector_Init(&includes, sizeof(IFile));
1.1       cgd      2934: }
1.9       jtc      2935:
1.383     rillig   2936: /* Clean up the parsing module. */
1.9       jtc      2937: void
1.84      wiz      2938: Parse_End(void)
1.9       jtc      2939: {
1.45      mycroft  2940: #ifdef CLEANUP
1.469     rillig   2941:        Lst_DoneCall(&targCmds, free);
                   2942:        assert(targets == NULL);
                   2943:        SearchPath_Free(defSysIncPath);
                   2944:        SearchPath_Free(sysIncPath);
                   2945:        SearchPath_Free(parseIncPath);
                   2946:        assert(includes.len == 0);
                   2947:        Vector_Done(&includes);
1.45      mycroft  2948: #endif
1.9       jtc      2949: }
1.27      christos 2950:
1.1       cgd      2951:
1.441     rillig   2952: /*
                   2953:  * Return a list containing the single main target to create.
                   2954:  * If no such target exists, we Punt with an obnoxious error message.
1.1       cgd      2955:  */
1.461     rillig   2956: void
                   2957: Parse_MainName(GNodeList *mainList)
1.1       cgd      2958: {
1.469     rillig   2959:        if (mainNode == NULL)
                   2960:                Punt("no target to make.");
1.430     rillig   2961:
1.527     rillig   2962:        Lst_Append(mainList, mainNode);
                   2963:        if (mainNode->type & OP_DOUBLEDEP)
1.469     rillig   2964:                Lst_AppendAll(mainList, &mainNode->cohorts);
1.441     rillig   2965:
1.542     rillig   2966:        Global_Append(".TARGETS", mainNode->name);
1.59      christos 2967: }
1.420     rillig   2968:
                   2969: int
1.561     rillig   2970: Parse_NumErrors(void)
1.420     rillig   2971: {
1.561     rillig   2972:        return parseErrors;
1.420     rillig   2973: }

CVSweb <webmaster@jp.NetBSD.org>