[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.507

1.507   ! rillig      1: /*     $NetBSD: parse.c,v 1.506 2020/12/20 14:48:35 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:  *
1.402     rillig     77:  * The directories for the .include "..." directive are kept in
                     78:  * 'parseIncPath', while those for .include <...> are kept in 'sysIncPath'.
                     79:  * The targets currently being defined are kept in 'targets'.
1.1       cgd        80:  *
                     81:  * Interface:
1.402     rillig     82:  *     Parse_Init      Initialize the module
1.338     rillig     83:  *
1.383     rillig     84:  *     Parse_End       Clean up the module
1.338     rillig     85:  *
1.402     rillig     86:  *     Parse_File      Parse a top-level makefile.  Included files are
                     87:  *                     handled by Parse_include_file though.
                     88:  *
                     89:  *     Parse_IsVar     Return TRUE if the given line is a variable
                     90:  *                     assignment. Used by MainParseArgs to determine if
                     91:  *                     an argument is a target or a variable assignment.
                     92:  *                     Used internally for pretty much the same thing.
                     93:  *
                     94:  *     Parse_Error     Report a parse error, a warning or an informational
                     95:  *                     message.
1.338     rillig     96:  *
1.402     rillig     97:  *     Parse_MainName  Returns a list of the main target to create.
1.1       cgd        98:  */
                     99:
1.170     dholland  100: #include <sys/types.h>
                    101: #include <sys/mman.h>
1.171     dholland  102: #include <sys/stat.h>
1.84      wiz       103: #include <errno.h>
1.5       cgd       104: #include <stdarg.h>
1.225     maya      105: #include <stdint.h>
1.84      wiz       106:
1.177     nakayama  107: #ifndef MAP_FILE
                    108: #define MAP_FILE 0
                    109: #endif
1.170     dholland  110: #ifndef MAP_COPY
                    111: #define MAP_COPY MAP_PRIVATE
                    112: #endif
                    113:
1.1       cgd       114: #include "make.h"
1.5       cgd       115: #include "dir.h"
                    116: #include "job.h"
1.1       cgd       117: #include "pathnames.h"
                    118:
1.303     rillig    119: /*     "@(#)parse.c    8.3 (Berkeley) 3/19/94" */
1.507   ! rillig    120: MAKE_RCSID("$NetBSD: parse.c,v 1.506 2020/12/20 14:48:35 rillig Exp $");
1.303     rillig    121:
1.248     rillig    122: /* types and constants */
1.166     dholland  123:
1.1       cgd       124: /*
1.166     dholland  125:  * Structure for a file being read ("included file")
1.1       cgd       126:  */
                    127: typedef struct IFile {
1.469     rillig    128:        char *fname;            /* name of file (relative? absolute?) */
                    129:        Boolean fromForLoop;    /* simulated .include by the .for loop */
                    130:        int lineno;             /* current line number in file */
                    131:        int first_lineno;       /* line number of start of text */
                    132:        unsigned int cond_depth; /* 'if' nesting when file opened */
                    133:        Boolean depending;      /* state of doing_depend on EOF */
                    134:
                    135:        /* The buffer from which the file's content is read. */
                    136:        char *buf_freeIt;
                    137:        char *buf_ptr;          /* next char to be read */
                    138:        char *buf_end;
                    139:
1.471     rillig    140:        /* Function to read more data, with a single opaque argument. */
                    141:        ReadMoreProc readMore;
                    142:        void *readMoreArg;
                    143:
1.469     rillig    144:        struct loadedfile *lf;  /* loadedfile object, if any */
1.5       cgd       145: } IFile;
1.1       cgd       146:
1.166     dholland  147: /*
                    148:  * Tokens for target attributes
1.1       cgd       149:  */
1.386     rillig    150: typedef enum ParseSpecial {
1.469     rillig    151:        SP_ATTRIBUTE,   /* Generic attribute */
                    152:        SP_BEGIN,       /* .BEGIN */
                    153:        SP_DEFAULT,     /* .DEFAULT */
                    154:        SP_DELETE_ON_ERROR, /* .DELETE_ON_ERROR */
                    155:        SP_END,         /* .END */
                    156:        SP_ERROR,       /* .ERROR */
                    157:        SP_IGNORE,      /* .IGNORE */
                    158:        SP_INCLUDES,    /* .INCLUDES; not mentioned in the manual page */
                    159:        SP_INTERRUPT,   /* .INTERRUPT */
                    160:        SP_LIBS,        /* .LIBS; not mentioned in the manual page */
                    161:        /* .MAIN and we don't have anything user-specified to make */
                    162:        SP_MAIN,
                    163:        SP_META,        /* .META */
                    164:        SP_MFLAGS,      /* .MFLAGS or .MAKEFLAGS */
                    165:        SP_NOMETA,      /* .NOMETA */
                    166:        SP_NOMETA_CMP,  /* .NOMETA_CMP */
                    167:        SP_NOPATH,      /* .NOPATH */
                    168:        SP_NOT,         /* Not special */
                    169:        SP_NOTPARALLEL, /* .NOTPARALLEL or .NO_PARALLEL */
                    170:        SP_NULL,        /* .NULL; not mentioned in the manual page */
                    171:        SP_OBJDIR,      /* .OBJDIR */
                    172:        SP_ORDER,       /* .ORDER */
                    173:        SP_PARALLEL,    /* .PARALLEL; not mentioned in the manual page */
                    174:        SP_PATH,        /* .PATH or .PATH.suffix */
                    175:        SP_PHONY,       /* .PHONY */
1.48      sjg       176: #ifdef POSIX
1.469     rillig    177:        SP_POSIX,       /* .POSIX; not mentioned in the manual page */
1.48      sjg       178: #endif
1.469     rillig    179:        SP_PRECIOUS,    /* .PRECIOUS */
                    180:        SP_SHELL,       /* .SHELL */
                    181:        SP_SILENT,      /* .SILENT */
                    182:        SP_SINGLESHELL, /* .SINGLESHELL; not mentioned in the manual page */
                    183:        SP_STALE,       /* .STALE */
                    184:        SP_SUFFIXES,    /* .SUFFIXES */
                    185:        SP_WAIT         /* .WAIT */
1.1       cgd       186: } ParseSpecial;
                    187:
1.368     rillig    188: typedef List SearchPathList;
1.392     rillig    189: typedef ListNode SearchPathListNode;
1.368     rillig    190:
1.248     rillig    191: /* result data */
1.166     dholland  192:
                    193: /*
                    194:  * The main target to create. This is the first target on the first
                    195:  * dependency line in the first makefile.
                    196:  */
                    197: static GNode *mainNode;
                    198:
1.248     rillig    199: /* eval state */
1.166     dholland  200:
1.415     rillig    201: /* During parsing, the targets from the left-hand side of the currently
                    202:  * active dependency line, or NULL if the current line does not belong to a
                    203:  * dependency line, for example because it is a variable assignment.
1.318     rillig    204:  *
                    205:  * See unit-tests/deptgt.mk, keyword "parse.c:targets". */
1.322     rillig    206: static GNodeList *targets;
1.166     dholland  207:
                    208: #ifdef CLEANUP
1.372     rillig    209: /* All shell commands for all targets, in no particular order and possibly
                    210:  * with duplicates.  Kept in a separate list since the commands from .USE or
                    211:  * .USEBEFORE nodes are shared with other GNodes, thereby giving up the
                    212:  * easily understandable ownership over the allocated strings. */
1.461     rillig    213: static StringList targCmds = LST_INIT;
1.166     dholland  214: #endif
                    215:
                    216: /*
1.152     dsl       217:  * Predecessor node for handling .ORDER. Initialized to NULL when .ORDER
1.1       cgd       218:  * seen, then set to each successive source on the line.
                    219:  */
1.407     rillig    220: static GNode *order_pred;
1.1       cgd       221:
1.248     rillig    222: /* parser state */
1.166     dholland  223:
                    224: /* number of fatal errors */
                    225: static int fatals = 0;
                    226:
                    227: /*
                    228:  * Variables for doing includes
                    229:  */
                    230:
1.408     rillig    231: /* The include chain of makefiles.  At the bottom is the top-level makefile
                    232:  * from the command line, and on top of that, there are the included files or
                    233:  * .for loops, up to and including the current file.
1.319     rillig    234:  *
                    235:  * This data could be used to print stack traces on parse errors.  As of
                    236:  * 2020-09-14, this is not done though.  It seems quite simple to print the
                    237:  * tuples (fname:lineno:fromForLoop), from top to bottom.  This simple idea is
                    238:  * made complicated by the fact that the .for loops also use this stack for
                    239:  * storing information.
                    240:  *
                    241:  * The lineno fields of the IFiles with fromForLoop == TRUE look confusing,
                    242:  * which is demonstrated by the test 'include-main.mk'.  They seem sorted
                    243:  * backwards since they tell the number of completely parsed lines, which for
                    244:  * a .for loop is right after the terminating .endfor.  To compensate for this
                    245:  * confusion, there is another field first_lineno pointing at the start of the
                    246:  * .for loop, 1-based for human consumption.
                    247:  *
                    248:  * To make the stack trace intuitive, the entry below the first .for loop must
                    249:  * be ignored completely since neither its lineno nor its first_lineno is
1.408     rillig    250:  * useful.  Instead, the topmost of each chain of .for loop needs to be
                    251:  * printed twice, once with its first_lineno and once with its lineno.
1.319     rillig    252:  *
1.408     rillig    253:  * As of 2020-10-28, using the above rules, the stack trace for the .info line
1.319     rillig    254:  * in include-subsub.mk would be:
                    255:  *
1.408     rillig    256:  *     includes[5]:    include-subsub.mk:4
1.319     rillig    257:  *                     (lineno, from an .include)
                    258:  *     includes[4]:    include-sub.mk:32
                    259:  *                     (lineno, from a .for loop below an .include)
                    260:  *     includes[4]:    include-sub.mk:31
                    261:  *                     (first_lineno, from a .for loop, lineno == 32)
                    262:  *     includes[3]:    include-sub.mk:30
                    263:  *                     (first_lineno, from a .for loop, lineno == 33)
                    264:  *     includes[2]:    include-sub.mk:29
                    265:  *                     (first_lineno, from a .for loop, lineno == 34)
                    266:  *     includes[1]:    include-sub.mk:35
                    267:  *                     (not printed since it is below a .for loop)
                    268:  *     includes[0]:    include-main.mk:27
                    269:  */
1.408     rillig    270: static Vector /* of IFile */ includes;
1.400     rillig    271:
                    272: static IFile *
                    273: GetInclude(size_t i)
                    274: {
1.469     rillig    275:        return Vector_Get(&includes, i);
1.408     rillig    276: }
                    277:
                    278: /* The file that is currently being read. */
                    279: static IFile *
                    280: CurFile(void)
                    281: {
1.469     rillig    282:        return GetInclude(includes.len - 1);
1.400     rillig    283: }
1.166     dholland  284:
1.409     rillig    285: /* include paths */
1.322     rillig    286: SearchPath *parseIncPath;      /* dirs for "..." includes */
                    287: SearchPath *sysIncPath;                /* dirs for <...> includes */
1.414     rillig    288: SearchPath *defSysIncPath;     /* default for sysIncPath */
1.166     dholland  289:
1.248     rillig    290: /* parser tables */
1.166     dholland  291:
1.1       cgd       292: /*
                    293:  * The parseKeywords table is searched using binary search when deciding
                    294:  * if a target or source is special. The 'spec' field is the ParseSpecial
1.404     rillig    295:  * type of the keyword (SP_NOT if the keyword isn't special as a target) while
1.1       cgd       296:  * the 'op' field is the operator to apply to the list of targets if the
                    297:  * keyword is used as a source ("0" if the keyword isn't special as a source)
                    298:  */
1.168     dholland  299: static const struct {
1.469     rillig    300:        const char *name;       /* Name of keyword */
                    301:        ParseSpecial spec;      /* Type when used as a target */
                    302:        GNodeType op;           /* Operator when used as a source */
1.1       cgd       303: } parseKeywords[] = {
1.466     rillig    304:     { ".BEGIN",                SP_BEGIN,       OP_NONE },
                    305:     { ".DEFAULT",      SP_DEFAULT,     OP_NONE },
                    306:     { ".DELETE_ON_ERROR", SP_DELETE_ON_ERROR, OP_NONE },
                    307:     { ".END",          SP_END,         OP_NONE },
                    308:     { ".ERROR",                SP_ERROR,       OP_NONE },
1.404     rillig    309:     { ".EXEC",         SP_ATTRIBUTE,   OP_EXEC },
                    310:     { ".IGNORE",       SP_IGNORE,      OP_IGNORE },
1.466     rillig    311:     { ".INCLUDES",     SP_INCLUDES,    OP_NONE },
                    312:     { ".INTERRUPT",    SP_INTERRUPT,   OP_NONE },
1.404     rillig    313:     { ".INVISIBLE",    SP_ATTRIBUTE,   OP_INVISIBLE },
                    314:     { ".JOIN",         SP_ATTRIBUTE,   OP_JOIN },
1.466     rillig    315:     { ".LIBS",         SP_LIBS,        OP_NONE },
1.404     rillig    316:     { ".MADE",         SP_ATTRIBUTE,   OP_MADE },
1.466     rillig    317:     { ".MAIN",         SP_MAIN,        OP_NONE },
1.404     rillig    318:     { ".MAKE",         SP_ATTRIBUTE,   OP_MAKE },
1.466     rillig    319:     { ".MAKEFLAGS",    SP_MFLAGS,      OP_NONE },
1.404     rillig    320:     { ".META",         SP_META,        OP_META },
1.466     rillig    321:     { ".MFLAGS",       SP_MFLAGS,      OP_NONE },
1.404     rillig    322:     { ".NOMETA",       SP_NOMETA,      OP_NOMETA },
                    323:     { ".NOMETA_CMP",   SP_NOMETA_CMP,  OP_NOMETA_CMP },
                    324:     { ".NOPATH",       SP_NOPATH,      OP_NOPATH },
                    325:     { ".NOTMAIN",      SP_ATTRIBUTE,   OP_NOTMAIN },
1.466     rillig    326:     { ".NOTPARALLEL",  SP_NOTPARALLEL, OP_NONE },
                    327:     { ".NO_PARALLEL",  SP_NOTPARALLEL, OP_NONE },
                    328:     { ".NULL",         SP_NULL,        OP_NONE },
                    329:     { ".OBJDIR",       SP_OBJDIR,      OP_NONE },
1.404     rillig    330:     { ".OPTIONAL",     SP_ATTRIBUTE,   OP_OPTIONAL },
1.466     rillig    331:     { ".ORDER",                SP_ORDER,       OP_NONE },
                    332:     { ".PARALLEL",     SP_PARALLEL,    OP_NONE },
                    333:     { ".PATH",         SP_PATH,        OP_NONE },
1.404     rillig    334:     { ".PHONY",                SP_PHONY,       OP_PHONY },
1.48      sjg       335: #ifdef POSIX
1.466     rillig    336:     { ".POSIX",                SP_POSIX,       OP_NONE },
1.48      sjg       337: #endif
1.404     rillig    338:     { ".PRECIOUS",     SP_PRECIOUS,    OP_PRECIOUS },
                    339:     { ".RECURSIVE",    SP_ATTRIBUTE,   OP_MAKE },
1.466     rillig    340:     { ".SHELL",                SP_SHELL,       OP_NONE },
1.404     rillig    341:     { ".SILENT",       SP_SILENT,      OP_SILENT },
1.466     rillig    342:     { ".SINGLESHELL",  SP_SINGLESHELL, OP_NONE },
                    343:     { ".STALE",                SP_STALE,       OP_NONE },
                    344:     { ".SUFFIXES",     SP_SUFFIXES,    OP_NONE },
1.404     rillig    345:     { ".USE",          SP_ATTRIBUTE,   OP_USE },
                    346:     { ".USEBEFORE",    SP_ATTRIBUTE,   OP_USEBEFORE },
1.466     rillig    347:     { ".WAIT",         SP_WAIT,        OP_NONE },
1.1       cgd       348: };
                    349:
1.248     rillig    350: /* file loader */
1.170     dholland  351:
                    352: struct loadedfile {
1.441     rillig    353:        /* XXX: What is the lifetime of this path? Who manages the memory? */
1.469     rillig    354:        const char *path;       /* name, for error reports */
                    355:        char *buf;              /* contents buffer */
                    356:        size_t len;             /* length of contents */
                    357:        size_t maplen;          /* length of mmap area, or 0 */
                    358:        Boolean used;           /* XXX: have we used the data yet */
1.170     dholland  359: };
                    360:
1.441     rillig    361: /* XXX: What is the lifetime of the path? Who manages the memory? */
1.170     dholland  362: static struct loadedfile *
                    363: loadedfile_create(const char *path)
                    364: {
                    365:        struct loadedfile *lf;
                    366:
1.427     rillig    367:        lf = bmake_malloc(sizeof *lf);
1.242     rillig    368:        lf->path = path == NULL ? "(stdin)" : path;
1.170     dholland  369:        lf->buf = NULL;
                    370:        lf->len = 0;
                    371:        lf->maplen = 0;
                    372:        lf->used = FALSE;
                    373:        return lf;
                    374: }
                    375:
                    376: static void
                    377: loadedfile_destroy(struct loadedfile *lf)
                    378: {
                    379:        if (lf->buf != NULL) {
1.430     rillig    380:                if (lf->maplen > 0)
1.170     dholland  381:                        munmap(lf->buf, lf->maplen);
1.430     rillig    382:                else
1.170     dholland  383:                        free(lf->buf);
                    384:        }
                    385:        free(lf);
                    386: }
                    387:
                    388: /*
1.471     rillig    389:  * readMore() operation for loadedfile, as needed by the weird and twisted
                    390:  * logic below. Once that's cleaned up, we can get rid of lf->used.
1.170     dholland  391:  */
                    392: static char *
1.471     rillig    393: loadedfile_readMore(void *x, size_t *len)
1.170     dholland  394: {
                    395:        struct loadedfile *lf = x;
                    396:
1.430     rillig    397:        if (lf->used)
1.170     dholland  398:                return NULL;
1.430     rillig    399:
1.170     dholland  400:        lf->used = TRUE;
                    401:        *len = lf->len;
                    402:        return lf->buf;
                    403: }
                    404:
                    405: /*
                    406:  * Try to get the size of a file.
                    407:  */
1.272     rillig    408: static Boolean
1.170     dholland  409: load_getsize(int fd, size_t *ret)
                    410: {
                    411:        struct stat st;
                    412:
1.430     rillig    413:        if (fstat(fd, &st) < 0)
1.272     rillig    414:                return FALSE;
1.170     dholland  415:
1.430     rillig    416:        if (!S_ISREG(st.st_mode))
1.272     rillig    417:                return FALSE;
1.170     dholland  418:
                    419:        /*
                    420:         * st_size is an off_t, which is 64 bits signed; *ret is
                    421:         * size_t, which might be 32 bits unsigned or 64 bits
                    422:         * unsigned. Rather than being elaborate, just punt on
                    423:         * files that are more than 2^31 bytes. We should never
                    424:         * see a makefile that size in practice...
                    425:         *
                    426:         * While we're at it reject negative sizes too, just in case.
                    427:         */
1.430     rillig    428:        if (st.st_size < 0 || st.st_size > 0x7fffffff)
1.272     rillig    429:                return FALSE;
1.170     dholland  430:
1.396     rillig    431:        *ret = (size_t)st.st_size;
1.272     rillig    432:        return TRUE;
1.170     dholland  433: }
                    434:
1.414     rillig    435: static Boolean
                    436: loadedfile_mmap(struct loadedfile *lf, int fd)
1.170     dholland  437: {
1.369     rillig    438:        static unsigned long pagesize = 0;
1.170     dholland  439:
1.430     rillig    440:        if (!load_getsize(fd, &lf->len))
                    441:                return FALSE;
                    442:
                    443:        /* found a size, try mmap */
                    444:        if (pagesize == 0)
                    445:                pagesize = (unsigned long)sysconf(_SC_PAGESIZE);
                    446:        if (pagesize == 0 || pagesize == (unsigned long)-1)
                    447:                pagesize = 0x1000;
                    448:
                    449:        /* round size up to a page */
                    450:        lf->maplen = pagesize * ((lf->len + pagesize - 1) / pagesize);
1.170     dholland  451:
1.430     rillig    452:        /*
                    453:         * XXX hack for dealing with empty files; remove when
                    454:         * we're no longer limited by interfacing to the old
                    455:         * logic elsewhere in this file.
                    456:         */
                    457:        if (lf->maplen == 0)
                    458:                lf->maplen = pagesize;
1.170     dholland  459:
1.430     rillig    460:        /*
                    461:         * FUTURE: remove PROT_WRITE when the parser no longer
                    462:         * needs to scribble on the input.
                    463:         */
1.469     rillig    464:        lf->buf = mmap(NULL, lf->maplen, PROT_READ | PROT_WRITE,
                    465:            MAP_FILE | MAP_COPY, fd, 0);
1.430     rillig    466:        if (lf->buf == MAP_FAILED)
                    467:                return FALSE;
1.170     dholland  468:
1.430     rillig    469:        if (lf->len == lf->maplen && lf->buf[lf->len - 1] != '\n') {
                    470:                char *b = bmake_malloc(lf->len + 1);
                    471:                b[lf->len] = '\n';
                    472:                memcpy(b, lf->buf, lf->len++);
                    473:                munmap(lf->buf, lf->maplen);
                    474:                lf->maplen = 0;
                    475:                lf->buf = b;
1.170     dholland  476:        }
1.430     rillig    477:
                    478:        return TRUE;
1.414     rillig    479: }
                    480:
                    481: /*
                    482:  * Read in a file.
                    483:  *
                    484:  * Until the path search logic can be moved under here instead of
                    485:  * being in the caller in another source file, we need to have the fd
                    486:  * passed in already open. Bleh.
                    487:  *
1.430     rillig    488:  * If the path is NULL, use stdin.
1.414     rillig    489:  */
                    490: static struct loadedfile *
                    491: loadfile(const char *path, int fd)
                    492: {
                    493:        struct loadedfile *lf;
                    494:        ssize_t result;
                    495:        size_t bufpos;
                    496:
                    497:        lf = loadedfile_create(path);
                    498:
                    499:        if (path == NULL) {
                    500:                assert(fd == -1);
                    501:                fd = STDIN_FILENO;
                    502:        } else {
                    503: #if 0 /* notyet */
                    504:                fd = open(path, O_RDONLY);
                    505:                if (fd < 0) {
                    506:                        ...
                    507:                        Error("%s: %s", path, strerror(errno));
                    508:                        exit(1);
                    509:                }
                    510: #endif
                    511:        }
                    512:
                    513:        if (loadedfile_mmap(lf, fd))
                    514:                goto done;
1.170     dholland  515:
                    516:        /* cannot mmap; load the traditional way */
                    517:
                    518:        lf->maplen = 0;
                    519:        lf->len = 1024;
                    520:        lf->buf = bmake_malloc(lf->len);
                    521:
                    522:        bufpos = 0;
1.428     rillig    523:        for (;;) {
1.170     dholland  524:                assert(bufpos <= lf->len);
                    525:                if (bufpos == lf->len) {
1.469     rillig    526:                        if (lf->len > SIZE_MAX / 2) {
1.221     riastrad  527:                                errno = EFBIG;
                    528:                                Error("%s: file too large", path);
                    529:                                exit(1);
                    530:                        }
1.170     dholland  531:                        lf->len *= 2;
                    532:                        lf->buf = bmake_realloc(lf->buf, lf->len);
                    533:                }
1.221     riastrad  534:                assert(bufpos < lf->len);
1.170     dholland  535:                result = read(fd, lf->buf + bufpos, lf->len - bufpos);
                    536:                if (result < 0) {
                    537:                        Error("%s: read error: %s", path, strerror(errno));
                    538:                        exit(1);
                    539:                }
1.430     rillig    540:                if (result == 0)
1.170     dholland  541:                        break;
1.430     rillig    542:
1.369     rillig    543:                bufpos += (size_t)result;
1.170     dholland  544:        }
                    545:        assert(bufpos <= lf->len);
1.173     dholland  546:        lf->len = bufpos;
1.170     dholland  547:
                    548:        /* truncate malloc region to actual length (maybe not useful) */
1.172     dholland  549:        if (lf->len > 0) {
1.218     sjg       550:                /* as for mmap case, ensure trailing \n */
                    551:                if (lf->buf[lf->len - 1] != '\n')
                    552:                        lf->len++;
1.172     dholland  553:                lf->buf = bmake_realloc(lf->buf, lf->len);
1.218     sjg       554:                lf->buf[lf->len - 1] = '\n';
1.172     dholland  555:        }
1.170     dholland  556:
                    557: done:
1.430     rillig    558:        if (path != NULL)
1.170     dholland  559:                close(fd);
1.430     rillig    560:
1.170     dholland  561:        return lf;
                    562: }
                    563:
1.248     rillig    564: /* old code */
1.77      christos  565:
1.279     rillig    566: /* Check if the current character is escaped on the current line. */
                    567: static Boolean
1.84      wiz       568: ParseIsEscaped(const char *line, const char *c)
1.77      christos  569: {
1.469     rillig    570:        Boolean active = FALSE;
                    571:        for (;;) {
                    572:                if (line == c)
                    573:                        return active;
                    574:                if (*--c != '\\')
                    575:                        return active;
                    576:                active = !active;
                    577:        }
1.77      christos  578: }
                    579:
1.278     rillig    580: /* Add the filename and lineno to the GNode so that we remember where it
                    581:  * was first defined. */
                    582: static void
                    583: ParseMark(GNode *gn)
                    584: {
1.469     rillig    585:        IFile *curFile = CurFile();
                    586:        gn->fname = curFile->fname;
                    587:        gn->lineno = curFile->lineno;
1.278     rillig    588: }
                    589:
1.368     rillig    590: /* Look in the table of keywords for one matching the given string.
                    591:  * Return the index of the keyword, or -1 if it isn't there. */
1.1       cgd       592: static int
1.120     dsl       593: ParseFindKeyword(const char *str)
1.1       cgd       594: {
1.469     rillig    595:        int start = 0;
                    596:        int end = sizeof parseKeywords / sizeof parseKeywords[0] - 1;
1.1       cgd       597:
1.469     rillig    598:        do {
                    599:                int curr = start + (end - start) / 2;
                    600:                int diff = strcmp(str, parseKeywords[curr].name);
                    601:
                    602:                if (diff == 0)
                    603:                        return curr;
                    604:                if (diff < 0)
                    605:                        end = curr - 1;
                    606:                else
                    607:                        start = curr + 1;
                    608:        } while (start <= end);
1.430     rillig    609:
1.469     rillig    610:        return -1;
1.1       cgd       611: }
                    612:
1.291     rillig    613: static void
1.441     rillig    614: PrintLocation(FILE *f, const char *fname, size_t lineno)
1.291     rillig    615: {
1.469     rillig    616:        char dirbuf[MAXPATHLEN + 1];
1.505     rillig    617:        FStr dir, base;
1.291     rillig    618:
1.441     rillig    619:        if (*fname == '/' || strcmp(fname, "(stdin)") == 0) {
1.481     rillig    620:                (void)fprintf(f, "\"%s\" line %u: ", fname, (unsigned)lineno);
1.299     rillig    621:                return;
                    622:        }
1.291     rillig    623:
1.299     rillig    624:        /* Find out which makefile is the culprit.
                    625:         * We try ${.PARSEDIR} and apply realpath(3) if not absolute. */
1.291     rillig    626:
1.505     rillig    627:        dir = Var_Value(".PARSEDIR", VAR_GLOBAL);
                    628:        if (dir.str == NULL)
                    629:                dir.str = ".";
                    630:        if (dir.str[0] != '/')
                    631:                dir.str = realpath(dir.str, dirbuf);
                    632:
                    633:        base = Var_Value(".PARSEFILE", VAR_GLOBAL);
                    634:        if (base.str == NULL)
                    635:                base.str = str_basename(fname);
                    636:
                    637:        (void)fprintf(f, "\"%s/%s\" line %u: ",
                    638:            dir.str, base.str, (unsigned)lineno);
                    639:
                    640:        FStr_Done(&base);
                    641:        FStr_Done(&dir);
1.291     rillig    642: }
                    643:
1.38      christos  644: static void
1.441     rillig    645: ParseVErrorInternal(FILE *f, const char *fname, size_t lineno,
1.398     rillig    646:                    ParseErrorLevel type, const char *fmt, va_list ap)
1.38      christos  647: {
1.56      christos  648:        static Boolean fatal_warning_error_printed = FALSE;
                    649:
1.148     sjg       650:        (void)fprintf(f, "%s: ", progname);
1.63      christos  651:
1.441     rillig    652:        if (fname != NULL)
                    653:                PrintLocation(f, fname, lineno);
1.38      christos  654:        if (type == PARSE_WARNING)
1.127     dsl       655:                (void)fprintf(f, "warning: ");
                    656:        (void)vfprintf(f, fmt, ap);
                    657:        (void)fprintf(f, "\n");
                    658:        (void)fflush(f);
1.300     rillig    659:
1.226     sjg       660:        if (type == PARSE_INFO)
                    661:                return;
1.401     rillig    662:        if (type == PARSE_FATAL || opts.parseWarnFatal)
1.300     rillig    663:                fatals++;
1.401     rillig    664:        if (opts.parseWarnFatal && !fatal_warning_error_printed) {
1.56      christos  665:                Error("parsing warnings being treated as errors");
                    666:                fatal_warning_error_printed = TRUE;
                    667:        }
1.38      christos  668: }
                    669:
1.203     joerg     670: static void
1.441     rillig    671: ParseErrorInternal(const char *fname, size_t lineno,
                    672:                   ParseErrorLevel type, const char *fmt, ...)
1.203     joerg     673: {
                    674:        va_list ap;
                    675:
1.441     rillig    676:        (void)fflush(stdout);
1.203     joerg     677:        va_start(ap, fmt);
1.441     rillig    678:        ParseVErrorInternal(stderr, fname, lineno, type, fmt, ap);
1.203     joerg     679:        va_end(ap);
                    680:
1.401     rillig    681:        if (opts.debug_file != stderr && opts.debug_file != stdout) {
1.203     joerg     682:                va_start(ap, fmt);
1.441     rillig    683:                ParseVErrorInternal(opts.debug_file, fname, lineno, type,
1.469     rillig    684:                    fmt, ap);
1.203     joerg     685:                va_end(ap);
                    686:        }
                    687: }
                    688:
1.441     rillig    689: /* Print a parse error message, including location information.
                    690:  *
                    691:  * If the level is PARSE_FATAL, continue parsing until the end of the
                    692:  * current top-level makefile, then exit (see Parse_File).
1.38      christos  693:  *
1.289     rillig    694:  * Fmt is given without a trailing newline. */
1.1       cgd       695: void
1.398     rillig    696: Parse_Error(ParseErrorLevel type, const char *fmt, ...)
1.1       cgd       697: {
                    698:        va_list ap;
1.156     dsl       699:        const char *fname;
                    700:        size_t lineno;
1.84      wiz       701:
1.408     rillig    702:        if (includes.len == 0) {
1.156     dsl       703:                fname = NULL;
                    704:                lineno = 0;
                    705:        } else {
1.408     rillig    706:                IFile *curFile = CurFile();
1.156     dsl       707:                fname = curFile->fname;
1.369     rillig    708:                lineno = (size_t)curFile->lineno;
1.148     sjg       709:        }
1.156     dsl       710:
                    711:        va_start(ap, fmt);
1.163     sjg       712:        (void)fflush(stdout);
1.156     dsl       713:        ParseVErrorInternal(stderr, fname, lineno, type, fmt, ap);
1.1       cgd       714:        va_end(ap);
1.127     dsl       715:
1.401     rillig    716:        if (opts.debug_file != stderr && opts.debug_file != stdout) {
1.127     dsl       717:                va_start(ap, fmt);
1.401     rillig    718:                ParseVErrorInternal(opts.debug_file, fname, lineno, type,
1.469     rillig    719:                    fmt, ap);
1.127     dsl       720:                va_end(ap);
                    721:        }
1.1       cgd       722: }
                    723:
1.161     sjg       724:
1.441     rillig    725: /* Parse and handle a .info, .warning or .error directive.
                    726:  * For an .error directive, immediately exit. */
1.503     rillig    727: static void
                    728: ParseMessage(ParseErrorLevel level, const char *levelName, const char *umsg)
1.161     sjg       729: {
1.475     rillig    730:        char *xmsg;
1.469     rillig    731:
1.503     rillig    732:        if (umsg[0] == '\0') {
                    733:                Parse_Error(PARSE_FATAL, "Missing argument for \".%s\"",
                    734:                    levelName);
                    735:                return;
                    736:        }
1.469     rillig    737:
1.475     rillig    738:        (void)Var_Subst(umsg, VAR_CMDLINE, VARE_WANTRES, &xmsg);
1.469     rillig    739:        /* TODO: handle errors */
                    740:
1.475     rillig    741:        Parse_Error(level, "%s", xmsg);
                    742:        free(xmsg);
1.469     rillig    743:
1.475     rillig    744:        if (level == PARSE_FATAL) {
1.469     rillig    745:                PrintOnError(NULL, NULL);
                    746:                exit(1);
                    747:        }
1.161     sjg       748: }
                    749:
1.316     rillig    750: /* Add the child to the parent's children.
1.1       cgd       751:  *
1.382     rillig    752:  * Additionally, add the parent to the child's parents, but only if the
                    753:  * target is not special.  An example for such a special target is .END,
                    754:  * which does not need to be informed once the child target has been made. */
                    755: static void
                    756: LinkSource(GNode *pgn, GNode *cgn, Boolean isSpecial)
                    757: {
1.469     rillig    758:        if ((pgn->type & OP_DOUBLEDEP) && !Lst_IsEmpty(&pgn->cohorts))
                    759:                pgn = pgn->cohorts.last->datum;
1.316     rillig    760:
1.469     rillig    761:        Lst_Append(&pgn->children, cgn);
                    762:        pgn->unmade++;
1.316     rillig    763:
1.469     rillig    764:        /* Special targets like .END don't need any children. */
                    765:        if (!isSpecial)
                    766:                Lst_Append(&cgn->parents, pgn);
                    767:
                    768:        if (DEBUG(PARSE)) {
                    769:                debug_printf("# %s: added child %s - %s\n",
                    770:                    __func__, pgn->name, cgn->name);
                    771:                Targ_PrintNode(pgn, 0);
                    772:                Targ_PrintNode(cgn, 0);
                    773:        }
1.1       cgd       774: }
                    775:
1.382     rillig    776: /* Add the node to each target from the current dependency group. */
                    777: static void
                    778: LinkToTargets(GNode *gn, Boolean isSpecial)
                    779: {
1.469     rillig    780:        GNodeListNode *ln;
                    781:
                    782:        for (ln = targets->first; ln != NULL; ln = ln->next)
                    783:                LinkSource(ln->datum, gn, isSpecial);
1.382     rillig    784: }
                    785:
1.337     rillig    786: static Boolean
                    787: TryApplyDependencyOperator(GNode *gn, GNodeType op)
1.1       cgd       788: {
                    789:        /*
1.469     rillig    790:         * If the node occurred on the left-hand side of a dependency and the
                    791:         * operator also defines a dependency, they must match.
1.1       cgd       792:         */
1.469     rillig    793:        if ((op & OP_OPMASK) && (gn->type & OP_OPMASK) &&
                    794:            ((op & OP_OPMASK) != (gn->type & OP_OPMASK))) {
                    795:                Parse_Error(PARSE_FATAL, "Inconsistent operator for %s",
                    796:                    gn->name);
                    797:                return FALSE;
                    798:        }
                    799:
                    800:        if (op == OP_DOUBLEDEP && (gn->type & OP_OPMASK) == OP_DOUBLEDEP) {
                    801:                /*
                    802:                 * If the node was of the left-hand side of a '::' operator,
                    803:                 * we need to create a new instance of it for the children
                    804:                 * and commands on this dependency line since each of these
                    805:                 * dependency groups has its own attributes and commands,
                    806:                 * separate from the others.
                    807:                 *
                    808:                 * The new instance is placed on the 'cohorts' list of the
                    809:                 * initial one (note the initial one is not on its own
                    810:                 * cohorts list) and the new instance is linked to all
                    811:                 * parents of the initial instance.
                    812:                 */
                    813:                GNode *cohort;
1.27      christos  814:
1.469     rillig    815:                /*
                    816:                 * Propagate copied bits to the initial node.  They'll be
                    817:                 * propagated back to the rest of the cohorts later.
                    818:                 */
                    819:                gn->type |= op & ~OP_OPMASK;
1.33      mycroft   820:
1.469     rillig    821:                cohort = Targ_NewInternalNode(gn->name);
                    822:                if (doing_depend)
                    823:                        ParseMark(cohort);
                    824:                /*
                    825:                 * Make the cohort invisible as well to avoid duplicating it
                    826:                 * into other variables. True, parents of this target won't
                    827:                 * tend to do anything with their local variables, but better
                    828:                 * safe than sorry.
                    829:                 *
                    830:                 * (I think this is pointless now, since the relevant list
                    831:                 * traversals will no longer see this node anyway. -mycroft)
                    832:                 */
                    833:                cohort->type = op | OP_INVISIBLE;
                    834:                Lst_Append(&gn->cohorts, cohort);
                    835:                cohort->centurion = gn;
                    836:                gn->unmade_cohorts++;
                    837:                snprintf(cohort->cohort_num, sizeof cohort->cohort_num, "#%d",
                    838:                    (unsigned int)gn->unmade_cohorts % 1000000);
                    839:        } else {
                    840:                /*
                    841:                 * We don't want to nuke any previous flags (whatever they
                    842:                 * were) so we just OR the new operator into the old.
                    843:                 */
                    844:                gn->type |= op;
                    845:        }
1.33      mycroft   846:
1.469     rillig    847:        return TRUE;
1.337     rillig    848: }
                    849:
                    850: static void
                    851: ApplyDependencyOperator(GNodeType op)
                    852: {
1.469     rillig    853:        GNodeListNode *ln;
                    854:
                    855:        for (ln = targets->first; ln != NULL; ln = ln->next)
                    856:                if (!TryApplyDependencyOperator(ln->datum, op))
                    857:                        break;
1.1       cgd       858: }
                    859:
1.467     rillig    860: /*
                    861:  * We add a .WAIT node in the dependency list. After any dynamic dependencies
                    862:  * (and filename globbing) have happened, it is given a dependency on each
                    863:  * previous child, back until the previous .WAIT node. The next child won't
                    864:  * be scheduled until the .WAIT node is built.
                    865:  *
                    866:  * We give each .WAIT node a unique name (mainly for diagnostics).
                    867:  */
                    868: static void
                    869: ParseDependencySourceWait(Boolean isSpecial)
                    870: {
                    871:        static int wait_number = 0;
                    872:        char wait_src[16];
                    873:        GNode *gn;
                    874:
                    875:        snprintf(wait_src, sizeof wait_src, ".WAIT_%u", ++wait_number);
                    876:        gn = Targ_NewInternalNode(wait_src);
                    877:        if (doing_depend)
                    878:                ParseMark(gn);
                    879:        gn->type = OP_WAIT | OP_PHONY | OP_DEPENDS | OP_NOTMAIN;
                    880:        LinkToTargets(gn, isSpecial);
                    881:
                    882: }
                    883:
1.368     rillig    884: static Boolean
1.464     rillig    885: ParseDependencySourceKeyword(const char *src, ParseSpecial specType)
1.1       cgd       886: {
1.468     rillig    887:        int keywd;
                    888:        GNodeType op;
1.1       cgd       889:
1.468     rillig    890:        if (*src != '.' || !ch_isupper(src[1]))
                    891:                return FALSE;
                    892:
                    893:        keywd = ParseFindKeyword(src);
                    894:        if (keywd == -1)
                    895:                return FALSE;
                    896:
                    897:        op = parseKeywords[keywd].op;
                    898:        if (op != OP_NONE) {
1.337     rillig    899:                ApplyDependencyOperator(op);
1.368     rillig    900:                return TRUE;
1.468     rillig    901:        }
                    902:        if (parseKeywords[keywd].spec == SP_WAIT) {
                    903:                ParseDependencySourceWait(specType != SP_NOT);
1.368     rillig    904:                return TRUE;
1.1       cgd       905:        }
1.468     rillig    906:        return FALSE;
1.368     rillig    907: }
1.18      christos  908:
1.368     rillig    909: static void
1.464     rillig    910: ParseDependencySourceMain(const char *src)
1.368     rillig    911: {
1.469     rillig    912:        /*
                    913:         * In a line like ".MAIN: source1 source2", it means we need to add
                    914:         * the sources of said target to the list of things to create.
                    915:         *
                    916:         * Note that this will only be invoked if the user didn't specify a
                    917:         * target on the command line and the .MAIN occurs for the first time.
                    918:         *
                    919:         * See ParseDoDependencyTargetSpecial, branch SP_MAIN.
                    920:         * See unit-tests/cond-func-make-main.mk.
                    921:         */
                    922:        Lst_Append(&opts.create, bmake_strdup(src));
                    923:        /*
                    924:         * Add the name to the .TARGETS variable as well, so the user can
                    925:         * employ that, if desired.
                    926:         */
                    927:        Var_Append(".TARGETS", src, VAR_GLOBAL);
1.368     rillig    928: }
1.18      christos  929:
1.368     rillig    930: static void
1.464     rillig    931: ParseDependencySourceOrder(const char *src)
1.368     rillig    932: {
1.469     rillig    933:        GNode *gn;
                    934:        /*
                    935:         * Create proper predecessor/successor links between the previous
                    936:         * source and the current one.
                    937:         */
                    938:        gn = Targ_GetNode(src);
                    939:        if (doing_depend)
                    940:                ParseMark(gn);
                    941:        if (order_pred != NULL) {
                    942:                Lst_Append(&order_pred->order_succ, gn);
                    943:                Lst_Append(&gn->order_pred, order_pred);
                    944:                if (DEBUG(PARSE)) {
                    945:                        debug_printf("# %s: added Order dependency %s - %s\n",
                    946:                            __func__, order_pred->name, gn->name);
                    947:                        Targ_PrintNode(order_pred, 0);
                    948:                        Targ_PrintNode(gn, 0);
                    949:                }
                    950:        }
                    951:        /*
                    952:         * The current source now becomes the predecessor for the next one.
                    953:         */
                    954:        order_pred = gn;
1.368     rillig    955: }
                    956:
                    957: static void
1.464     rillig    958: ParseDependencySourceOther(const char *src, GNodeType tOp,
                    959:                           ParseSpecial specType)
1.368     rillig    960: {
1.469     rillig    961:        GNode *gn;
                    962:
                    963:        /*
                    964:         * If the source is not an attribute, we need to find/create
                    965:         * a node for it. After that we can apply any operator to it
                    966:         * from a special target or link it to its parents, as
                    967:         * appropriate.
                    968:         *
                    969:         * In the case of a source that was the object of a :: operator,
                    970:         * the attribute is applied to all of its instances (as kept in
                    971:         * the 'cohorts' list of the node) or all the cohorts are linked
                    972:         * to all the targets.
                    973:         */
1.363     rillig    974:
1.469     rillig    975:        /* Find/create the 'src' node and attach to all targets */
                    976:        gn = Targ_GetNode(src);
                    977:        if (doing_depend)
                    978:                ParseMark(gn);
                    979:        if (tOp != OP_NONE)
                    980:                gn->type |= tOp;
                    981:        else
                    982:                LinkToTargets(gn, specType != SP_NOT);
1.1       cgd       983: }
                    984:
1.469     rillig    985: /*
                    986:  * Given the name of a source in a dependency line, figure out if it is an
1.368     rillig    987:  * attribute (such as .SILENT) and apply it to the targets if it is. Else
                    988:  * decide if there is some attribute which should be applied *to* the source
                    989:  * because of some special target (such as .PHONY) and apply it if so.
                    990:  * Otherwise, make the source a child of the targets in the list 'targets'.
                    991:  *
                    992:  * Input:
                    993:  *     tOp             operator (if any) from special targets
                    994:  *     src             name of the source to handle
                    995:  */
                    996: static void
1.464     rillig    997: ParseDependencySource(GNodeType tOp, const char *src, ParseSpecial specType)
1.368     rillig    998: {
1.469     rillig    999:        if (ParseDependencySourceKeyword(src, specType))
                   1000:                return;
1.368     rillig   1001:
1.469     rillig   1002:        if (specType == SP_MAIN)
                   1003:                ParseDependencySourceMain(src);
                   1004:        else if (specType == SP_ORDER)
                   1005:                ParseDependencySourceOrder(src);
                   1006:        else
                   1007:                ParseDependencySourceOther(src, tOp, specType);
1.368     rillig   1008: }
                   1009:
1.469     rillig   1010: /*
                   1011:  * If we have yet to decide on a main target to make, in the absence of any
1.335     rillig   1012:  * user input, we want the first target on the first dependency line that is
1.469     rillig   1013:  * actually a real target (i.e. isn't a .USE or .EXEC rule) to be made.
                   1014:  */
1.335     rillig   1015: static void
                   1016: FindMainTarget(void)
1.1       cgd      1017: {
1.469     rillig   1018:        GNodeListNode *ln;
1.335     rillig   1019:
1.469     rillig   1020:        if (mainNode != NULL)
                   1021:                return;
1.335     rillig   1022:
1.469     rillig   1023:        for (ln = targets->first; ln != NULL; ln = ln->next) {
                   1024:                GNode *gn = ln->datum;
                   1025:                if (!(gn->type & OP_NOTARGET)) {
                   1026:                        DEBUG1(MAKE, "Setting main node to \"%s\"\n", gn->name);
                   1027:                        mainNode = gn;
                   1028:                        Targ_SetMain(gn);
                   1029:                        return;
                   1030:                }
1.335     rillig   1031:        }
1.1       cgd      1032: }
                   1033:
1.311     rillig   1034: /*
                   1035:  * We got to the end of the line while we were still looking at targets.
                   1036:  *
                   1037:  * Ending a dependency line without an operator is a Bozo no-no.  As a
                   1038:  * heuristic, this is also often triggered by undetected conflicts from
                   1039:  * cvs/rcs merges.
                   1040:  */
                   1041: static void
1.395     rillig   1042: ParseErrorNoDependency(const char *lstart)
1.311     rillig   1043: {
1.469     rillig   1044:        if ((strncmp(lstart, "<<<<<<", 6) == 0) ||
                   1045:            (strncmp(lstart, "======", 6) == 0) ||
                   1046:            (strncmp(lstart, ">>>>>>", 6) == 0))
                   1047:                Parse_Error(PARSE_FATAL,
1.311     rillig   1048:                    "Makefile appears to contain unresolved cvs/rcs/??? merge conflicts");
1.469     rillig   1049:        else if (lstart[0] == '.') {
                   1050:                const char *dirstart = lstart + 1;
                   1051:                const char *dirend;
                   1052:                cpp_skip_whitespace(&dirstart);
                   1053:                dirend = dirstart;
                   1054:                while (ch_isalnum(*dirend) || *dirend == '-')
                   1055:                        dirend++;
                   1056:                Parse_Error(PARSE_FATAL, "Unknown directive \"%.*s\"",
1.311     rillig   1057:                    (int)(dirend - dirstart), dirstart);
1.469     rillig   1058:        } else
                   1059:                Parse_Error(PARSE_FATAL, "Need an operator");
1.311     rillig   1060: }
                   1061:
1.314     rillig   1062: static void
1.445     rillig   1063: ParseDependencyTargetWord(const char **pp, const char *lstart)
1.314     rillig   1064: {
1.469     rillig   1065:        const char *cp = *pp;
                   1066:
                   1067:        while (*cp != '\0') {
                   1068:                if ((ch_isspace(*cp) || *cp == '!' || *cp == ':' ||
                   1069:                     *cp == '(') &&
                   1070:                    !ParseIsEscaped(lstart, cp))
                   1071:                        break;
1.314     rillig   1072:
1.469     rillig   1073:                if (*cp == '$') {
                   1074:                        /*
                   1075:                         * Must be a dynamic source (would have been expanded
                   1076:                         * otherwise), so call the Var module to parse the
                   1077:                         * puppy so we can safely advance beyond it.
                   1078:                         *
                   1079:                         * There should be no errors in this, as they would
                   1080:                         * have been discovered in the initial Var_Subst and
                   1081:                         * we wouldn't be here.
                   1082:                         */
                   1083:                        const char *nested_p = cp;
1.504     rillig   1084:                        FStr nested_val;
1.314     rillig   1085:
1.469     rillig   1086:                        /* XXX: Why VARE_WANTRES? */
                   1087:                        (void)Var_Parse(&nested_p, VAR_CMDLINE,
1.504     rillig   1088:                            VARE_WANTRES | VARE_UNDEFERR, &nested_val);
1.469     rillig   1089:                        /* TODO: handle errors */
1.504     rillig   1090:                        FStr_Done(&nested_val);
1.469     rillig   1091:                        cp += nested_p - cp;
                   1092:                } else
                   1093:                        cp++;
                   1094:        }
1.314     rillig   1095:
1.469     rillig   1096:        *pp = cp;
1.314     rillig   1097: }
                   1098:
1.440     rillig   1099: /* Handle special targets like .PATH, .DEFAULT, .BEGIN, .ORDER. */
1.368     rillig   1100: static void
1.395     rillig   1101: ParseDoDependencyTargetSpecial(ParseSpecial *inout_specType,
1.478     rillig   1102:                               const char *line, /* XXX: bad name */
1.395     rillig   1103:                               SearchPathList **inout_paths)
1.368     rillig   1104: {
1.469     rillig   1105:        switch (*inout_specType) {
                   1106:        case SP_PATH:
                   1107:                if (*inout_paths == NULL)
                   1108:                        *inout_paths = Lst_New();
                   1109:                Lst_Append(*inout_paths, &dirSearchPath);
                   1110:                break;
                   1111:        case SP_MAIN:
                   1112:                /*
                   1113:                 * Allow targets from the command line to override the
                   1114:                 * .MAIN node.
                   1115:                 */
                   1116:                if (!Lst_IsEmpty(&opts.create))
                   1117:                        *inout_specType = SP_NOT;
                   1118:                break;
                   1119:        case SP_BEGIN:
                   1120:        case SP_END:
                   1121:        case SP_STALE:
                   1122:        case SP_ERROR:
                   1123:        case SP_INTERRUPT: {
                   1124:                GNode *gn = Targ_GetNode(line);
                   1125:                if (doing_depend)
                   1126:                        ParseMark(gn);
                   1127:                gn->type |= OP_NOTMAIN | OP_SPECIAL;
                   1128:                Lst_Append(targets, gn);
                   1129:                break;
                   1130:        }
                   1131:        case SP_DEFAULT: {
                   1132:                /*
                   1133:                 * Need to create a node to hang commands on, but we don't
                   1134:                 * want it in the graph, nor do we want it to be the Main
                   1135:                 * Target. We claim the node is a transformation rule to make
                   1136:                 * life easier later, when we'll use Make_HandleUse to
                   1137:                 * actually apply the .DEFAULT commands.
                   1138:                 */
                   1139:                GNode *gn = GNode_New(".DEFAULT");
                   1140:                gn->type |= OP_NOTMAIN | OP_TRANSFORM;
                   1141:                Lst_Append(targets, gn);
                   1142:                defaultNode = gn;
                   1143:                break;
                   1144:        }
                   1145:        case SP_DELETE_ON_ERROR:
                   1146:                deleteOnError = TRUE;
                   1147:                break;
                   1148:        case SP_NOTPARALLEL:
                   1149:                opts.maxJobs = 1;
                   1150:                break;
                   1151:        case SP_SINGLESHELL:
                   1152:                opts.compatMake = TRUE;
                   1153:                break;
                   1154:        case SP_ORDER:
                   1155:                order_pred = NULL;
                   1156:                break;
                   1157:        default:
                   1158:                break;
                   1159:        }
1.368     rillig   1160: }
                   1161:
                   1162: /*
                   1163:  * .PATH<suffix> has to be handled specially.
                   1164:  * Call on the suffix module to give us a path to modify.
                   1165:  */
                   1166: static Boolean
1.478     rillig   1167: ParseDoDependencyTargetPath(const char *line, /* XXX: bad name */
                   1168:                            SearchPathList **inout_paths)
1.368     rillig   1169: {
1.469     rillig   1170:        SearchPath *path;
1.368     rillig   1171:
1.469     rillig   1172:        path = Suff_GetPath(&line[5]);
                   1173:        if (path == NULL) {
                   1174:                Parse_Error(PARSE_FATAL,
                   1175:                    "Suffix '%s' not defined (yet)", &line[5]);
                   1176:                return FALSE;
                   1177:        }
1.430     rillig   1178:
1.469     rillig   1179:        if (*inout_paths == NULL)
                   1180:                *inout_paths = Lst_New();
                   1181:        Lst_Append(*inout_paths, path);
1.430     rillig   1182:
1.469     rillig   1183:        return TRUE;
1.368     rillig   1184: }
                   1185:
                   1186: /*
                   1187:  * See if it's a special target and if so set specType to match it.
1.364     rillig   1188:  */
1.368     rillig   1189: static Boolean
1.478     rillig   1190: ParseDoDependencyTarget(const char *line, /* XXX: bad name */
                   1191:                        ParseSpecial *inout_specType,
1.395     rillig   1192:                        GNodeType *out_tOp, SearchPathList **inout_paths)
1.364     rillig   1193: {
1.469     rillig   1194:        int keywd;
                   1195:
1.478     rillig   1196:        if (!(line[0] == '.' && ch_isupper(line[1])))
1.469     rillig   1197:                return TRUE;
                   1198:
                   1199:        /*
                   1200:         * See if the target is a special target that must have it
                   1201:         * or its sources handled specially.
                   1202:         */
                   1203:        keywd = ParseFindKeyword(line);
                   1204:        if (keywd != -1) {
                   1205:                if (*inout_specType == SP_PATH &&
                   1206:                    parseKeywords[keywd].spec != SP_PATH) {
                   1207:                        Parse_Error(PARSE_FATAL, "Mismatched special targets");
                   1208:                        return FALSE;
                   1209:                }
                   1210:
                   1211:                *inout_specType = parseKeywords[keywd].spec;
                   1212:                *out_tOp = parseKeywords[keywd].op;
                   1213:
                   1214:                ParseDoDependencyTargetSpecial(inout_specType, line,
                   1215:                    inout_paths);
1.364     rillig   1216:
1.469     rillig   1217:        } else if (strncmp(line, ".PATH", 5) == 0) {
                   1218:                *inout_specType = SP_PATH;
                   1219:                if (!ParseDoDependencyTargetPath(line, inout_paths))
                   1220:                        return FALSE;
                   1221:        }
1.368     rillig   1222:        return TRUE;
                   1223: }
                   1224:
                   1225: static void
1.478     rillig   1226: ParseDoDependencyTargetMundane(char *line, /* XXX: bad name */
                   1227:                               StringList *curTargs)
1.368     rillig   1228: {
1.469     rillig   1229:        if (Dir_HasWildcards(line)) {
                   1230:                /*
                   1231:                 * Targets are to be sought only in the current directory,
                   1232:                 * so create an empty path for the thing. Note we need to
                   1233:                 * use Dir_Destroy in the destruction of the path as the
                   1234:                 * Dir module could have added a directory to the path...
                   1235:                 */
                   1236:                SearchPath *emptyPath = SearchPath_New();
1.368     rillig   1237:
1.469     rillig   1238:                Dir_Expand(line, emptyPath, curTargs);
1.368     rillig   1239:
1.469     rillig   1240:                SearchPath_Free(emptyPath);
                   1241:        } else {
                   1242:                /*
                   1243:                 * No wildcards, but we want to avoid code duplication,
                   1244:                 * so create a list with the word on it.
                   1245:                 */
                   1246:                Lst_Append(curTargs, line);
                   1247:        }
1.368     rillig   1248:
1.469     rillig   1249:        /* Apply the targets. */
1.368     rillig   1250:
1.469     rillig   1251:        while (!Lst_IsEmpty(curTargs)) {
                   1252:                char *targName = Lst_Dequeue(curTargs);
                   1253:                GNode *gn = Suff_IsTransform(targName)
1.368     rillig   1254:                    ? Suff_AddTransform(targName)
                   1255:                    : Targ_GetNode(targName);
1.469     rillig   1256:                if (doing_depend)
                   1257:                        ParseMark(gn);
1.368     rillig   1258:
1.469     rillig   1259:                Lst_Append(targets, gn);
                   1260:        }
1.368     rillig   1261: }
                   1262:
                   1263: static void
                   1264: ParseDoDependencyTargetExtraWarn(char **pp, const char *lstart)
                   1265: {
1.469     rillig   1266:        Boolean warning = FALSE;
                   1267:        char *cp = *pp;
1.368     rillig   1268:
1.469     rillig   1269:        while (*cp != '\0') {
                   1270:                if (!ParseIsEscaped(lstart, cp) && (*cp == '!' || *cp == ':'))
                   1271:                        break;
                   1272:                if (ParseIsEscaped(lstart, cp) || (*cp != ' ' && *cp != '\t'))
                   1273:                        warning = TRUE;
                   1274:                cp++;
                   1275:        }
                   1276:        if (warning)
                   1277:                Parse_Error(PARSE_WARNING, "Extra target ignored");
1.430     rillig   1278:
1.469     rillig   1279:        *pp = cp;
1.368     rillig   1280: }
                   1281:
                   1282: static void
1.395     rillig   1283: ParseDoDependencyCheckSpec(ParseSpecial specType)
1.368     rillig   1284: {
1.469     rillig   1285:        switch (specType) {
                   1286:        default:
                   1287:                Parse_Error(PARSE_WARNING,
1.441     rillig   1288:                    "Special and mundane targets don't mix. "
                   1289:                    "Mundane ones ignored");
1.469     rillig   1290:                break;
                   1291:        case SP_DEFAULT:
                   1292:        case SP_STALE:
                   1293:        case SP_BEGIN:
                   1294:        case SP_END:
                   1295:        case SP_ERROR:
                   1296:        case SP_INTERRUPT:
                   1297:                /*
                   1298:                 * These create nodes on which to hang commands, so targets
                   1299:                 * shouldn't be empty.
                   1300:                 */
                   1301:        case SP_NOT:
                   1302:                /* Nothing special here -- targets can be empty if it wants. */
                   1303:                break;
                   1304:        }
1.368     rillig   1305: }
                   1306:
                   1307: static Boolean
1.395     rillig   1308: ParseDoDependencyParseOp(char **pp, const char *lstart, GNodeType *out_op)
1.368     rillig   1309: {
1.469     rillig   1310:        const char *cp = *pp;
1.368     rillig   1311:
1.469     rillig   1312:        if (*cp == '!') {
                   1313:                *out_op = OP_FORCE;
                   1314:                (*pp)++;
                   1315:                return TRUE;
                   1316:        }
1.368     rillig   1317:
1.469     rillig   1318:        if (*cp == ':') {
                   1319:                if (cp[1] == ':') {
                   1320:                        *out_op = OP_DOUBLEDEP;
                   1321:                        (*pp) += 2;
                   1322:                } else {
                   1323:                        *out_op = OP_DEPENDS;
                   1324:                        (*pp)++;
                   1325:                }
                   1326:                return TRUE;
1.368     rillig   1327:        }
1.364     rillig   1328:
1.469     rillig   1329:        {
                   1330:                const char *msg = lstart[0] == '.'
                   1331:                    ? "Unknown directive" : "Missing dependency operator";
                   1332:                Parse_Error(PARSE_FATAL, "%s", msg);
                   1333:                return FALSE;
                   1334:        }
1.368     rillig   1335: }
1.364     rillig   1336:
1.368     rillig   1337: static void
1.392     rillig   1338: ClearPaths(SearchPathList *paths)
                   1339: {
1.469     rillig   1340:        if (paths != NULL) {
                   1341:                SearchPathListNode *ln;
                   1342:                for (ln = paths->first; ln != NULL; ln = ln->next)
                   1343:                        SearchPath_Clear(ln->datum);
                   1344:        }
1.392     rillig   1345:
1.469     rillig   1346:        Dir_SetPATH();
1.392     rillig   1347: }
                   1348:
                   1349: static void
1.395     rillig   1350: ParseDoDependencySourcesEmpty(ParseSpecial specType, SearchPathList *paths)
1.368     rillig   1351: {
1.469     rillig   1352:        switch (specType) {
                   1353:        case SP_SUFFIXES:
                   1354:                Suff_ClearSuffixes();
                   1355:                break;
                   1356:        case SP_PRECIOUS:
                   1357:                allPrecious = TRUE;
                   1358:                break;
                   1359:        case SP_IGNORE:
                   1360:                opts.ignoreErrors = TRUE;
                   1361:                break;
                   1362:        case SP_SILENT:
                   1363:                opts.beSilent = TRUE;
                   1364:                break;
                   1365:        case SP_PATH:
                   1366:                ClearPaths(paths);
                   1367:                break;
1.368     rillig   1368: #ifdef POSIX
1.469     rillig   1369:        case SP_POSIX:
                   1370:                Var_Set("%POSIX", "1003.2", VAR_GLOBAL);
                   1371:                break;
1.368     rillig   1372: #endif
1.469     rillig   1373:        default:
                   1374:                break;
                   1375:        }
1.368     rillig   1376: }
1.364     rillig   1377:
1.393     rillig   1378: static void
                   1379: AddToPaths(const char *dir, SearchPathList *paths)
                   1380: {
1.469     rillig   1381:        if (paths != NULL) {
                   1382:                SearchPathListNode *ln;
                   1383:                for (ln = paths->first; ln != NULL; ln = ln->next)
                   1384:                        (void)Dir_AddDir(ln->datum, dir);
                   1385:        }
1.393     rillig   1386: }
                   1387:
1.368     rillig   1388: /*
                   1389:  * If the target was one that doesn't take files as its sources
                   1390:  * but takes something like suffixes, we take each
                   1391:  * space-separated word on the line as a something and deal
                   1392:  * with it accordingly.
                   1393:  *
                   1394:  * If the target was .SUFFIXES, we take each source as a
                   1395:  * suffix and add it to the list of suffixes maintained by the
                   1396:  * Suff module.
                   1397:  *
                   1398:  * If the target was a .PATH, we add the source as a directory
                   1399:  * to search on the search path.
                   1400:  *
                   1401:  * If it was .INCLUDES, the source is taken to be the suffix of
                   1402:  * files which will be #included and whose search path should
                   1403:  * be present in the .INCLUDES variable.
                   1404:  *
                   1405:  * If it was .LIBS, the source is taken to be the suffix of
                   1406:  * files which are considered libraries and whose search path
                   1407:  * should be present in the .LIBS variable.
                   1408:  *
                   1409:  * If it was .NULL, the source is the suffix to use when a file
                   1410:  * has no valid suffix.
                   1411:  *
                   1412:  * If it was .OBJDIR, the source is a new definition for .OBJDIR,
                   1413:  * and will cause make to do a new chdir to that path.
                   1414:  */
                   1415: static void
1.395     rillig   1416: ParseDoDependencySourceSpecial(ParseSpecial specType, char *word,
                   1417:                               SearchPathList *paths)
1.368     rillig   1418: {
1.469     rillig   1419:        switch (specType) {
                   1420:        case SP_SUFFIXES:
                   1421:                Suff_AddSuffix(word, &mainNode);
                   1422:                break;
                   1423:        case SP_PATH:
                   1424:                AddToPaths(word, paths);
                   1425:                break;
                   1426:        case SP_INCLUDES:
                   1427:                Suff_AddInclude(word);
                   1428:                break;
                   1429:        case SP_LIBS:
                   1430:                Suff_AddLib(word);
                   1431:                break;
                   1432:        case SP_NULL:
                   1433:                Suff_SetNull(word);
                   1434:                break;
                   1435:        case SP_OBJDIR:
                   1436:                Main_SetObjdir(FALSE, "%s", word);
                   1437:                break;
                   1438:        default:
                   1439:                break;
                   1440:        }
1.368     rillig   1441: }
1.364     rillig   1442:
1.368     rillig   1443: static Boolean
1.395     rillig   1444: ParseDoDependencyTargets(char **inout_cp,
                   1445:                         char **inout_line,
                   1446:                         const char *lstart,
                   1447:                         ParseSpecial *inout_specType,
                   1448:                         GNodeType *inout_tOp,
                   1449:                         SearchPathList **inout_paths,
                   1450:                         StringList *curTargs)
1.368     rillig   1451: {
1.469     rillig   1452:        char *cp;
                   1453:        char *tgt = *inout_line;
                   1454:        char savec;
                   1455:        const char *p;
                   1456:
                   1457:        for (;;) {
                   1458:                /*
                   1459:                 * Here LINE points to the beginning of the next word, and
                   1460:                 * LSTART points to the actual beginning of the line.
                   1461:                 */
                   1462:
                   1463:                /* Find the end of the next word. */
                   1464:                cp = tgt;
                   1465:                p = cp;
                   1466:                ParseDependencyTargetWord(&p, lstart);
                   1467:                cp += p - cp;
                   1468:
                   1469:                /*
                   1470:                 * If the word is followed by a left parenthesis, it's the
                   1471:                 * name of an object file inside an archive (ar file).
                   1472:                 */
                   1473:                if (!ParseIsEscaped(lstart, cp) && *cp == '(') {
                   1474:                        /*
                   1475:                         * Archives must be handled specially to make sure the
                   1476:                         * OP_ARCHV flag is set in their 'type' field, for one
                   1477:                         * thing, and because things like "archive(file1.o
                   1478:                         * file2.o file3.o)" are permissible.
                   1479:                         *
                   1480:                         * Arch_ParseArchive will set 'line' to be the first
                   1481:                         * non-blank after the archive-spec. It creates/finds
                   1482:                         * nodes for the members and places them on the given
                   1483:                         * list, returning TRUE if all went well and FALSE if
                   1484:                         * there was an error in the specification. On error,
                   1485:                         * line should remain untouched.
                   1486:                         */
                   1487:                        if (!Arch_ParseArchive(&tgt, targets, VAR_CMDLINE)) {
                   1488:                                Parse_Error(PARSE_FATAL,
                   1489:                                    "Error in archive specification: \"%s\"",
                   1490:                                    tgt);
                   1491:                                return FALSE;
                   1492:                        }
                   1493:
                   1494:                        cp = tgt;
                   1495:                        continue;
                   1496:                }
1.444     rillig   1497:
1.469     rillig   1498:                if (*cp == '\0') {
                   1499:                        ParseErrorNoDependency(lstart);
                   1500:                        return FALSE;
                   1501:                }
1.27      christos 1502:
1.469     rillig   1503:                /* Insert a null terminator. */
                   1504:                savec = *cp;
                   1505:                *cp = '\0';
1.204     dholland 1506:
1.469     rillig   1507:                if (!ParseDoDependencyTarget(tgt, inout_specType, inout_tOp,
                   1508:                    inout_paths))
                   1509:                        return FALSE;
1.118     dsl      1510:
1.469     rillig   1511:                /*
                   1512:                 * Have word in line. Get or create its node and stick it at
                   1513:                 * the end of the targets list
                   1514:                 */
                   1515:                if (*inout_specType == SP_NOT && *tgt != '\0')
                   1516:                        ParseDoDependencyTargetMundane(tgt, curTargs);
                   1517:                else if (*inout_specType == SP_PATH && *tgt != '.' &&
                   1518:                         *tgt != '\0')
                   1519:                        Parse_Error(PARSE_WARNING, "Extra target (%s) ignored",
                   1520:                            tgt);
1.368     rillig   1521:
1.469     rillig   1522:                /* Don't need the inserted null terminator any more. */
                   1523:                *cp = savec;
1.368     rillig   1524:
1.469     rillig   1525:                /*
                   1526:                 * If it is a special type and not .PATH, it's the only target
                   1527:                 * we allow on this line.
                   1528:                 */
                   1529:                if (*inout_specType != SP_NOT && *inout_specType != SP_PATH)
                   1530:                        ParseDoDependencyTargetExtraWarn(&cp, lstart);
                   1531:                else
                   1532:                        pp_skip_whitespace(&cp);
1.368     rillig   1533:
1.469     rillig   1534:                tgt = cp;
                   1535:                if (*tgt == '\0')
                   1536:                        break;
                   1537:                if ((*tgt == '!' || *tgt == ':') &&
                   1538:                    !ParseIsEscaped(lstart, tgt))
                   1539:                        break;
                   1540:        }
1.430     rillig   1541:
1.469     rillig   1542:        *inout_cp = cp;
                   1543:        *inout_line = tgt;
                   1544:        return TRUE;
1.368     rillig   1545: }
1.27      christos 1546:
1.368     rillig   1547: static void
1.395     rillig   1548: ParseDoDependencySourcesSpecial(char *start, char *end,
1.368     rillig   1549:                                ParseSpecial specType, SearchPathList *paths)
                   1550: {
1.469     rillig   1551:        char savec;
1.204     dholland 1552:
1.469     rillig   1553:        while (*start != '\0') {
                   1554:                while (*end != '\0' && !ch_isspace(*end))
                   1555:                        end++;
                   1556:                savec = *end;
                   1557:                *end = '\0';
                   1558:                ParseDoDependencySourceSpecial(specType, start, paths);
                   1559:                *end = savec;
                   1560:                if (savec != '\0')
                   1561:                        end++;
                   1562:                pp_skip_whitespace(&end);
                   1563:                start = end;
                   1564:        }
1.368     rillig   1565: }
                   1566:
                   1567: static Boolean
1.395     rillig   1568: ParseDoDependencySourcesMundane(char *start, char *end,
1.374     rillig   1569:                                ParseSpecial specType, GNodeType tOp)
1.368     rillig   1570: {
1.469     rillig   1571:        while (*start != '\0') {
1.367     rillig   1572:                /*
1.469     rillig   1573:                 * The targets take real sources, so we must beware of archive
                   1574:                 * specifications (i.e. things with left parentheses in them)
                   1575:                 * and handle them accordingly.
1.367     rillig   1576:                 */
1.469     rillig   1577:                for (; *end != '\0' && !ch_isspace(*end); end++) {
                   1578:                        if (*end == '(' && end > start && end[-1] != '$') {
                   1579:                                /*
                   1580:                                 * Only stop for a left parenthesis if it
                   1581:                                 * isn't at the start of a word (that'll be
                   1582:                                 * for variable changes later) and isn't
                   1583:                                 * preceded by a dollar sign (a dynamic
                   1584:                                 * source).
                   1585:                                 */
                   1586:                                break;
                   1587:                        }
                   1588:                }
1.368     rillig   1589:
1.469     rillig   1590:                if (*end == '(') {
                   1591:                        GNodeList sources = LST_INIT;
                   1592:                        if (!Arch_ParseArchive(&start, &sources, VAR_CMDLINE)) {
                   1593:                                Parse_Error(PARSE_FATAL,
                   1594:                                    "Error in source archive spec \"%s\"",
                   1595:                                    start);
                   1596:                                return FALSE;
                   1597:                        }
1.368     rillig   1598:
1.469     rillig   1599:                        while (!Lst_IsEmpty(&sources)) {
                   1600:                                GNode *gn = Lst_Dequeue(&sources);
                   1601:                                ParseDependencySource(tOp, gn->name, specType);
                   1602:                        }
                   1603:                        Lst_Done(&sources);
                   1604:                        end = start;
                   1605:                } else {
                   1606:                        if (*end != '\0') {
                   1607:                                *end = '\0';
                   1608:                                end++;
                   1609:                        }
1.368     rillig   1610:
1.469     rillig   1611:                        ParseDependencySource(tOp, start, specType);
                   1612:                }
                   1613:                pp_skip_whitespace(&end);
                   1614:                start = end;
1.368     rillig   1615:        }
1.469     rillig   1616:        return TRUE;
1.368     rillig   1617: }
1.1       cgd      1618:
1.368     rillig   1619: /* Parse a dependency line consisting of targets, followed by a dependency
                   1620:  * operator, optionally followed by sources.
                   1621:  *
                   1622:  * The nodes of the sources are linked as children to the nodes of the
                   1623:  * targets. Nodes are created as necessary.
                   1624:  *
                   1625:  * The operator is applied to each node in the global 'targets' list,
                   1626:  * which is where the nodes found for the targets are kept, by means of
                   1627:  * the ParseDoOp function.
                   1628:  *
                   1629:  * The sources are parsed in much the same way as the targets, except
                   1630:  * that they are expanded using the wildcarding scheme of the C-Shell,
1.441     rillig   1631:  * and a target is created for each expanded word. Each of the resulting
                   1632:  * nodes is then linked to each of the targets as one of its children.
1.368     rillig   1633:  *
                   1634:  * Certain targets and sources such as .PHONY or .PRECIOUS are handled
                   1635:  * specially. These are the ones detailed by the specType variable.
                   1636:  *
                   1637:  * The storing of transformation rules such as '.c.o' is also taken care of
                   1638:  * here. A target is recognized as a transformation rule by calling
                   1639:  * Suff_IsTransform. If it is a transformation rule, its node is gotten
                   1640:  * from the suffix module via Suff_AddTransform rather than the standard
                   1641:  * Targ_FindNode in the target module.
1.441     rillig   1642:  *
                   1643:  * Upon return, the value of the line is unspecified.
1.368     rillig   1644:  */
                   1645: static void
                   1646: ParseDoDependency(char *line)
                   1647: {
1.469     rillig   1648:        char *cp;               /* our current position */
                   1649:        GNodeType op;           /* the operator on the line */
                   1650:        SearchPathList *paths;  /* search paths to alter when parsing
1.368     rillig   1651:                                 * a list of .PATH targets */
1.469     rillig   1652:        GNodeType tOp;          /* operator from special target */
                   1653:        /* target names to be found and added to the targets list */
                   1654:        StringList curTargs = LST_INIT;
                   1655:        char *lstart = line;
                   1656:
                   1657:        /*
                   1658:         * specType contains the SPECial TYPE of the current target. It is
                   1659:         * SP_NOT if the target is unspecial. If it *is* special, however, the
                   1660:         * children are linked as children of the parent but not vice versa.
                   1661:         */
                   1662:        ParseSpecial specType = SP_NOT;
                   1663:
                   1664:        DEBUG1(PARSE, "ParseDoDependency(%s)\n", line);
                   1665:        tOp = OP_NONE;
                   1666:
                   1667:        paths = NULL;
                   1668:
                   1669:        /*
                   1670:         * First, grind through the targets.
                   1671:         */
1.478     rillig   1672:        /* XXX: don't use line as an iterator variable */
1.469     rillig   1673:        if (!ParseDoDependencyTargets(&cp, &line, lstart, &specType, &tOp,
                   1674:            &paths, &curTargs))
                   1675:                goto out;
                   1676:
                   1677:        /*
                   1678:         * Don't need the list of target names anymore.
                   1679:         * The targets themselves are now in the global variable 'targets'.
                   1680:         */
                   1681:        Lst_Done(&curTargs);
                   1682:        Lst_Init(&curTargs);
                   1683:
                   1684:        if (!Lst_IsEmpty(targets))
                   1685:                ParseDoDependencyCheckSpec(specType);
                   1686:
                   1687:        /*
                   1688:         * Have now parsed all the target names. Must parse the operator next.
                   1689:         */
                   1690:        if (!ParseDoDependencyParseOp(&cp, lstart, &op))
                   1691:                goto out;
                   1692:
                   1693:        /*
                   1694:         * Apply the operator to the target. This is how we remember which
                   1695:         * operator a target was defined with. It fails if the operator
                   1696:         * used isn't consistent across all references.
                   1697:         */
                   1698:        ApplyDependencyOperator(op);
                   1699:
                   1700:        /*
                   1701:         * Onward to the sources.
                   1702:         *
                   1703:         * LINE will now point to the first source word, if any, or the
                   1704:         * end of the string if not.
                   1705:         */
                   1706:        pp_skip_whitespace(&cp);
                   1707:        line = cp;              /* XXX: 'line' is an inappropriate name */
                   1708:
                   1709:        /*
                   1710:         * Several special targets take different actions if present with no
                   1711:         * sources:
                   1712:         *      a .SUFFIXES line with no sources clears out all old suffixes
                   1713:         *      a .PRECIOUS line makes all targets precious
                   1714:         *      a .IGNORE line ignores errors for all targets
                   1715:         *      a .SILENT line creates silence when making all targets
                   1716:         *      a .PATH removes all directories from the search path(s).
                   1717:         */
                   1718:        if (line[0] == '\0') {
                   1719:                ParseDoDependencySourcesEmpty(specType, paths);
                   1720:        } else if (specType == SP_MFLAGS) {
                   1721:                /*
                   1722:                 * Call on functions in main.c to deal with these arguments and
                   1723:                 * set the initial character to a null-character so the loop to
                   1724:                 * get sources won't get anything
                   1725:                 */
                   1726:                Main_ParseArgLine(line);
                   1727:                *line = '\0';
                   1728:        } else if (specType == SP_SHELL) {
                   1729:                if (!Job_ParseShell(line)) {
                   1730:                        Parse_Error(PARSE_FATAL,
                   1731:                            "improper shell specification");
                   1732:                        goto out;
                   1733:                }
                   1734:                *line = '\0';
                   1735:        } else if (specType == SP_NOTPARALLEL || specType == SP_SINGLESHELL ||
                   1736:                   specType == SP_DELETE_ON_ERROR) {
                   1737:                *line = '\0';
                   1738:        }
                   1739:
                   1740:        /* Now go for the sources. */
                   1741:        if (specType == SP_SUFFIXES || specType == SP_PATH ||
                   1742:            specType == SP_INCLUDES || specType == SP_LIBS ||
                   1743:            specType == SP_NULL || specType == SP_OBJDIR) {
                   1744:                ParseDoDependencySourcesSpecial(line, cp, specType, paths);
                   1745:                if (paths != NULL) {
                   1746:                        Lst_Free(paths);
                   1747:                        paths = NULL;
                   1748:                }
                   1749:                if (specType == SP_PATH)
                   1750:                        Dir_SetPATH();
                   1751:        } else {
                   1752:                assert(paths == NULL);
                   1753:                if (!ParseDoDependencySourcesMundane(line, cp, specType, tOp))
                   1754:                        goto out;
1.1       cgd      1755:        }
1.27      christos 1756:
1.469     rillig   1757:        FindMainTarget();
1.1       cgd      1758:
1.112     christos 1759: out:
1.469     rillig   1760:        if (paths != NULL)
                   1761:                Lst_Free(paths);
                   1762:        Lst_Done(&curTargs);
1.1       cgd      1763: }
                   1764:
1.389     rillig   1765: typedef struct VarAssignParsed {
1.469     rillig   1766:        const char *nameStart;  /* unexpanded */
                   1767:        const char *nameEnd;    /* before operator adjustment */
                   1768:        const char *eq;         /* the '=' of the assignment operator */
1.389     rillig   1769: } VarAssignParsed;
                   1770:
1.469     rillig   1771: /*
                   1772:  * Determine the assignment operator and adjust the end of the variable
                   1773:  * name accordingly.
                   1774:  */
1.388     rillig   1775: static void
1.389     rillig   1776: AdjustVarassignOp(const VarAssignParsed *pvar, const char *value,
                   1777:                  VarAssign *out_var)
1.388     rillig   1778: {
1.469     rillig   1779:        const char *op = pvar->eq;
                   1780:        const char *const name = pvar->nameStart;
                   1781:        VarAssignOp type;
                   1782:
                   1783:        if (op > name && op[-1] == '+') {
                   1784:                type = VAR_APPEND;
                   1785:                op--;
                   1786:
                   1787:        } else if (op > name && op[-1] == '?') {
                   1788:                op--;
                   1789:                type = VAR_DEFAULT;
                   1790:
                   1791:        } else if (op > name && op[-1] == ':') {
                   1792:                op--;
                   1793:                type = VAR_SUBST;
                   1794:
                   1795:        } else if (op > name && op[-1] == '!') {
                   1796:                op--;
                   1797:                type = VAR_SHELL;
1.388     rillig   1798:
1.469     rillig   1799:        } else {
                   1800:                type = VAR_NORMAL;
1.388     rillig   1801: #ifdef SUNSHCMD
1.469     rillig   1802:                while (op > name && ch_isspace(op[-1]))
                   1803:                        op--;
1.388     rillig   1804:
1.469     rillig   1805:                if (op >= name + 3 && op[-3] == ':' && op[-2] == 's' &&
                   1806:                    op[-1] == 'h') {
                   1807:                        type = VAR_SHELL;
                   1808:                        op -= 3;
                   1809:                }
                   1810: #endif
1.388     rillig   1811:        }
                   1812:
1.469     rillig   1813:        {
                   1814:                const char *nameEnd = pvar->nameEnd < op ? pvar->nameEnd : op;
                   1815:                out_var->varname = bmake_strsedup(pvar->nameStart, nameEnd);
                   1816:                out_var->op = type;
                   1817:                out_var->value = value;
                   1818:        }
1.388     rillig   1819: }
                   1820:
1.469     rillig   1821: /*
                   1822:  * Parse a variable assignment, consisting of a single-word variable name,
1.368     rillig   1823:  * optional whitespace, an assignment operator, optional whitespace and the
                   1824:  * variable value.
1.84      wiz      1825:  *
1.410     rillig   1826:  * Note: There is a lexical ambiguity with assignment modifier characters
                   1827:  * in variable names. This routine interprets the character before the =
                   1828:  * as a modifier. Therefore, an assignment like
                   1829:  *     C++=/usr/bin/CC
                   1830:  * is interpreted as "C+ +=" instead of "C++ =".
                   1831:  *
1.469     rillig   1832:  * Used for both lines in a file and command line arguments.
                   1833:  */
1.1       cgd      1834: Boolean
1.368     rillig   1835: Parse_IsVar(const char *p, VarAssign *out_var)
1.1       cgd      1836: {
1.469     rillig   1837:        VarAssignParsed pvar;
                   1838:        const char *firstSpace = NULL;
                   1839:        int level = 0;
                   1840:
                   1841:        cpp_skip_hspace(&p);    /* Skip to variable name */
                   1842:
                   1843:        /*
                   1844:         * During parsing, the '+' of the '+=' operator is initially parsed
                   1845:         * as part of the variable name.  It is later corrected, as is the
                   1846:         * ':sh' modifier. Of these two (nameEnd and op), the earlier one
                   1847:         * determines the actual end of the variable name.
                   1848:         */
                   1849:        pvar.nameStart = p;
1.368     rillig   1850: #ifdef CLEANUP
1.469     rillig   1851:        pvar.nameEnd = NULL;
                   1852:        pvar.eq = NULL;
1.368     rillig   1853: #endif
1.356     rillig   1854:
1.469     rillig   1855:        /*
                   1856:         * Scan for one of the assignment operators outside a variable
                   1857:         * expansion.
                   1858:         */
                   1859:        while (*p != '\0') {
                   1860:                char ch = *p++;
                   1861:                if (ch == '(' || ch == '{') {
                   1862:                        level++;
                   1863:                        continue;
                   1864:                }
                   1865:                if (ch == ')' || ch == '}') {
                   1866:                        level--;
                   1867:                        continue;
                   1868:                }
                   1869:
                   1870:                if (level != 0)
                   1871:                        continue;
                   1872:
                   1873:                if (ch == ' ' || ch == '\t')
                   1874:                        if (firstSpace == NULL)
                   1875:                                firstSpace = p - 1;
                   1876:                while (ch == ' ' || ch == '\t')
                   1877:                        ch = *p++;
1.368     rillig   1878:
1.191     sjg      1879: #ifdef SUNSHCMD
1.469     rillig   1880:                if (ch == ':' && p[0] == 's' && p[1] == 'h') {
                   1881:                        p += 2;
                   1882:                        continue;
                   1883:                }
                   1884: #endif
                   1885:                if (ch == '=') {
                   1886:                        pvar.eq = p - 1;
                   1887:                        pvar.nameEnd = firstSpace != NULL ? firstSpace : p - 1;
                   1888:                        cpp_skip_whitespace(&p);
                   1889:                        AdjustVarassignOp(&pvar, p, out_var);
                   1890:                        return TRUE;
                   1891:                }
                   1892:                if (*p == '=' &&
                   1893:                    (ch == '+' || ch == ':' || ch == '?' || ch == '!')) {
                   1894:                        pvar.eq = p;
                   1895:                        pvar.nameEnd = firstSpace != NULL ? firstSpace : p;
                   1896:                        p++;
                   1897:                        cpp_skip_whitespace(&p);
                   1898:                        AdjustVarassignOp(&pvar, p, out_var);
                   1899:                        return TRUE;
                   1900:                }
                   1901:                if (firstSpace != NULL)
                   1902:                        return FALSE;
1.191     sjg      1903:        }
1.1       cgd      1904:
1.469     rillig   1905:        return FALSE;
1.1       cgd      1906: }
                   1907:
1.469     rillig   1908: /*
                   1909:  * Check for syntax errors such as unclosed expressions or unknown modifiers.
                   1910:  */
1.368     rillig   1911: static void
                   1912: VarCheckSyntax(VarAssignOp type, const char *uvalue, GNode *ctxt)
                   1913: {
1.469     rillig   1914:        if (opts.lint) {
                   1915:                if (type != VAR_SUBST && strchr(uvalue, '$') != NULL) {
                   1916:                        char *expandedValue;
                   1917:
                   1918:                        (void)Var_Subst(uvalue, ctxt, VARE_NONE,
                   1919:                            &expandedValue);
                   1920:                        /* TODO: handle errors */
                   1921:                        free(expandedValue);
                   1922:                }
1.243     sjg      1923:        }
1.368     rillig   1924: }
                   1925:
1.390     rillig   1926: static void
1.391     rillig   1927: VarAssign_EvalSubst(const char *name, const char *uvalue, GNode *ctxt,
1.506     rillig   1928:                    FStr *out_avalue)
1.390     rillig   1929: {
1.469     rillig   1930:        const char *avalue;
                   1931:        char *evalue;
                   1932:        Boolean savedPreserveUndefined = preserveUndefined;
                   1933:
                   1934:        /* TODO: Can this assignment to preserveUndefined be moved further down
                   1935:         * to the actually interesting Var_Subst call, without affecting any
                   1936:         * edge cases?
                   1937:         *
                   1938:         * It might affect the implicit expansion of the variable name in the
                   1939:         * Var_Exists and Var_Set calls, even though it's unlikely that anyone
                   1940:         * cared about this edge case when adding this code.  In addition,
                   1941:         * variable assignments should not refer to any undefined variables in
                   1942:         * the variable name. */
                   1943:        preserveUndefined = TRUE;
                   1944:
                   1945:        /*
                   1946:         * make sure that we set the variable the first time to nothing
                   1947:         * so that it gets substituted!
                   1948:         */
                   1949:        if (!Var_Exists(name, ctxt))
                   1950:                Var_Set(name, "", ctxt);
                   1951:
                   1952:        (void)Var_Subst(uvalue, ctxt, VARE_WANTRES | VARE_KEEP_DOLLAR, &evalue);
                   1953:        /* TODO: handle errors */
                   1954:        preserveUndefined = savedPreserveUndefined;
                   1955:        avalue = evalue;
                   1956:        Var_Set(name, avalue, ctxt);
1.390     rillig   1957:
1.506     rillig   1958:        *out_avalue = (FStr){ avalue, evalue };
1.390     rillig   1959: }
                   1960:
                   1961: static void
1.391     rillig   1962: VarAssign_EvalShell(const char *name, const char *uvalue, GNode *ctxt,
1.506     rillig   1963:                    FStr *out_avalue)
1.390     rillig   1964: {
1.507   ! rillig   1965:        FStr cmd;
        !          1966:        const char *errfmt;
1.469     rillig   1967:        char *cmdOut;
                   1968:
1.507   ! rillig   1969:        cmd = FStr_InitRefer(uvalue);
        !          1970:        if (strchr(cmd.str, '$') != NULL) {
        !          1971:                char *expanded;
        !          1972:                (void)Var_Subst(cmd.str, VAR_CMDLINE,
        !          1973:                    VARE_WANTRES | VARE_UNDEFERR, &expanded);
1.469     rillig   1974:                /* TODO: handle errors */
1.507   ! rillig   1975:                cmd = FStr_InitOwn(expanded);
1.469     rillig   1976:        }
                   1977:
1.507   ! rillig   1978:        cmdOut = Cmd_Exec(cmd.str, &errfmt);
1.469     rillig   1979:        Var_Set(name, cmdOut, ctxt);
1.506     rillig   1980:        *out_avalue = FStr_InitOwn(cmdOut);
1.390     rillig   1981:
1.469     rillig   1982:        if (errfmt != NULL)
                   1983:                Parse_Error(PARSE_WARNING, errfmt, cmd);
1.390     rillig   1984:
1.507   ! rillig   1985:        FStr_Done(&cmd);
1.390     rillig   1986: }
                   1987:
1.391     rillig   1988: /* Perform a variable assignment.
                   1989:  *
                   1990:  * The actual value of the variable is returned in *out_avalue and
                   1991:  * *out_avalue_freeIt.  Especially for VAR_SUBST and VAR_SHELL this can differ
                   1992:  * from the literal value.
                   1993:  *
                   1994:  * Return whether the assignment was actually done.  The assignment is only
                   1995:  * skipped if the operator is '?=' and the variable already exists. */
1.368     rillig   1996: static Boolean
1.391     rillig   1997: VarAssign_Eval(const char *name, VarAssignOp op, const char *uvalue,
1.506     rillig   1998:               GNode *ctxt, FStr *out_TRUE_avalue)
1.368     rillig   1999: {
1.506     rillig   2000:        FStr avalue = FStr_InitRefer(uvalue);
1.469     rillig   2001:
                   2002:        if (op == VAR_APPEND)
                   2003:                Var_Append(name, uvalue, ctxt);
                   2004:        else if (op == VAR_SUBST)
1.506     rillig   2005:                VarAssign_EvalSubst(name, uvalue, ctxt, &avalue);
1.469     rillig   2006:        else if (op == VAR_SHELL)
1.506     rillig   2007:                VarAssign_EvalShell(name, uvalue, ctxt, &avalue);
1.469     rillig   2008:        else {
1.506     rillig   2009:                if (op == VAR_DEFAULT && Var_Exists(name, ctxt))
1.469     rillig   2010:                        return FALSE;
1.353     rillig   2011:
1.469     rillig   2012:                /* Normal assignment -- just do it. */
                   2013:                Var_Set(name, uvalue, ctxt);
                   2014:        }
                   2015:
1.506     rillig   2016:        *out_TRUE_avalue = avalue;
1.469     rillig   2017:        return TRUE;
1.368     rillig   2018: }
                   2019:
                   2020: static void
                   2021: VarAssignSpecial(const char *name, const char *avalue)
                   2022: {
1.469     rillig   2023:        if (strcmp(name, MAKEOVERRIDES) == 0)
                   2024:                Main_ExportMAKEFLAGS(FALSE); /* re-export MAKEFLAGS */
                   2025:        else if (strcmp(name, ".CURDIR") == 0) {
                   2026:                /*
                   2027:                 * Someone is being (too?) clever...
                   2028:                 * Let's pretend they know what they are doing and
                   2029:                 * re-initialize the 'cur' CachedDir.
                   2030:                 */
                   2031:                Dir_InitCur(avalue);
                   2032:                Dir_SetPATH();
                   2033:        } else if (strcmp(name, MAKE_JOB_PREFIX) == 0)
                   2034:                Job_SetPrefix();
                   2035:        else if (strcmp(name, MAKE_EXPORTED) == 0)
1.473     rillig   2036:                Var_ExportVars(avalue);
1.368     rillig   2037: }
                   2038:
1.410     rillig   2039: /* Perform the variable variable assignment in the given context. */
1.368     rillig   2040: void
                   2041: Parse_DoVar(VarAssign *var, GNode *ctxt)
                   2042: {
1.506     rillig   2043:        FStr avalue;    /* actual value (maybe expanded) */
1.368     rillig   2044:
1.469     rillig   2045:        VarCheckSyntax(var->op, var->value, ctxt);
1.506     rillig   2046:        if (VarAssign_Eval(var->varname, var->op, var->value, ctxt, &avalue)) {
                   2047:                VarAssignSpecial(var->varname, avalue.str);
                   2048:                FStr_Done(&avalue);
                   2049:        }
1.368     rillig   2050:
1.469     rillig   2051:        free(var->varname);
1.1       cgd      2052: }
1.23      christos 2053:
1.200     christos 2054:
1.432     rillig   2055: /* See if the command possibly calls a sub-make by using the variable
                   2056:  * expressions ${.MAKE}, ${MAKE} or the plain word "make". */
1.195     christos 2057: static Boolean
1.432     rillig   2058: MaybeSubMake(const char *cmd)
1.195     christos 2059: {
1.469     rillig   2060:        const char *start;
1.432     rillig   2061:
1.469     rillig   2062:        for (start = cmd; *start != '\0'; start++) {
                   2063:                const char *p = start;
                   2064:                char endc;
                   2065:
                   2066:                /* XXX: What if progname != "make"? */
                   2067:                if (p[0] == 'm' && p[1] == 'a' && p[2] == 'k' && p[3] == 'e')
                   2068:                        if (start == cmd || !ch_isalnum(p[-1]))
                   2069:                                if (!ch_isalnum(p[4]))
                   2070:                                        return TRUE;
                   2071:
                   2072:                if (*p != '$')
                   2073:                        continue;
                   2074:                p++;
                   2075:
                   2076:                if (*p == '{')
                   2077:                        endc = '}';
                   2078:                else if (*p == '(')
                   2079:                        endc = ')';
                   2080:                else
                   2081:                        continue;
                   2082:                p++;
1.432     rillig   2083:
1.469     rillig   2084:                if (*p == '.')  /* Accept either ${.MAKE} or ${MAKE}. */
                   2085:                        p++;
1.432     rillig   2086:
1.469     rillig   2087:                if (p[0] == 'M' && p[1] == 'A' && p[2] == 'K' && p[3] == 'E')
                   2088:                        if (p[4] == endc)
                   2089:                                return TRUE;
                   2090:        }
                   2091:        return FALSE;
1.195     christos 2092: }
                   2093:
1.327     rillig   2094: /* Append the command to the target node.
1.1       cgd      2095:  *
1.327     rillig   2096:  * The node may be marked as a submake node if the command is determined to
                   2097:  * be that. */
                   2098: static void
                   2099: ParseAddCmd(GNode *gn, char *cmd)
1.9       jtc      2100: {
1.469     rillig   2101:        /* Add to last (ie current) cohort for :: targets */
                   2102:        if ((gn->type & OP_DOUBLEDEP) && gn->cohorts.last != NULL)
                   2103:                gn = gn->cohorts.last->datum;
                   2104:
                   2105:        /* if target already supplied, ignore commands */
                   2106:        if (!(gn->type & OP_HAS_COMMANDS)) {
                   2107:                Lst_Append(&gn->commands, cmd);
                   2108:                if (MaybeSubMake(cmd))
                   2109:                        gn->type |= OP_SUBMAKE;
                   2110:                ParseMark(gn);
                   2111:        } else {
1.327     rillig   2112: #if 0
1.469     rillig   2113:                /* XXX: We cannot do this until we fix the tree */
                   2114:                Lst_Append(&gn->commands, cmd);
                   2115:                Parse_Error(PARSE_WARNING,
                   2116:                    "overriding commands for target \"%s\"; "
                   2117:                    "previous commands defined at %s: %d ignored",
                   2118:                    gn->name, gn->fname, gn->lineno);
1.203     joerg    2119: #else
1.469     rillig   2120:                Parse_Error(PARSE_WARNING,
1.374     rillig   2121:                    "duplicate script for target \"%s\" ignored",
                   2122:                    gn->name);
1.469     rillig   2123:                ParseErrorInternal(gn->fname, (size_t)gn->lineno, PARSE_WARNING,
                   2124:                    "using previous script for \"%s\" defined here",
                   2125:                    gn->name);
1.203     joerg    2126: #endif
1.469     rillig   2127:        }
1.1       cgd      2128: }
                   2129:
1.469     rillig   2130: /*
                   2131:  * Add a directory to the path searched for included makefiles bracketed
                   2132:  * by double-quotes.
                   2133:  */
1.1       cgd      2134: void
1.344     rillig   2135: Parse_AddIncludeDir(const char *dir)
1.1       cgd      2136: {
1.469     rillig   2137:        (void)Dir_AddDir(parseIncPath, dir);
1.1       cgd      2138: }
                   2139:
1.441     rillig   2140: /* Handle one of the .[-ds]include directives by remembering the current file
                   2141:  * and pushing the included file on the stack.  After the included file has
                   2142:  * finished, parsing continues with the including file; see Parse_SetInput
                   2143:  * and ParseEOF.
                   2144:  *
                   2145:  * System includes are looked up in sysIncPath, any other includes are looked
                   2146:  * up in the parsedir and then in the directories specified by the -I command
                   2147:  * line options.
1.1       cgd      2148:  */
                   2149: static void
1.434     rillig   2150: Parse_include_file(char *file, Boolean isSystem, Boolean depinc, Boolean silent)
1.1       cgd      2151: {
1.469     rillig   2152:        struct loadedfile *lf;
                   2153:        char *fullname;         /* full pathname of file */
                   2154:        char *newName;
                   2155:        char *slash, *incdir;
                   2156:        int fd;
                   2157:        int i;
                   2158:
                   2159:        fullname = file[0] == '/' ? bmake_strdup(file) : NULL;
                   2160:
                   2161:        if (fullname == NULL && !isSystem) {
                   2162:                /*
                   2163:                 * Include files contained in double-quotes are first searched
                   2164:                 * relative to the including file's location. We don't want to
                   2165:                 * cd there, of course, so we just tack on the old file's
                   2166:                 * leading path components and call Dir_FindFile to see if
                   2167:                 * we can locate the file.
                   2168:                 */
                   2169:
                   2170:                incdir = bmake_strdup(CurFile()->fname);
                   2171:                slash = strrchr(incdir, '/');
                   2172:                if (slash != NULL) {
                   2173:                        *slash = '\0';
                   2174:                        /*
                   2175:                         * Now do lexical processing of leading "../" on the
                   2176:                         * filename.
                   2177:                         */
                   2178:                        for (i = 0; strncmp(file + i, "../", 3) == 0; i += 3) {
                   2179:                                slash = strrchr(incdir + 1, '/');
                   2180:                                if (slash == NULL || strcmp(slash, "/..") == 0)
                   2181:                                        break;
                   2182:                                *slash = '\0';
                   2183:                        }
                   2184:                        newName = str_concat3(incdir, "/", file + i);
                   2185:                        fullname = Dir_FindFile(newName, parseIncPath);
                   2186:                        if (fullname == NULL)
                   2187:                                fullname = Dir_FindFile(newName,
                   2188:                                    &dirSearchPath);
                   2189:                        free(newName);
                   2190:                }
                   2191:                free(incdir);
                   2192:
                   2193:                if (fullname == NULL) {
                   2194:                        /*
                   2195:                         * Makefile wasn't found in same directory as included
                   2196:                         * makefile.
                   2197:                         *
                   2198:                         * Search for it first on the -I search path, then on
                   2199:                         * the .PATH search path, if not found in a -I
                   2200:                         * directory. If we have a suffix-specific path, we
                   2201:                         * should use that.
                   2202:                         */
                   2203:                        const char *suff;
                   2204:                        SearchPath *suffPath = NULL;
                   2205:
                   2206:                        if ((suff = strrchr(file, '.'))) {
                   2207:                                suffPath = Suff_GetPath(suff);
                   2208:                                if (suffPath != NULL)
                   2209:                                        fullname = Dir_FindFile(file, suffPath);
                   2210:                        }
                   2211:                        if (fullname == NULL) {
                   2212:                                fullname = Dir_FindFile(file, parseIncPath);
                   2213:                                if (fullname == NULL)
                   2214:                                        fullname = Dir_FindFile(file,
                   2215:                                            &dirSearchPath);
                   2216:                        }
                   2217:                }
1.1       cgd      2218:        }
1.140     dsl      2219:
1.469     rillig   2220:        /* Looking for a system file or file still not found */
1.142     sjg      2221:        if (fullname == NULL) {
1.469     rillig   2222:                /*
                   2223:                 * Look for it on the system path
                   2224:                 */
                   2225:                SearchPath *path = Lst_IsEmpty(sysIncPath) ? defSysIncPath
                   2226:                    : sysIncPath;
                   2227:                fullname = Dir_FindFile(file, path);
                   2228:        }
                   2229:
                   2230:        if (fullname == NULL) {
                   2231:                if (!silent)
                   2232:                        Parse_Error(PARSE_FATAL, "Could not find %s", file);
                   2233:                return;
                   2234:        }
                   2235:
                   2236:        /* Actually open the file... */
                   2237:        fd = open(fullname, O_RDONLY);
                   2238:        if (fd == -1) {
                   2239:                if (!silent)
                   2240:                        Parse_Error(PARSE_FATAL, "Cannot open %s", fullname);
                   2241:                free(fullname);
                   2242:                return;
                   2243:        }
                   2244:
                   2245:        /* load it */
                   2246:        lf = loadfile(fullname, fd);
                   2247:
                   2248:        /* Start reading from this file next */
1.471     rillig   2249:        Parse_SetInput(fullname, 0, -1, loadedfile_readMore, lf);
1.469     rillig   2250:        CurFile()->lf = lf;
                   2251:        if (depinc)
                   2252:                doing_depend = depinc;  /* only turn it on */
1.123     dsl      2253: }
                   2254:
                   2255: static void
1.478     rillig   2256: ParseDoInclude(char *line /* XXX: bad name */)
1.123     dsl      2257: {
1.469     rillig   2258:        char endc;              /* the character which ends the file spec */
                   2259:        char *cp;               /* current position in file spec */
1.478     rillig   2260:        Boolean silent = line[0] != 'i';
1.469     rillig   2261:        char *file = line + (silent ? 8 : 7);
1.123     dsl      2262:
1.469     rillig   2263:        /* Skip to delimiter character so we know where to look */
                   2264:        pp_skip_hspace(&file);
1.123     dsl      2265:
1.469     rillig   2266:        if (*file != '"' && *file != '<') {
                   2267:                Parse_Error(PARSE_FATAL,
1.374     rillig   2268:                    ".include filename must be delimited by '\"' or '<'");
1.469     rillig   2269:                return;
                   2270:        }
1.123     dsl      2271:
1.469     rillig   2272:        /*
                   2273:         * Set the search path on which to find the include file based on the
                   2274:         * characters which bracket its name. Angle-brackets imply it's
                   2275:         * a system Makefile while double-quotes imply it's a user makefile
                   2276:         */
                   2277:        if (*file == '<')
                   2278:                endc = '>';
                   2279:        else
                   2280:                endc = '"';
                   2281:
                   2282:        /* Skip to matching delimiter */
                   2283:        for (cp = ++file; *cp && *cp != endc; cp++)
                   2284:                continue;
1.123     dsl      2285:
1.469     rillig   2286:        if (*cp != endc) {
                   2287:                Parse_Error(PARSE_FATAL,
1.441     rillig   2288:                    "Unclosed .include filename. '%c' expected", endc);
1.469     rillig   2289:                return;
                   2290:        }
1.430     rillig   2291:
1.469     rillig   2292:        *cp = '\0';
1.123     dsl      2293:
1.469     rillig   2294:        /*
                   2295:         * Substitute for any variables in the filename before trying to
                   2296:         * find the file.
                   2297:         */
                   2298:        (void)Var_Subst(file, VAR_CMDLINE, VARE_WANTRES, &file);
                   2299:        /* TODO: handle errors */
1.123     dsl      2300:
1.478     rillig   2301:        Parse_include_file(file, endc == '>', line[0] == 'd', silent);
1.469     rillig   2302:        free(file);
1.1       cgd      2303: }
                   2304:
1.281     rillig   2305: /* Split filename into dirname + basename, then assign these to the
                   2306:  * given variables. */
1.193     christos 2307: static void
1.281     rillig   2308: SetFilenameVars(const char *filename, const char *dirvar, const char *filevar)
1.193     christos 2309: {
1.469     rillig   2310:        const char *slash, *dirname, *basename;
                   2311:        void *freeIt;
                   2312:
                   2313:        slash = strrchr(filename, '/');
                   2314:        if (slash == NULL) {
                   2315:                dirname = curdir;
                   2316:                basename = filename;
                   2317:                freeIt = NULL;
                   2318:        } else {
                   2319:                dirname = freeIt = bmake_strsedup(filename, slash);
                   2320:                basename = slash + 1;
                   2321:        }
1.281     rillig   2322:
1.469     rillig   2323:        Var_Set(dirvar, dirname, VAR_GLOBAL);
                   2324:        Var_Set(filevar, basename, VAR_GLOBAL);
                   2325:
                   2326:        DEBUG5(PARSE, "%s: ${%s} = `%s' ${%s} = `%s'\n",
                   2327:            __func__, dirvar, dirname, filevar, basename);
                   2328:        free(freeIt);
1.281     rillig   2329: }
                   2330:
1.469     rillig   2331: /*
                   2332:  * Return the immediately including file.
1.281     rillig   2333:  *
                   2334:  * This is made complicated since the .for loop is implemented as a special
1.469     rillig   2335:  * kind of .include; see For_Run.
                   2336:  */
1.281     rillig   2337: static const char *
                   2338: GetActuallyIncludingFile(void)
                   2339: {
1.469     rillig   2340:        size_t i;
                   2341:        const IFile *incs = GetInclude(0);
1.193     christos 2342:
1.469     rillig   2343:        for (i = includes.len; i >= 2; i--)
                   2344:                if (!incs[i - 1].fromForLoop)
                   2345:                        return incs[i - 2].fname;
                   2346:        return NULL;
1.193     christos 2347: }
1.281     rillig   2348:
1.285     rillig   2349: /* Set .PARSEDIR, .PARSEFILE, .INCLUDEDFROMDIR and .INCLUDEDFROMFILE. */
1.44      aidan    2350: static void
1.122     dsl      2351: ParseSetParseFile(const char *filename)
1.44      aidan    2352: {
1.469     rillig   2353:        const char *including;
1.44      aidan    2354:
1.469     rillig   2355:        SetFilenameVars(filename, ".PARSEDIR", ".PARSEFILE");
1.281     rillig   2356:
1.469     rillig   2357:        including = GetActuallyIncludingFile();
                   2358:        if (including != NULL) {
                   2359:                SetFilenameVars(including,
                   2360:                    ".INCLUDEDFROMDIR", ".INCLUDEDFROMFILE");
                   2361:        } else {
                   2362:                Var_Delete(".INCLUDEDFROMDIR", VAR_GLOBAL);
                   2363:                Var_Delete(".INCLUDEDFROMFILE", VAR_GLOBAL);
                   2364:        }
1.44      aidan    2365: }
                   2366:
1.418     rillig   2367: static Boolean
                   2368: StrContainsWord(const char *str, const char *word)
                   2369: {
1.469     rillig   2370:        size_t strLen = strlen(str);
                   2371:        size_t wordLen = strlen(word);
                   2372:        const char *p, *end;
                   2373:
                   2374:        if (strLen < wordLen)
                   2375:                return FALSE;   /* str is too short to contain word */
                   2376:
                   2377:        end = str + strLen - wordLen;
                   2378:        for (p = str; p != NULL; p = strchr(p, ' ')) {
                   2379:                if (*p == ' ')
                   2380:                        p++;
                   2381:                if (p > end)
                   2382:                        return FALSE;   /* cannot contain word */
                   2383:
                   2384:                if (memcmp(p, word, wordLen) == 0 &&
                   2385:                    (p[wordLen] == '\0' || p[wordLen] == ' '))
                   2386:                        return TRUE;
                   2387:        }
                   2388:        return FALSE;
                   2389: }
                   2390:
                   2391: /*
                   2392:  * XXX: Searching through a set of words with this linear search is
                   2393:  * inefficient for variables that contain thousands of words.
                   2394:  *
                   2395:  * XXX: The paths in this list don't seem to be normalized in any way.
                   2396:  */
1.418     rillig   2397: static Boolean
                   2398: VarContainsWord(const char *varname, const char *word)
                   2399: {
1.505     rillig   2400:        FStr val = Var_Value(varname, VAR_GLOBAL);
                   2401:        Boolean found = val.str != NULL && StrContainsWord(val.str, word);
                   2402:        FStr_Done(&val);
1.469     rillig   2403:        return found;
1.418     rillig   2404: }
                   2405:
1.284     rillig   2406: /* Track the makefiles we read - so makefiles can set dependencies on them.
1.441     rillig   2407:  * Avoid adding anything more than once.
                   2408:  *
                   2409:  * Time complexity: O(n) per call, in total O(n^2), where n is the number
                   2410:  * of makefiles that have been loaded. */
1.184     sjg      2411: static void
                   2412: ParseTrackInput(const char *name)
                   2413: {
1.469     rillig   2414:        if (!VarContainsWord(MAKE_MAKEFILES, name))
                   2415:                Var_Append(MAKE_MAKEFILES, name, VAR_GLOBAL);
1.184     sjg      2416: }
1.137     sjg      2417:
1.44      aidan    2418:
1.469     rillig   2419: /*
                   2420:  * Start parsing from the given source.
1.5       cgd      2421:  *
1.469     rillig   2422:  * The given file is added to the includes stack.
                   2423:  */
1.5       cgd      2424: void
1.496     rillig   2425: Parse_SetInput(const char *name, int lineno, int fd,
1.471     rillig   2426:               ReadMoreProc readMore, void *readMoreArg)
1.5       cgd      2427: {
1.469     rillig   2428:        IFile *curFile;
                   2429:        char *buf;
                   2430:        size_t len;
                   2431:        Boolean fromForLoop = name == NULL;
                   2432:
                   2433:        if (fromForLoop)
                   2434:                name = CurFile()->fname;
                   2435:        else
                   2436:                ParseTrackInput(name);
                   2437:
1.497     rillig   2438:        DEBUG3(PARSE, "Parse_SetInput: %s %s, line %d\n",
                   2439:            readMore == loadedfile_readMore ? "file" : ".for loop in",
                   2440:            name, lineno);
1.5       cgd      2441:
1.471     rillig   2442:        if (fd == -1 && readMore == NULL)
1.469     rillig   2443:                /* sanity */
                   2444:                return;
                   2445:
                   2446:        curFile = Vector_Push(&includes);
                   2447:        curFile->fname = bmake_strdup(name);
                   2448:        curFile->fromForLoop = fromForLoop;
1.496     rillig   2449:        curFile->lineno = lineno;
                   2450:        curFile->first_lineno = lineno;
1.471     rillig   2451:        curFile->readMore = readMore;
                   2452:        curFile->readMoreArg = readMoreArg;
1.469     rillig   2453:        curFile->lf = NULL;
                   2454:        curFile->depending = doing_depend;      /* restore this on EOF */
                   2455:
1.471     rillig   2456:        assert(readMore != NULL);
1.469     rillig   2457:
                   2458:        /* Get first block of input data */
1.471     rillig   2459:        buf = curFile->readMore(curFile->readMoreArg, &len);
1.469     rillig   2460:        if (buf == NULL) {
                   2461:                /* Was all a waste of time ... */
                   2462:                if (curFile->fname)
                   2463:                        free(curFile->fname);
                   2464:                free(curFile);
                   2465:                return;
                   2466:        }
                   2467:        curFile->buf_freeIt = buf;
                   2468:        curFile->buf_ptr = buf;
                   2469:        curFile->buf_end = buf + len;
                   2470:
                   2471:        curFile->cond_depth = Cond_save_depth();
                   2472:        ParseSetParseFile(name);
1.5       cgd      2473: }
                   2474:
1.375     rillig   2475: /* Check if the directive is an include directive. */
1.228     christos 2476: static Boolean
1.298     rillig   2477: IsInclude(const char *dir, Boolean sysv)
1.228     christos 2478: {
1.298     rillig   2479:        if (dir[0] == 's' || dir[0] == '-' || (dir[0] == 'd' && !sysv))
                   2480:                dir++;
1.228     christos 2481:
1.298     rillig   2482:        if (strncmp(dir, "include", 7) != 0)
1.228     christos 2483:                return FALSE;
                   2484:
1.248     rillig   2485:        /* Space is not mandatory for BSD .include */
1.298     rillig   2486:        return !sysv || ch_isspace(dir[7]);
1.228     christos 2487: }
                   2488:
                   2489:
1.5       cgd      2490: #ifdef SYSVINCLUDE
1.284     rillig   2491: /* Check if the line is a SYSV include directive. */
1.228     christos 2492: static Boolean
                   2493: IsSysVInclude(const char *line)
                   2494: {
                   2495:        const char *p;
                   2496:
                   2497:        if (!IsInclude(line, TRUE))
                   2498:                return FALSE;
                   2499:
1.375     rillig   2500:        /* Avoid interpreting a dependency line as an include */
1.228     christos 2501:        for (p = line; (p = strchr(p, ':')) != NULL;) {
1.430     rillig   2502:
                   2503:                /* end of line -> it's a dependency */
                   2504:                if (*++p == '\0')
1.228     christos 2505:                        return FALSE;
1.430     rillig   2506:
                   2507:                /* '::' operator or ': ' -> it's a dependency */
                   2508:                if (*p == ':' || ch_isspace(*p))
1.228     christos 2509:                        return FALSE;
                   2510:        }
                   2511:        return TRUE;
                   2512: }
                   2513:
1.284     rillig   2514: /* Push to another file.  The line points to the word "include". */
1.5       cgd      2515: static void
1.84      wiz      2516: ParseTraditionalInclude(char *line)
1.5       cgd      2517: {
1.469     rillig   2518:        char *cp;               /* current position in file spec */
                   2519:        Boolean done = FALSE;
                   2520:        Boolean silent = line[0] != 'i';
                   2521:        char *file = line + (silent ? 8 : 7);
                   2522:        char *all_files;
                   2523:
                   2524:        DEBUG2(PARSE, "%s: %s\n", __func__, file);
                   2525:
                   2526:        pp_skip_whitespace(&file);
                   2527:
                   2528:        /*
                   2529:         * Substitute for any variables in the file name before trying to
                   2530:         * find the thing.
                   2531:         */
                   2532:        (void)Var_Subst(file, VAR_CMDLINE, VARE_WANTRES, &all_files);
                   2533:        /* TODO: handle errors */
                   2534:
                   2535:        if (*file == '\0') {
                   2536:                Parse_Error(PARSE_FATAL, "Filename missing from \"include\"");
                   2537:                goto out;
                   2538:        }
1.38      christos 2539:
1.469     rillig   2540:        for (file = all_files; !done; file = cp + 1) {
                   2541:                /* Skip to end of line or next whitespace */
                   2542:                for (cp = file; *cp != '\0' && !ch_isspace(*cp); cp++)
                   2543:                        continue;
                   2544:
                   2545:                if (*cp != '\0')
                   2546:                        *cp = '\0';
                   2547:                else
                   2548:                        done = TRUE;
1.38      christos 2549:
1.469     rillig   2550:                Parse_include_file(file, FALSE, FALSE, silent);
                   2551:        }
1.224     riastrad 2552: out:
1.469     rillig   2553:        free(all_files);
1.5       cgd      2554: }
                   2555: #endif
                   2556:
1.183     sjg      2557: #ifdef GMAKEEXPORT
1.375     rillig   2558: /* Parse "export <variable>=<value>", and actually export it. */
1.182     christos 2559: static void
                   2560: ParseGmakeExport(char *line)
                   2561: {
1.469     rillig   2562:        char *variable = line + 6;
                   2563:        char *value;
1.182     christos 2564:
1.469     rillig   2565:        DEBUG2(PARSE, "%s: %s\n", __func__, variable);
1.182     christos 2566:
1.469     rillig   2567:        pp_skip_whitespace(&variable);
1.182     christos 2568:
1.469     rillig   2569:        for (value = variable; *value && *value != '='; value++)
                   2570:                continue;
1.182     christos 2571:
1.469     rillig   2572:        if (*value != '=') {
                   2573:                Parse_Error(PARSE_FATAL,
1.284     rillig   2574:                    "Variable/Value missing from \"export\"");
1.469     rillig   2575:                return;
                   2576:        }
                   2577:        *value++ = '\0';        /* terminate variable */
1.323     rillig   2578:
1.469     rillig   2579:        /*
                   2580:         * Expand the value before putting it in the environment.
                   2581:         */
                   2582:        (void)Var_Subst(value, VAR_CMDLINE, VARE_WANTRES, &value);
                   2583:        /* TODO: handle errors */
                   2584:
                   2585:        setenv(variable, value, 1);
                   2586:        free(value);
1.182     christos 2587: }
                   2588: #endif
                   2589:
1.469     rillig   2590: /*
                   2591:  * Called when EOF is reached in the current file. If we were reading an
1.441     rillig   2592:  * include file or a .for loop, the includes stack is popped and things set
                   2593:  * up to go back to reading the previous file at the previous location.
1.1       cgd      2594:  *
                   2595:  * Results:
1.376     rillig   2596:  *     TRUE to continue parsing, i.e. it had only reached the end of an
                   2597:  *     included file, FALSE if the main file has been parsed completely.
1.1       cgd      2598:  */
1.376     rillig   2599: static Boolean
1.123     dsl      2600: ParseEOF(void)
1.1       cgd      2601: {
1.469     rillig   2602:        char *ptr;
                   2603:        size_t len;
                   2604:        IFile *curFile = CurFile();
                   2605:
1.471     rillig   2606:        assert(curFile->readMore != NULL);
1.469     rillig   2607:
                   2608:        doing_depend = curFile->depending;      /* restore this */
                   2609:        /* get next input buffer, if any */
1.471     rillig   2610:        ptr = curFile->readMore(curFile->readMoreArg, &len);
1.469     rillig   2611:        curFile->buf_ptr = ptr;
                   2612:        curFile->buf_freeIt = ptr;
1.470     rillig   2613:        curFile->buf_end = ptr == NULL ? NULL : ptr + len;
1.469     rillig   2614:        curFile->lineno = curFile->first_lineno;
                   2615:        if (ptr != NULL)
                   2616:                return TRUE;    /* Iterate again */
                   2617:
                   2618:        /* Ensure the makefile (or loop) didn't have mismatched conditionals */
                   2619:        Cond_restore_depth(curFile->cond_depth);
                   2620:
                   2621:        if (curFile->lf != NULL) {
                   2622:                loadedfile_destroy(curFile->lf);
                   2623:                curFile->lf = NULL;
                   2624:        }
                   2625:
                   2626:        /* Dispose of curFile info */
                   2627:        /* Leak curFile->fname because all the gnodes have pointers to it. */
                   2628:        free(curFile->buf_freeIt);
                   2629:        Vector_Pop(&includes);
1.155     dsl      2630:
1.469     rillig   2631:        if (includes.len == 0) {
                   2632:                /* We've run out of input */
                   2633:                Var_Delete(".PARSEDIR", VAR_GLOBAL);
                   2634:                Var_Delete(".PARSEFILE", VAR_GLOBAL);
                   2635:                Var_Delete(".INCLUDEDFROMDIR", VAR_GLOBAL);
                   2636:                Var_Delete(".INCLUDEDFROMFILE", VAR_GLOBAL);
                   2637:                return FALSE;
                   2638:        }
1.170     dholland 2639:
1.469     rillig   2640:        curFile = CurFile();
                   2641:        DEBUG2(PARSE, "ParseEOF: returning to file %s, line %d\n",
                   2642:            curFile->fname, curFile->lineno);
1.1       cgd      2643:
1.469     rillig   2644:        ParseSetParseFile(curFile->fname);
                   2645:        return TRUE;
1.1       cgd      2646: }
                   2647:
1.493     rillig   2648: typedef enum ParseRawLineResult {
                   2649:        PRLR_LINE,
                   2650:        PRLR_EOF,
                   2651:        PRLR_ERROR
                   2652: } ParseRawLineResult;
                   2653:
1.489     rillig   2654: /*
1.492     rillig   2655:  * Parse until the end of a line, taking into account lines that end with
                   2656:  * backslash-newline.
1.489     rillig   2657:  */
1.493     rillig   2658: static ParseRawLineResult
                   2659: ParseRawLine(IFile *curFile, char **out_line, char **out_line_end,
                   2660:             char **out_firstBackslash, char **out_firstComment)
1.489     rillig   2661: {
1.493     rillig   2662:        char *line = curFile->buf_ptr;
1.492     rillig   2663:        char *p = line;
1.489     rillig   2664:        char *line_end = line;
1.492     rillig   2665:        char *firstBackslash = NULL;
                   2666:        char *firstComment = NULL;
1.493     rillig   2667:        ParseRawLineResult res = PRLR_LINE;
1.489     rillig   2668:
1.493     rillig   2669:        curFile->lineno++;
1.490     rillig   2670:
1.489     rillig   2671:        for (;;) {
1.492     rillig   2672:                char ch;
                   2673:
1.493     rillig   2674:                if (p == curFile->buf_end) {
                   2675:                        res = PRLR_EOF;
1.489     rillig   2676:                        break;
                   2677:                }
                   2678:
1.492     rillig   2679:                ch = *p;
1.489     rillig   2680:                if (ch == '\0' ||
1.493     rillig   2681:                    (ch == '\\' && p + 1 < curFile->buf_end && p[1] == '\0')) {
1.492     rillig   2682:                        Parse_Error(PARSE_FATAL, "Zero byte read from file");
1.493     rillig   2683:                        return PRLR_ERROR;
1.489     rillig   2684:                }
                   2685:
1.492     rillig   2686:                /* Treat next character after '\' as literal. */
1.489     rillig   2687:                if (ch == '\\') {
1.492     rillig   2688:                        if (firstBackslash == NULL)
                   2689:                                firstBackslash = p;
                   2690:                        if (p[1] == '\n')
1.493     rillig   2691:                                curFile->lineno++;
1.492     rillig   2692:                        p += 2;
                   2693:                        line_end = p;
1.489     rillig   2694:                        continue;
                   2695:                }
                   2696:
                   2697:                /*
1.492     rillig   2698:                 * Remember the first '#' for comment stripping, unless
                   2699:                 * the previous char was '[', as in the modifier ':[#]'.
                   2700:                 */
                   2701:                if (ch == '#' && firstComment == NULL &&
                   2702:                    !(p > line && p[-1] == '['))
                   2703:                        firstComment = line_end;
1.489     rillig   2704:
1.492     rillig   2705:                p++;
1.489     rillig   2706:                if (ch == '\n')
                   2707:                        break;
                   2708:
                   2709:                /* We are not interested in trailing whitespace. */
                   2710:                if (!ch_isspace(ch))
1.492     rillig   2711:                        line_end = p;
1.489     rillig   2712:        }
                   2713:
1.490     rillig   2714:        *out_line = line;
1.493     rillig   2715:        curFile->buf_ptr = p;
1.489     rillig   2716:        *out_line_end = line_end;
1.492     rillig   2717:        *out_firstBackslash = firstBackslash;
                   2718:        *out_firstComment = firstComment;
1.493     rillig   2719:        return res;
1.489     rillig   2720: }
                   2721:
1.491     rillig   2722: /*
                   2723:  * Beginning at start, unescape '\#' to '#' and replace backslash-newline
                   2724:  * with a single space.
                   2725:  */
1.485     rillig   2726: static void
1.491     rillig   2727: UnescapeBackslash(char *const line, char *start)
1.487     rillig   2728: {
1.491     rillig   2729:        char *src = start;
                   2730:        char *dst = start;
                   2731:        char *spaceStart = line;
1.485     rillig   2732:
                   2733:        for (;;) {
1.491     rillig   2734:                char ch = *src++;
1.485     rillig   2735:                if (ch != '\\') {
                   2736:                        if (ch == '\0')
                   2737:                                break;
1.491     rillig   2738:                        *dst++ = ch;
1.485     rillig   2739:                        continue;
                   2740:                }
                   2741:
1.491     rillig   2742:                ch = *src++;
1.485     rillig   2743:                if (ch == '\0') {
                   2744:                        /* Delete '\\' at end of buffer */
1.491     rillig   2745:                        dst--;
1.485     rillig   2746:                        break;
                   2747:                }
                   2748:
                   2749:                /* Delete '\\' from before '#' on non-command lines */
                   2750:                if (ch == '#' && line[0] != '\t') {
1.491     rillig   2751:                        *dst++ = ch;
1.485     rillig   2752:                        continue;
                   2753:                }
                   2754:
                   2755:                if (ch != '\n') {
                   2756:                        /* Leave '\\' in buffer for later */
1.491     rillig   2757:                        *dst++ = '\\';
1.485     rillig   2758:                        /*
                   2759:                         * Make sure we don't delete an escaped ' ' from the
                   2760:                         * line end.
                   2761:                         */
1.491     rillig   2762:                        spaceStart = dst + 1;
                   2763:                        *dst++ = ch;
1.485     rillig   2764:                        continue;
                   2765:                }
                   2766:
                   2767:                /*
                   2768:                 * Escaped '\n' -- replace following whitespace with a single
                   2769:                 * ' '.
                   2770:                 */
1.491     rillig   2771:                pp_skip_hspace(&src);
                   2772:                *dst++ = ' ';
1.485     rillig   2773:        }
                   2774:
1.487     rillig   2775:        /* Delete any trailing spaces - eg from empty continuations */
1.491     rillig   2776:        while (dst > spaceStart && ch_isspace(dst[-1]))
                   2777:                dst--;
                   2778:        *dst = '\0';
1.485     rillig   2779: }
                   2780:
1.441     rillig   2781: typedef enum GetLineMode {
1.495     rillig   2782:        /*
1.498     rillig   2783:         * Return the next line that is neither empty nor a comment.
1.495     rillig   2784:         * Backslash line continuations are folded into a single space.
                   2785:         * A trailing comment, if any, is discarded.
                   2786:         */
1.499     rillig   2787:        GLM_NONEMPTY,
1.495     rillig   2788:
                   2789:        /*
1.498     rillig   2790:         * Return the next line, even if it is empty or a comment.
1.499     rillig   2791:         * Preserve backslash-newline to keep the line numbers correct.
1.495     rillig   2792:         *
                   2793:         * Used in .for loops to collect the body of the loop while waiting
                   2794:         * for the corresponding .endfor.
                   2795:         */
1.499     rillig   2796:        GLM_FOR_BODY,
1.495     rillig   2797:
                   2798:        /*
1.499     rillig   2799:         * Return the next line that starts with a dot.
1.495     rillig   2800:         * Backslash line continuations are folded into a single space.
                   2801:         * A trailing comment, if any, is discarded.
                   2802:         *
                   2803:         * Used in .if directives to skip over irrelevant branches while
                   2804:         * waiting for the corresponding .endif.
                   2805:         */
1.499     rillig   2806:        GLM_DOT
1.441     rillig   2807: } GetLineMode;
1.127     dsl      2808:
1.498     rillig   2809: /* Return the next "interesting" logical line from the current file. */
1.127     dsl      2810: static char *
1.441     rillig   2811: ParseGetLine(GetLineMode mode)
1.5       cgd      2812: {
1.493     rillig   2813:        IFile *curFile = CurFile();
1.469     rillig   2814:        char *line;
                   2815:        char *line_end;
1.492     rillig   2816:        char *firstBackslash;
                   2817:        char *firstComment;
1.469     rillig   2818:
                   2819:        /* Loop through blank lines and comment lines */
1.127     dsl      2820:        for (;;) {
1.493     rillig   2821:                ParseRawLineResult res = ParseRawLine(curFile,
                   2822:                    &line, &line_end, &firstBackslash, &firstComment);
                   2823:                if (res == PRLR_ERROR)
1.489     rillig   2824:                        return NULL;
1.27      christos 2825:
1.492     rillig   2826:                if (line_end == line || firstComment == line) {
1.493     rillig   2827:                        if (res == PRLR_EOF)
1.469     rillig   2828:                                return NULL;
1.499     rillig   2829:                        if (mode != GLM_FOR_BODY)
1.494     rillig   2830:                                continue;
1.469     rillig   2831:                }
1.5       cgd      2832:
1.469     rillig   2833:                /* We now have a line of data */
                   2834:                *line_end = '\0';
1.5       cgd      2835:
1.499     rillig   2836:                if (mode == GLM_FOR_BODY)
                   2837:                        return line;    /* Don't join the physical lines. */
1.5       cgd      2838:
1.499     rillig   2839:                if (mode == GLM_DOT && line[0] != '.')
                   2840:                        continue;
1.127     dsl      2841:                break;
                   2842:        }
1.5       cgd      2843:
1.469     rillig   2844:        /* Brutally ignore anything after a non-escaped '#' in non-commands. */
1.492     rillig   2845:        if (firstComment != NULL && line[0] != '\t') {
                   2846:                line_end = firstComment;
1.469     rillig   2847:                *line_end = '\0';
                   2848:        }
                   2849:
                   2850:        /* If we didn't see a '\\' then the in-situ data is fine. */
1.492     rillig   2851:        if (firstBackslash == NULL)
1.469     rillig   2852:                return line;
                   2853:
                   2854:        /* Remove escapes from '\n' and '#' */
1.492     rillig   2855:        UnescapeBackslash(line, firstBackslash);
1.27      christos 2856:
1.469     rillig   2857:        return line;
1.5       cgd      2858: }
1.1       cgd      2859:
1.500     rillig   2860: static Boolean
1.501     rillig   2861: ParseSkippedBranches(void)
                   2862: {
                   2863:        char *line;
                   2864:
                   2865:        while ((line = ParseGetLine(GLM_DOT)) != NULL) {
                   2866:                if (Cond_EvalLine(line) == COND_PARSE)
                   2867:                        break;
                   2868:                /*
                   2869:                 * TODO: Check for typos in .elif directives
                   2870:                 * such as .elsif or .elseif.
                   2871:                 *
                   2872:                 * This check will probably duplicate some of
                   2873:                 * the code in ParseLine.  Most of the code
                   2874:                 * there cannot apply, only ParseVarassign and
                   2875:                 * ParseDependency can, and to prevent code
                   2876:                 * duplication, these would need to be called
                   2877:                 * with a flag called onlyCheckSyntax.
                   2878:                 *
                   2879:                 * See directive-elif.mk for details.
                   2880:                 */
                   2881:        }
                   2882:
                   2883:        return line != NULL;
                   2884: }
                   2885:
                   2886: static Boolean
1.500     rillig   2887: ParseForLoop(const char *line)
                   2888: {
                   2889:        int rval;
                   2890:        int firstLineno;
                   2891:
                   2892:        rval = For_Eval(line);
                   2893:        if (rval == 0)
                   2894:                return FALSE;   /* Not a .for line */
                   2895:        if (rval < 0)
                   2896:                return TRUE;    /* Syntax error - error printed, ignore line */
                   2897:
                   2898:        firstLineno = CurFile()->lineno;
                   2899:
                   2900:        /* Accumulate loop lines until matching .endfor */
                   2901:        do {
                   2902:                line = ParseGetLine(GLM_FOR_BODY);
                   2903:                if (line == NULL) {
                   2904:                        Parse_Error(PARSE_FATAL,
                   2905:                            "Unexpected end of file in for loop.");
                   2906:                        break;
                   2907:                }
                   2908:        } while (For_Accum(line));
                   2909:
                   2910:        For_Run(firstLineno);   /* Stash each iteration as a new 'input file' */
                   2911:
                   2912:        return TRUE;            /* Read next line from for-loop buffer */
                   2913: }
                   2914:
1.469     rillig   2915: /*
1.482     rillig   2916:  * Read an entire line from the input file.
                   2917:  *
                   2918:  * Empty lines, .if and .for are completely handled by this function,
                   2919:  * leaving only variable assignments, other directives, dependency lines
                   2920:  * and shell commands to the caller.
1.1       cgd      2921:  *
                   2922:  * Results:
1.482     rillig   2923:  *     A line without its newline and without any trailing whitespace,
                   2924:  *     or NULL.
1.1       cgd      2925:  */
                   2926: static char *
1.84      wiz      2927: ParseReadLine(void)
1.1       cgd      2928: {
1.500     rillig   2929:        char *line;
1.469     rillig   2930:
                   2931:        for (;;) {
1.499     rillig   2932:                line = ParseGetLine(GLM_NONEMPTY);
1.469     rillig   2933:                if (line == NULL)
                   2934:                        return NULL;
                   2935:
                   2936:                if (line[0] != '.')
                   2937:                        return line;
                   2938:
                   2939:                /*
                   2940:                 * The line might be a conditional. Ask the conditional module
                   2941:                 * about it and act accordingly
                   2942:                 */
                   2943:                switch (Cond_EvalLine(line)) {
                   2944:                case COND_SKIP:
1.501     rillig   2945:                        if (!ParseSkippedBranches())
1.482     rillig   2946:                                return NULL;
1.469     rillig   2947:                        continue;
                   2948:                case COND_PARSE:
                   2949:                        continue;
                   2950:                case COND_INVALID:      /* Not a conditional line */
1.500     rillig   2951:                        if (ParseForLoop(line))
1.469     rillig   2952:                                continue;
1.500     rillig   2953:                        break;
1.469     rillig   2954:                }
                   2955:                return line;
1.1       cgd      2956:        }
                   2957: }
                   2958:
1.331     rillig   2959: static void
1.329     rillig   2960: FinishDependencyGroup(void)
1.1       cgd      2961: {
1.469     rillig   2962:        GNodeListNode *ln;
1.430     rillig   2963:
1.469     rillig   2964:        if (targets == NULL)
                   2965:                return;
1.371     rillig   2966:
1.469     rillig   2967:        for (ln = targets->first; ln != NULL; ln = ln->next) {
                   2968:                GNode *gn = ln->datum;
1.371     rillig   2969:
1.469     rillig   2970:                Suff_EndTransform(gn);
1.371     rillig   2971:
1.469     rillig   2972:                /*
                   2973:                 * Mark the target as already having commands if it does, to
                   2974:                 * keep from having shell commands on multiple dependency
                   2975:                 * lines.
                   2976:                 */
                   2977:                if (!Lst_IsEmpty(&gn->commands))
                   2978:                        gn->type |= OP_HAS_COMMANDS;
                   2979:        }
1.430     rillig   2980:
1.469     rillig   2981:        Lst_Free(targets);
                   2982:        targets = NULL;
1.1       cgd      2983: }
1.27      christos 2984:
1.327     rillig   2985: /* Add the command to each target from the current dependency spec. */
1.326     rillig   2986: static void
1.375     rillig   2987: ParseLine_ShellCommand(const char *p)
1.326     rillig   2988: {
1.469     rillig   2989:        cpp_skip_whitespace(&p);
                   2990:        if (*p == '\0')
                   2991:                return;         /* skip empty commands */
1.327     rillig   2992:
1.469     rillig   2993:        if (targets == NULL) {
                   2994:                Parse_Error(PARSE_FATAL,
                   2995:                    "Unassociated shell command \"%s\"", p);
                   2996:                return;
                   2997:        }
1.327     rillig   2998:
1.469     rillig   2999:        {
                   3000:                char *cmd = bmake_strdup(p);
                   3001:                GNodeListNode *ln;
                   3002:
                   3003:                for (ln = targets->first; ln != NULL; ln = ln->next) {
                   3004:                        GNode *gn = ln->datum;
                   3005:                        ParseAddCmd(gn, cmd);
                   3006:                }
1.326     rillig   3007: #ifdef CLEANUP
1.469     rillig   3008:                Lst_Append(&targCmds, cmd);
1.326     rillig   3009: #endif
1.469     rillig   3010:        }
1.326     rillig   3011: }
1.1       cgd      3012:
1.475     rillig   3013: MAKE_INLINE Boolean
                   3014: IsDirective(const char *dir, size_t dirlen, const char *name)
                   3015: {
                   3016:        return dirlen == strlen(name) && memcmp(dir, name, dirlen) == 0;
                   3017: }
                   3018:
1.474     rillig   3019: /*
1.477     rillig   3020:  * See if the line starts with one of the known directives, and if so, handle
                   3021:  * the directive.
1.474     rillig   3022:  */
1.379     rillig   3023: static Boolean
                   3024: ParseDirective(char *line)
                   3025: {
1.474     rillig   3026:        char *cp = line + 1;
1.475     rillig   3027:        const char *dir, *arg;
                   3028:        size_t dirlen;
1.474     rillig   3029:
                   3030:        pp_skip_whitespace(&cp);
                   3031:        if (IsInclude(cp, FALSE)) {
                   3032:                ParseDoInclude(cp);
                   3033:                return TRUE;
                   3034:        }
1.379     rillig   3035:
1.475     rillig   3036:        dir = cp;
                   3037:        while (ch_isalpha(*cp) || *cp == '-')
                   3038:                cp++;
                   3039:        dirlen = (size_t)(cp - dir);
                   3040:
                   3041:        if (*cp != '\0' && !ch_isspace(*cp))
                   3042:                return FALSE;
                   3043:
                   3044:        pp_skip_whitespace(&cp);
                   3045:        arg = cp;
                   3046:
                   3047:        if (IsDirective(dir, dirlen, "undef")) {
1.502     rillig   3048:                Var_Undef(cp);
1.474     rillig   3049:                return TRUE;
1.476     rillig   3050:        } else if (IsDirective(dir, dirlen, "export")) {
                   3051:                Var_Export(VEM_PARENT, arg);
                   3052:                return TRUE;
                   3053:        } else if (IsDirective(dir, dirlen, "export-env")) {
                   3054:                Var_Export(VEM_NORMAL, arg);
                   3055:                return TRUE;
                   3056:        } else if (IsDirective(dir, dirlen, "export-literal")) {
                   3057:                Var_Export(VEM_LITERAL, arg);
1.474     rillig   3058:                return TRUE;
1.479     rillig   3059:        } else if (IsDirective(dir, dirlen, "unexport")) {
                   3060:                Var_UnExport(FALSE, arg);
                   3061:                return TRUE;
                   3062:        } else if (IsDirective(dir, dirlen, "unexport-env")) {
                   3063:                Var_UnExport(TRUE, arg);
1.474     rillig   3064:                return TRUE;
1.475     rillig   3065:        } else if (IsDirective(dir, dirlen, "info")) {
1.503     rillig   3066:                ParseMessage(PARSE_INFO, "info", arg);
                   3067:                return TRUE;
1.475     rillig   3068:        } else if (IsDirective(dir, dirlen, "warning")) {
1.503     rillig   3069:                ParseMessage(PARSE_WARNING, "warning", arg);
                   3070:                return TRUE;
1.475     rillig   3071:        } else if (IsDirective(dir, dirlen, "error")) {
1.503     rillig   3072:                ParseMessage(PARSE_FATAL, "error", arg);
                   3073:                return TRUE;
1.379     rillig   3074:        }
1.469     rillig   3075:        return FALSE;
1.379     rillig   3076: }
                   3077:
                   3078: static Boolean
                   3079: ParseVarassign(const char *line)
                   3080: {
1.469     rillig   3081:        VarAssign var;
1.430     rillig   3082:
1.469     rillig   3083:        if (!Parse_IsVar(line, &var))
                   3084:                return FALSE;
1.430     rillig   3085:
1.469     rillig   3086:        FinishDependencyGroup();
                   3087:        Parse_DoVar(&var, VAR_GLOBAL);
                   3088:        return TRUE;
1.379     rillig   3089: }
                   3090:
1.380     rillig   3091: static char *
                   3092: FindSemicolon(char *p)
                   3093: {
1.469     rillig   3094:        int level = 0;
                   3095:
                   3096:        for (; *p != '\0'; p++) {
                   3097:                if (*p == '\\' && p[1] != '\0') {
                   3098:                        p++;
                   3099:                        continue;
                   3100:                }
1.380     rillig   3101:
1.469     rillig   3102:                if (*p == '$' && (p[1] == '(' || p[1] == '{'))
                   3103:                        level++;
                   3104:                else if (level > 0 && (*p == ')' || *p == '}'))
                   3105:                        level--;
                   3106:                else if (level == 0 && *p == ';')
                   3107:                        break;
                   3108:        }
                   3109:        return p;
1.380     rillig   3110: }
                   3111:
1.379     rillig   3112: /* dependency  -> target... op [source...]
                   3113:  * op          -> ':' | '::' | '!' */
                   3114: static void
1.380     rillig   3115: ParseDependency(char *line)
1.379     rillig   3116: {
1.469     rillig   3117:        VarEvalFlags eflags;
                   3118:        char *expanded_line;
                   3119:        const char *shellcmd = NULL;
                   3120:
                   3121:        /*
                   3122:         * For some reason - probably to make the parser impossible -
                   3123:         * a ';' can be used to separate commands from dependencies.
                   3124:         * Attempt to avoid ';' inside substitution patterns.
                   3125:         */
                   3126:        {
                   3127:                char *semicolon = FindSemicolon(line);
                   3128:                if (*semicolon != '\0') {
                   3129:                        /* Terminate the dependency list at the ';' */
                   3130:                        *semicolon = '\0';
                   3131:                        shellcmd = semicolon + 1;
                   3132:                }
                   3133:        }
1.379     rillig   3134:
1.469     rillig   3135:        /*
                   3136:         * We now know it's a dependency line so it needs to have all
                   3137:         * variables expanded before being parsed.
                   3138:         *
                   3139:         * XXX: Ideally the dependency line would first be split into
                   3140:         * its left-hand side, dependency operator and right-hand side,
                   3141:         * and then each side would be expanded on its own.  This would
                   3142:         * allow for the left-hand side to allow only defined variables
                   3143:         * and to allow variables on the right-hand side to be undefined
                   3144:         * as well.
                   3145:         *
                   3146:         * Parsing the line first would also prevent that targets
                   3147:         * generated from variable expressions are interpreted as the
                   3148:         * dependency operator, such as in "target${:U\:} middle: source",
                   3149:         * in which the middle is interpreted as a source, not a target.
                   3150:         */
                   3151:
                   3152:        /* In lint mode, allow undefined variables to appear in
                   3153:         * dependency lines.
                   3154:         *
                   3155:         * Ideally, only the right-hand side would allow undefined
                   3156:         * variables since it is common to have optional dependencies.
                   3157:         * Having undefined variables on the left-hand side is more
                   3158:         * unusual though.  Since both sides are expanded in a single
                   3159:         * pass, there is not much choice what to do here.
                   3160:         *
                   3161:         * In normal mode, it does not matter whether undefined
                   3162:         * variables are allowed or not since as of 2020-09-14,
                   3163:         * Var_Parse does not print any parse errors in such a case.
                   3164:         * It simply returns the special empty string var_Error,
                   3165:         * which cannot be detected in the result of Var_Subst. */
                   3166:        eflags = opts.lint ? VARE_WANTRES : VARE_WANTRES | VARE_UNDEFERR;
                   3167:        (void)Var_Subst(line, VAR_CMDLINE, eflags, &expanded_line);
                   3168:        /* TODO: handle errors */
                   3169:
                   3170:        /* Need a fresh list for the target nodes */
                   3171:        if (targets != NULL)
                   3172:                Lst_Free(targets);
                   3173:        targets = Lst_New();
1.379     rillig   3174:
1.469     rillig   3175:        ParseDoDependency(expanded_line);
                   3176:        free(expanded_line);
1.380     rillig   3177:
1.469     rillig   3178:        if (shellcmd != NULL)
                   3179:                ParseLine_ShellCommand(shellcmd);
1.379     rillig   3180: }
                   3181:
1.381     rillig   3182: static void
                   3183: ParseLine(char *line)
                   3184: {
1.477     rillig   3185:        /*
                   3186:         * Lines that begin with '.' can be pretty much anything:
                   3187:         *      - directives like '.include' or '.if',
                   3188:         *      - suffix rules like '.c.o:',
                   3189:         *      - dependencies for filenames that start with '.',
                   3190:         *      - variable assignments like '.tmp=value'.
                   3191:         */
1.474     rillig   3192:        if (line[0] == '.' && ParseDirective(line))
1.469     rillig   3193:                return;
1.381     rillig   3194:
1.478     rillig   3195:        if (line[0] == '\t') {
1.469     rillig   3196:                ParseLine_ShellCommand(line + 1);
                   3197:                return;
                   3198:        }
1.381     rillig   3199:
                   3200: #ifdef SYSVINCLUDE
1.469     rillig   3201:        if (IsSysVInclude(line)) {
                   3202:                /*
                   3203:                 * It's an S3/S5-style "include".
                   3204:                 */
                   3205:                ParseTraditionalInclude(line);
                   3206:                return;
                   3207:        }
1.381     rillig   3208: #endif
                   3209:
                   3210: #ifdef GMAKEEXPORT
1.469     rillig   3211:        if (strncmp(line, "export", 6) == 0 && ch_isspace(line[6]) &&
                   3212:            strchr(line, ':') == NULL) {
                   3213:                /*
                   3214:                 * It's a Gmake "export".
                   3215:                 */
                   3216:                ParseGmakeExport(line);
                   3217:                return;
                   3218:        }
1.381     rillig   3219: #endif
                   3220:
1.469     rillig   3221:        if (ParseVarassign(line))
                   3222:                return;
1.381     rillig   3223:
1.469     rillig   3224:        FinishDependencyGroup();
1.381     rillig   3225:
1.469     rillig   3226:        ParseDependency(line);
1.381     rillig   3227: }
                   3228:
1.469     rillig   3229: /*
                   3230:  * Parse a top-level makefile, incorporating its content into the global
1.441     rillig   3231:  * dependency graph.
1.1       cgd      3232:  *
1.84      wiz      3233:  * Input:
1.297     rillig   3234:  *     name            The name of the file being read
                   3235:  *     fd              The open file to parse; will be closed at the end
1.1       cgd      3236:  */
                   3237: void
1.125     dsl      3238: Parse_File(const char *name, int fd)
1.1       cgd      3239: {
1.469     rillig   3240:        char *line;             /* the line we're working on */
                   3241:        struct loadedfile *lf;
1.170     dholland 3242:
1.469     rillig   3243:        lf = loadfile(name, fd);
1.1       cgd      3244:
1.469     rillig   3245:        assert(targets == NULL);
1.44      aidan    3246:
1.469     rillig   3247:        if (name == NULL)
                   3248:                name = "(stdin)";
1.170     dholland 3249:
1.471     rillig   3250:        Parse_SetInput(name, 0, -1, loadedfile_readMore, lf);
1.469     rillig   3251:        CurFile()->lf = lf;
1.1       cgd      3252:
1.469     rillig   3253:        do {
                   3254:                while ((line = ParseReadLine()) != NULL) {
                   3255:                        DEBUG2(PARSE, "ParseReadLine (%d): '%s'\n",
                   3256:                            CurFile()->lineno, line);
                   3257:                        ParseLine(line);
                   3258:                }
                   3259:                /* Reached EOF, but it may be just EOF of an include file. */
                   3260:        } while (ParseEOF());
1.1       cgd      3261:
1.469     rillig   3262:        FinishDependencyGroup();
1.328     rillig   3263:
1.469     rillig   3264:        if (fatals != 0) {
                   3265:                (void)fflush(stdout);
                   3266:                (void)fprintf(stderr,
                   3267:                    "%s: Fatal errors encountered -- cannot continue",
                   3268:                    progname);
                   3269:                PrintOnError(NULL, NULL);
                   3270:                exit(1);
                   3271:        }
1.1       cgd      3272: }
                   3273:
1.383     rillig   3274: /* Initialize the parsing module. */
1.5       cgd      3275: void
1.84      wiz      3276: Parse_Init(void)
1.1       cgd      3277: {
1.469     rillig   3278:        mainNode = NULL;
                   3279:        parseIncPath = SearchPath_New();
                   3280:        sysIncPath = SearchPath_New();
                   3281:        defSysIncPath = SearchPath_New();
                   3282:        Vector_Init(&includes, sizeof(IFile));
1.1       cgd      3283: }
1.9       jtc      3284:
1.383     rillig   3285: /* Clean up the parsing module. */
1.9       jtc      3286: void
1.84      wiz      3287: Parse_End(void)
1.9       jtc      3288: {
1.45      mycroft  3289: #ifdef CLEANUP
1.469     rillig   3290:        Lst_DoneCall(&targCmds, free);
                   3291:        assert(targets == NULL);
                   3292:        SearchPath_Free(defSysIncPath);
                   3293:        SearchPath_Free(sysIncPath);
                   3294:        SearchPath_Free(parseIncPath);
                   3295:        assert(includes.len == 0);
                   3296:        Vector_Done(&includes);
1.45      mycroft  3297: #endif
1.9       jtc      3298: }
1.27      christos 3299:
1.1       cgd      3300:
1.441     rillig   3301: /*
                   3302:  * Return a list containing the single main target to create.
                   3303:  * If no such target exists, we Punt with an obnoxious error message.
1.1       cgd      3304:  */
1.461     rillig   3305: void
                   3306: Parse_MainName(GNodeList *mainList)
1.1       cgd      3307: {
1.469     rillig   3308:        if (mainNode == NULL)
                   3309:                Punt("no target to make.");
1.430     rillig   3310:
1.469     rillig   3311:        if (mainNode->type & OP_DOUBLEDEP) {
                   3312:                Lst_Append(mainList, mainNode);
                   3313:                Lst_AppendAll(mainList, &mainNode->cohorts);
                   3314:        } else
                   3315:                Lst_Append(mainList, mainNode);
1.441     rillig   3316:
1.469     rillig   3317:        Var_Append(".TARGETS", mainNode->name, VAR_GLOBAL);
1.59      christos 3318: }
1.420     rillig   3319:
                   3320: int
                   3321: Parse_GetFatals(void)
                   3322: {
1.469     rillig   3323:        return fatals;
1.420     rillig   3324: }

CVSweb <webmaster@jp.NetBSD.org>