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

Annotation of src/usr.bin/make/var.c, Revision 1.283

1.283   ! rillig      1: /*     $NetBSD: var.c,v 1.282 2020/07/20 15:48:50 rillig Exp $ */
1.11      christos    2:
1.1       cgd         3: /*
1.15      christos    4:  * Copyright (c) 1988, 1989, 1990, 1993
                      5:  *     The Regents of the University of California.  All rights reserved.
1.80      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.88      ross       71: #ifndef MAKE_NATIVE
1.283   ! rillig     72: static char rcsid[] = "$NetBSD: var.c,v 1.282 2020/07/20 15:48:50 rillig Exp $";
1.23      lukem      73: #else
1.19      christos   74: #include <sys/cdefs.h>
1.1       cgd        75: #ifndef lint
1.11      christos   76: #if 0
1.15      christos   77: static char sccsid[] = "@(#)var.c      8.3 (Berkeley) 3/19/94";
1.11      christos   78: #else
1.283   ! rillig     79: __RCSID("$NetBSD: var.c,v 1.282 2020/07/20 15:48:50 rillig Exp $");
1.11      christos   80: #endif
1.1       cgd        81: #endif /* not lint */
1.23      lukem      82: #endif
1.1       cgd        83:
                     84: /*-
                     85:  * var.c --
                     86:  *     Variable-handling functions
                     87:  *
                     88:  * Interface:
1.138     dsl        89:  *     Var_Set             Set the value of a variable in the given
                     90:  *                         context. The variable is created if it doesn't
                     91:  *                         yet exist. The value and variable name need not
                     92:  *                         be preserved.
1.1       cgd        93:  *
                     94:  *     Var_Append          Append more characters to an existing variable
1.138     dsl        95:  *                         in the given context. The variable needn't
                     96:  *                         exist already -- it will be created if it doesn't.
                     97:  *                         A space is placed between the old value and the
                     98:  *                         new one.
1.1       cgd        99:  *
                    100:  *     Var_Exists          See if a variable exists.
                    101:  *
                    102:  *     Var_Value           Return the value of a variable in a context or
1.138     dsl       103:  *                         NULL if the variable is undefined.
1.1       cgd       104:  *
1.250     rillig    105:  *     Var_Subst           Substitute either a single variable or all
                    106:  *                         variables in a string, using the given context as
                    107:  *                         the top-most one.
1.1       cgd       108:  *
                    109:  *     Var_Parse           Parse a variable expansion from a string and
1.138     dsl       110:  *                         return the result and the number of characters
                    111:  *                         consumed.
1.1       cgd       112:  *
                    113:  *     Var_Delete          Delete a variable in a context.
                    114:  *
                    115:  *     Var_Init            Initialize this module.
                    116:  *
                    117:  * Debugging:
                    118:  *     Var_Dump            Print out all variables defined in the given
1.138     dsl       119:  *                         context.
1.1       cgd       120:  *
                    121:  * XXX: There's a lot of duplication in these functions.
                    122:  */
                    123:
1.157     sjg       124: #include    <sys/stat.h>
1.31      gwr       125: #ifndef NO_REGEX
1.28      wsanchez  126: #include    <sys/types.h>
1.16      christos  127: #include    <regex.h>
1.17      christos  128: #endif
1.70      wiz       129: #include    <ctype.h>
1.163     joerg     130: #include    <inttypes.h>
1.17      christos  131: #include    <stdlib.h>
1.82      jmc       132: #include    <limits.h>
1.166     tsutsui   133: #include    <time.h>
1.70      wiz       134:
1.1       cgd       135: #include    "make.h"
                    136: #include    "buf.h"
1.103     sjg       137: #include    "dir.h"
1.111     rillig    138: #include    "job.h"
1.193     christos  139: #include    "metachar.h"
1.1       cgd       140:
1.182     christos  141: extern int makelevel;
1.1       cgd       142: /*
1.170     sjg       143:  * This lets us tell if we have replaced the original environ
                    144:  * (which we cannot free).
                    145:  */
                    146: char **savedEnv = NULL;
                    147:
                    148: /*
1.1       cgd       149:  * This is a harmless return value for Var_Parse that can be used by Var_Subst
                    150:  * to determine if there was an error in parsing -- easier than returning
                    151:  * a flag, as things outside this module don't give a hoot.
                    152:  */
1.249     rillig    153: char var_Error[] = "";
1.1       cgd       154:
                    155: /*
1.259     rillig    156:  * Similar to var_Error, but returned when the 'VARE_UNDEFERR' flag for
1.202     christos  157:  * Var_Parse is not set. Why not just use a constant? Well, gcc likes
                    158:  * to condense identical string instances...
1.1       cgd       159:  */
1.249     rillig    160: static char varNoError[] = "";
1.1       cgd       161:
                    162: /*
1.205     sjg       163:  * Traditionally we consume $$ during := like any other expansion.
                    164:  * Other make's do not.
                    165:  * This knob allows controlling the behavior.
                    166:  * FALSE for old behavior.
                    167:  * TRUE for new compatible.
                    168:  */
                    169: #define SAVE_DOLLARS ".MAKE.SAVE_DOLLARS"
                    170: static Boolean save_dollars = TRUE;
                    171:
                    172: /*
1.1       cgd       173:  * Internally, variables are contained in four different contexts.
                    174:  *     1) the environment. They may not be changed. If an environment
                    175:  *         variable is appended-to, the result is placed in the global
                    176:  *         context.
                    177:  *     2) the global context. Variables set in the Makefile are located in
                    178:  *         the global context. It is the penultimate context searched when
                    179:  *         substituting.
                    180:  *     3) the command-line context. All variables set on the command line
                    181:  *        are placed in this context. They are UNALTERABLE once placed here.
                    182:  *     4) the local context. Each target has associated with it a context
                    183:  *        list. On this list are located the structures describing such
                    184:  *        local variables as $(@) and $(*)
                    185:  * The four contexts are searched in the reverse order from which they are
                    186:  * listed.
                    187:  */
1.240     rillig    188: GNode          *VAR_INTERNAL;  /* variables from make itself */
                    189: GNode          *VAR_GLOBAL;    /* variables from the makefile */
                    190: GNode          *VAR_CMD;       /* variables defined on the command-line */
                    191:
1.260     rillig    192: typedef enum {
                    193:     FIND_CMD           = 0x01, /* look in VAR_CMD when searching */
                    194:     FIND_GLOBAL                = 0x02, /* look in VAR_GLOBAL as well */
                    195:     FIND_ENV           = 0x04  /* look in the environment also */
                    196: } VarFindFlags;
1.1       cgd       197:
1.228     rillig    198: typedef enum {
1.240     rillig    199:     VAR_IN_USE         = 0x01, /* Variable's value is currently being used.
1.228     rillig    200:                                 * Used to avoid endless recursion */
1.240     rillig    201:     VAR_FROM_ENV       = 0x02, /* Variable comes from the environment */
                    202:     VAR_JUNK           = 0x04, /* Variable is a junk variable that
1.228     rillig    203:                                 * should be destroyed when done with
                    204:                                 * it. Used by Var_Parse for undefined,
                    205:                                 * modified variables */
1.240     rillig    206:     VAR_KEEP           = 0x08, /* Variable is VAR_JUNK, but we found
1.228     rillig    207:                                 * a use for it in some modifier and
                    208:                                 * the value is therefore valid */
1.240     rillig    209:     VAR_EXPORTED       = 0x10, /* Variable is exported */
                    210:     VAR_REEXPORT       = 0x20, /* Indicate if var needs re-export.
1.228     rillig    211:                                 * This would be true if it contains $'s */
1.240     rillig    212:     VAR_FROM_CMD       = 0x40  /* Variable came from command line */
1.228     rillig    213: } Var_Flags;
                    214:
1.1       cgd       215: typedef struct Var {
                    216:     char          *name;       /* the variable's name */
1.138     dsl       217:     Buffer       val;          /* its value */
1.228     rillig    218:     Var_Flags    flags;        /* miscellaneous status flags */
1.1       cgd       219: }  Var;
                    220:
1.118     sjg       221: /*
                    222:  * Exporting vars is expensive so skip it if we can
                    223:  */
                    224: #define VAR_EXPORTED_NONE      0
                    225: #define VAR_EXPORTED_YES       1
                    226: #define VAR_EXPORTED_ALL       2
                    227: static int var_exportedVars = VAR_EXPORTED_NONE;
                    228: /*
                    229:  * We pass this to Var_Export when doing the initial export
                    230:  * or after updating an exported var.
                    231:  */
1.203     sjg       232: #define VAR_EXPORT_PARENT      1
                    233: /*
                    234:  * We pass this to Var_Export1 to tell it to leave the value alone.
                    235:  */
                    236: #define VAR_EXPORT_LITERAL     2
1.16      christos  237:
1.261     rillig    238: /* Flags for pattern matching in the :S and :C modifiers */
1.229     rillig    239: typedef enum {
1.261     rillig    240:     VARP_SUB_GLOBAL    = 0x01, /* Apply substitution globally */
                    241:     VARP_SUB_ONE       = 0x02, /* Apply substitution to one word */
                    242:     VARP_SUB_MATCHED   = 0x04, /* There was a match */
                    243:     VARP_MATCH_START   = 0x08, /* Match at start of word */
                    244:     VARP_MATCH_END     = 0x10, /* Match at end of word */
                    245:
1.265     rillig    246:     /* FIXME: This constant doesn't belong here.
                    247:      * It is not related to pattern matching. */
                    248:     VAR_NOSUBST        = 0x20          /* don't expand vars in ParseModifierPart */
1.261     rillig    249: } VarPatternFlags;
1.16      christos  250:
1.230     rillig    251: typedef enum {
                    252:        VAR_NO_EXPORT   = 0x01  /* do not export */
                    253: } VarSet_Flags;
1.65      sjg       254:
1.5       cgd       255: typedef struct {
1.81      sjg       256:     /*
                    257:      * The following fields are set by Var_Parse() when it
                    258:      * encounters modifiers that need to keep state for use by
                    259:      * subsequent modifiers within the same variable expansion.
                    260:      */
                    261:     Byte       varSpace;       /* Word separator in expansions */
                    262:     Boolean    oneBigWord;     /* TRUE if we will treat the variable as a
                    263:                                 * single big word, even if it contains
                    264:                                 * embedded spaces (as opposed to the
                    265:                                 * usual behaviour of treating it as
                    266:                                 * several space-separated words). */
                    267: } Var_Parse_State;
                    268:
1.281     rillig    269: /* struct passed as 'void *' to VarSubstitute() for ":S/lhs/rhs/" */
1.81      sjg       270: typedef struct {
1.281     rillig    271:     const char *lhs;
                    272:     size_t     lhsLen;
                    273:     const char *rhs;
                    274:     size_t     rhsLen;
1.261     rillig    275:     VarPatternFlags pflags;
1.281     rillig    276: } VarSubstituteArgs;
1.5       cgd       277:
1.148     dsl       278: /* struct passed as 'void *' to VarLoopExpand() for ":@tvar@str@" */
1.41      sjg       279: typedef struct {
1.267     rillig    280:     char       *tvar;          /* name of temporary variable */
1.41      sjg       281:     char       *str;           /* string to expand */
1.267     rillig    282:     VarEvalFlags eflags;
1.251     rillig    283: } VarLoop;
1.41      sjg       284:
1.31      gwr       285: #ifndef NO_REGEX
1.148     dsl       286: /* struct passed as 'void *' to VarRESubstitute() for ":C///" */
1.16      christos  287: typedef struct {
                    288:     regex_t       re;
1.127     christos  289:     int                   nsub;
1.16      christos  290:     regmatch_t           *matches;
                    291:     char         *replace;
1.261     rillig    292:     VarPatternFlags pflags;
1.16      christos  293: } VarREPattern;
1.17      christos  294: #endif
1.16      christos  295:
1.81      sjg       296: /* struct passed to VarSelectWords() for ":[start..end]" */
                    297: typedef struct {
                    298:     int                start;          /* first word to select */
                    299:     int                end;            /* last word to select */
                    300: } VarSelectWords_t;
                    301:
1.100     christos  302: #define BROPEN '{'
                    303: #define BRCLOSE        '}'
                    304: #define PROPEN '('
                    305: #define PRCLOSE        ')'
                    306:
1.1       cgd       307: /*-
                    308:  *-----------------------------------------------------------------------
                    309:  * VarFind --
                    310:  *     Find the given variable in the given context and any other contexts
                    311:  *     indicated.
                    312:  *
1.70      wiz       313:  * Input:
                    314:  *     name            name to find
                    315:  *     ctxt            context in which to find it
1.260     rillig    316:  *     flags           FIND_GLOBAL     look in VAR_GLOBAL as well
                    317:  *                     FIND_CMD        look in VAR_CMD as well
                    318:  *                     FIND_ENV        look in the environment as well
1.70      wiz       319:  *
1.1       cgd       320:  * Results:
                    321:  *     A pointer to the structure describing the desired variable or
1.136     dsl       322:  *     NULL if the variable does not exist.
1.1       cgd       323:  *
                    324:  * Side Effects:
                    325:  *     None
                    326:  *-----------------------------------------------------------------------
                    327:  */
                    328: static Var *
1.260     rillig    329: VarFind(const char *name, GNode *ctxt, VarFindFlags flags)
1.1       cgd       330: {
1.36      mycroft   331:     Hash_Entry                 *var;
1.138     dsl       332:     Var                        *v;
1.1       cgd       333:
1.242     rillig    334:     /*
                    335:      * If the variable name begins with a '.', it could very well be one of
                    336:      * the local ones.  We check the name against all the local variables
                    337:      * and substitute the short version in for 'name' if it matches one of
                    338:      * them.
                    339:      */
                    340:     if (*name == '.' && isupper((unsigned char) name[1])) {
                    341:        switch (name[1]) {
                    342:        case 'A':
1.257     rillig    343:            if (strcmp(name, ".ALLSRC") == 0)
1.242     rillig    344:                name = ALLSRC;
1.257     rillig    345:            if (strcmp(name, ".ARCHIVE") == 0)
1.242     rillig    346:                name = ARCHIVE;
                    347:            break;
                    348:        case 'I':
1.257     rillig    349:            if (strcmp(name, ".IMPSRC") == 0)
1.242     rillig    350:                name = IMPSRC;
                    351:            break;
                    352:        case 'M':
1.257     rillig    353:            if (strcmp(name, ".MEMBER") == 0)
1.242     rillig    354:                name = MEMBER;
                    355:            break;
                    356:        case 'O':
1.257     rillig    357:            if (strcmp(name, ".OODATE") == 0)
1.242     rillig    358:                name = OODATE;
                    359:            break;
                    360:        case 'P':
1.257     rillig    361:            if (strcmp(name, ".PREFIX") == 0)
1.242     rillig    362:                name = PREFIX;
                    363:            break;
                    364:        case 'T':
1.257     rillig    365:            if (strcmp(name, ".TARGET") == 0)
1.242     rillig    366:                name = TARGET;
                    367:            break;
                    368:        }
                    369:     }
                    370:
1.160     christos  371: #ifdef notyet
                    372:     /* for compatibility with gmake */
                    373:     if (name[0] == '^' && name[1] == '\0')
1.242     rillig    374:        name = ALLSRC;
1.160     christos  375: #endif
                    376:
1.1       cgd       377:     /*
                    378:      * First look for the variable in the given context. If it's not there,
                    379:      * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order,
                    380:      * depending on the FIND_* flags in 'flags'
                    381:      */
1.92      christos  382:     var = Hash_FindEntry(&ctxt->context, name);
1.1       cgd       383:
1.231     rillig    384:     if (var == NULL && (flags & FIND_CMD) && ctxt != VAR_CMD) {
1.92      christos  385:        var = Hash_FindEntry(&VAR_CMD->context, name);
1.1       cgd       386:     }
1.231     rillig    387:     if (!checkEnvFirst && var == NULL && (flags & FIND_GLOBAL) &&
                    388:        ctxt != VAR_GLOBAL)
1.1       cgd       389:     {
1.92      christos  390:        var = Hash_FindEntry(&VAR_GLOBAL->context, name);
1.231     rillig    391:        if (var == NULL && ctxt != VAR_INTERNAL) {
1.184     sjg       392:            /* VAR_INTERNAL is subordinate to VAR_GLOBAL */
                    393:            var = Hash_FindEntry(&VAR_INTERNAL->context, name);
                    394:        }
1.1       cgd       395:     }
1.231     rillig    396:     if (var == NULL && (flags & FIND_ENV)) {
1.1       cgd       397:        char *env;
                    398:
1.97      christos  399:        if ((env = getenv(name)) != NULL) {
1.257     rillig    400:            int len;
1.15      christos  401:
1.134     joerg     402:            v = bmake_malloc(sizeof(Var));
                    403:            v->name = bmake_strdup(name);
1.1       cgd       404:
                    405:            len = strlen(env);
1.15      christos  406:
1.146     dsl       407:            Buf_Init(&v->val, len + 1);
                    408:            Buf_AddBytes(&v->val, len, env);
1.15      christos  409:
1.1       cgd       410:            v->flags = VAR_FROM_ENV;
1.231     rillig    411:            return v;
1.1       cgd       412:        } else if (checkEnvFirst && (flags & FIND_GLOBAL) &&
1.231     rillig    413:                   ctxt != VAR_GLOBAL)
1.1       cgd       414:        {
1.92      christos  415:            var = Hash_FindEntry(&VAR_GLOBAL->context, name);
1.231     rillig    416:            if (var == NULL && ctxt != VAR_INTERNAL) {
1.184     sjg       417:                var = Hash_FindEntry(&VAR_INTERNAL->context, name);
                    418:            }
1.36      mycroft   419:            if (var == NULL) {
1.136     dsl       420:                return NULL;
1.1       cgd       421:            } else {
1.231     rillig    422:                return (Var *)Hash_GetValue(var);
1.1       cgd       423:            }
                    424:        } else {
1.136     dsl       425:            return NULL;
1.1       cgd       426:        }
1.36      mycroft   427:     } else if (var == NULL) {
1.136     dsl       428:        return NULL;
1.1       cgd       429:     } else {
1.231     rillig    430:        return (Var *)Hash_GetValue(var);
1.1       cgd       431:     }
                    432: }
                    433:
                    434: /*-
                    435:  *-----------------------------------------------------------------------
1.105     christos  436:  * VarFreeEnv  --
                    437:  *     If the variable is an environment variable, free it
                    438:  *
                    439:  * Input:
                    440:  *     v               the variable
                    441:  *     destroy         true if the value buffer should be destroyed.
                    442:  *
                    443:  * Results:
                    444:  *     1 if it is an environment variable 0 ow.
                    445:  *
                    446:  * Side Effects:
                    447:  *     The variable is free'ed if it is an environent variable.
                    448:  *-----------------------------------------------------------------------
                    449:  */
                    450: static Boolean
                    451: VarFreeEnv(Var *v, Boolean destroy)
                    452: {
1.257     rillig    453:     if (!(v->flags & VAR_FROM_ENV))
1.105     christos  454:        return FALSE;
                    455:     free(v->name);
1.146     dsl       456:     Buf_Destroy(&v->val, destroy);
1.105     christos  457:     free(v);
                    458:     return TRUE;
                    459: }
                    460:
                    461: /*-
                    462:  *-----------------------------------------------------------------------
1.1       cgd       463:  * VarAdd  --
                    464:  *     Add a new variable of name name and value val to the given context
                    465:  *
1.70      wiz       466:  * Input:
                    467:  *     name            name of variable to add
                    468:  *     val             value to set it to
                    469:  *     ctxt            context in which to set it
                    470:  *
1.1       cgd       471:  * Side Effects:
                    472:  *     The new variable is placed at the front of the given context
                    473:  *     The name and val arguments are duplicated so they may
                    474:  *     safely be freed.
                    475:  *-----------------------------------------------------------------------
                    476:  */
1.5       cgd       477: static void
1.73      christos  478: VarAdd(const char *name, const char *val, GNode *ctxt)
1.1       cgd       479: {
1.70      wiz       480:     Var          *v;
1.138     dsl       481:     int                  len;
1.70      wiz       482:     Hash_Entry    *h;
1.1       cgd       483:
1.134     joerg     484:     v = bmake_malloc(sizeof(Var));
1.1       cgd       485:
1.257     rillig    486:     len = val != NULL ? strlen(val) : 0;
1.242     rillig    487:     Buf_Init(&v->val, len + 1);
1.146     dsl       488:     Buf_AddBytes(&v->val, len, val);
1.1       cgd       489:
                    490:     v->flags = 0;
                    491:
1.92      christos  492:     h = Hash_CreateEntry(&ctxt->context, name, NULL);
1.36      mycroft   493:     Hash_SetValue(h, v);
1.37      sommerfe  494:     v->name = h->name;
1.257     rillig    495:     if (DEBUG(VAR) && !(ctxt->flags & INTERNAL)) {
1.114     dsl       496:        fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val);
1.1       cgd       497:     }
                    498: }
                    499:
                    500: /*-
                    501:  *-----------------------------------------------------------------------
                    502:  * Var_Delete --
                    503:  *     Remove a variable from a context.
                    504:  *
                    505:  * Side Effects:
                    506:  *     The Var structure is removed and freed.
                    507:  *
                    508:  *-----------------------------------------------------------------------
                    509:  */
                    510: void
1.73      christos  511: Var_Delete(const char *name, GNode *ctxt)
1.1       cgd       512: {
1.36      mycroft   513:     Hash_Entry           *ln;
1.174     sjg       514:     char *cp;
1.231     rillig    515:
1.257     rillig    516:     if (strchr(name, '$') != NULL) {
1.259     rillig    517:        cp = Var_Subst(NULL, name, VAR_GLOBAL, VARE_WANTRES);
1.174     sjg       518:     } else {
1.257     rillig    519:        cp = UNCONST(name);
1.174     sjg       520:     }
                    521:     ln = Hash_FindEntry(&ctxt->context, cp);
1.1       cgd       522:     if (DEBUG(VAR)) {
1.117     dsl       523:        fprintf(debug_file, "%s:delete %s%s\n",
1.174     sjg       524:            ctxt->name, cp, ln ? "" : " (not found)");
                    525:     }
1.257     rillig    526:     if (cp != name)
1.174     sjg       527:        free(cp);
1.36      mycroft   528:     if (ln != NULL) {
1.257     rillig    529:        Var *v = (Var *)Hash_GetValue(ln);
                    530:        if (v->flags & VAR_EXPORTED) {
1.118     sjg       531:            unsetenv(v->name);
                    532:        }
1.155     sjg       533:        if (strcmp(MAKE_EXPORTED, v->name) == 0) {
                    534:            var_exportedVars = VAR_EXPORTED_NONE;
                    535:        }
1.37      sommerfe  536:        if (v->name != ln->name)
1.242     rillig    537:            free(v->name);
1.36      mycroft   538:        Hash_DeleteEntry(&ctxt->context, ln);
1.146     dsl       539:        Buf_Destroy(&v->val, TRUE);
1.98      christos  540:        free(v);
1.1       cgd       541:     }
                    542: }
                    543:
1.118     sjg       544:
                    545: /*
                    546:  * Export a var.
                    547:  * We ignore make internal variables (those which start with '.')
                    548:  * Also we jump through some hoops to avoid calling setenv
                    549:  * more than necessary since it can leak.
1.152     sjg       550:  * We only manipulate flags of vars if 'parent' is set.
1.118     sjg       551:  */
                    552: static int
1.203     sjg       553: Var_Export1(const char *name, int flags)
1.118     sjg       554: {
                    555:     char tmp[BUFSIZ];
                    556:     Var *v;
                    557:     char *val = NULL;
                    558:     int n;
1.203     sjg       559:     int parent = (flags & VAR_EXPORT_PARENT);
1.118     sjg       560:
                    561:     if (*name == '.')
1.240     rillig    562:        return 0;               /* skip internals */
1.118     sjg       563:     if (!name[1]) {
                    564:        /*
                    565:         * A single char.
                    566:         * If it is one of the vars that should only appear in
                    567:         * local context, skip it, else we can get Var_Subst
                    568:         * into a loop.
                    569:         */
                    570:        switch (name[0]) {
                    571:        case '@':
                    572:        case '%':
                    573:        case '*':
                    574:        case '!':
                    575:            return 0;
                    576:        }
                    577:     }
                    578:     v = VarFind(name, VAR_GLOBAL, 0);
1.257     rillig    579:     if (v == NULL)
1.118     sjg       580:        return 0;
1.152     sjg       581:     if (!parent &&
1.118     sjg       582:        (v->flags & (VAR_EXPORTED|VAR_REEXPORT)) == VAR_EXPORTED) {
                    583:        return 0;                       /* nothing to do */
                    584:     }
1.146     dsl       585:     val = Buf_GetAll(&v->val, NULL);
1.203     sjg       586:     if ((flags & VAR_EXPORT_LITERAL) == 0 && strchr(val, '$')) {
1.152     sjg       587:        if (parent) {
1.118     sjg       588:            /*
1.152     sjg       589:             * Flag this as something we need to re-export.
1.118     sjg       590:             * No point actually exporting it now though,
                    591:             * the child can do it at the last minute.
                    592:             */
1.152     sjg       593:            v->flags |= (VAR_EXPORTED|VAR_REEXPORT);
1.118     sjg       594:            return 1;
                    595:        }
1.158     sjg       596:        if (v->flags & VAR_IN_USE) {
                    597:            /*
                    598:             * We recursed while exporting in a child.
                    599:             * This isn't going to end well, just skip it.
                    600:             */
                    601:            return 0;
                    602:        }
1.118     sjg       603:        n = snprintf(tmp, sizeof(tmp), "${%s}", name);
1.147     lukem     604:        if (n < (int)sizeof(tmp)) {
1.259     rillig    605:            val = Var_Subst(NULL, tmp, VAR_GLOBAL, VARE_WANTRES);
1.118     sjg       606:            setenv(name, val, 1);
                    607:            free(val);
                    608:        }
                    609:     } else {
1.152     sjg       610:        if (parent) {
                    611:            v->flags &= ~VAR_REEXPORT;  /* once will do */
                    612:        }
                    613:        if (parent || !(v->flags & VAR_EXPORTED)) {
1.118     sjg       614:            setenv(name, val, 1);
                    615:        }
                    616:     }
                    617:     /*
                    618:      * This is so Var_Set knows to call Var_Export again...
                    619:      */
1.152     sjg       620:     if (parent) {
                    621:        v->flags |= VAR_EXPORTED;
                    622:     }
1.118     sjg       623:     return 1;
                    624: }
                    625:
1.241     rillig    626: static void
                    627: Var_ExportVars_callback(void *entry, void *unused MAKE_ATTR_UNUSED)
                    628: {
1.242     rillig    629:     Var *var = entry;
                    630:     Var_Export1(var->name, 0);
1.241     rillig    631: }
                    632:
1.118     sjg       633: /*
                    634:  * This gets called from our children.
                    635:  */
                    636: void
                    637: Var_ExportVars(void)
                    638: {
                    639:     char tmp[BUFSIZ];
                    640:     char *val;
                    641:     int n;
                    642:
1.182     christos  643:     /*
                    644:      * Several make's support this sort of mechanism for tracking
                    645:      * recursion - but each uses a different name.
                    646:      * We allow the makefiles to update MAKELEVEL and ensure
                    647:      * children see a correctly incremented value.
                    648:      */
                    649:     snprintf(tmp, sizeof(tmp), "%d", makelevel + 1);
                    650:     setenv(MAKE_LEVEL_ENV, tmp, 1);
                    651:
1.118     sjg       652:     if (VAR_EXPORTED_NONE == var_exportedVars)
                    653:        return;
                    654:
                    655:     if (VAR_EXPORTED_ALL == var_exportedVars) {
1.241     rillig    656:        /* Ouch! This is crazy... */
                    657:        Hash_ForEach(&VAR_GLOBAL->context, Var_ExportVars_callback, NULL);
1.118     sjg       658:        return;
                    659:     }
                    660:     /*
                    661:      * We have a number of exported vars,
                    662:      */
                    663:     n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}");
1.147     lukem     664:     if (n < (int)sizeof(tmp)) {
1.118     sjg       665:        char **av;
                    666:        char *as;
1.127     christos  667:        int ac;
1.118     sjg       668:        int i;
1.142     dsl       669:
1.259     rillig    670:        val = Var_Subst(NULL, tmp, VAR_GLOBAL, VARE_WANTRES);
1.200     sjg       671:        if (*val) {
                    672:            av = brk_string(val, &ac, FALSE, &as);
1.257     rillig    673:            for (i = 0; i < ac; i++)
1.200     sjg       674:                Var_Export1(av[i], 0);
                    675:            free(as);
                    676:            free(av);
1.118     sjg       677:        }
                    678:        free(val);
                    679:     }
                    680: }
                    681:
                    682: /*
                    683:  * This is called when .export is seen or
                    684:  * .MAKE.EXPORTED is modified.
                    685:  * It is also called when any exported var is modified.
                    686:  */
                    687: void
                    688: Var_Export(char *str, int isExport)
                    689: {
                    690:     char *name;
                    691:     char *val;
                    692:     char **av;
                    693:     char *as;
1.203     sjg       694:     int flags;
1.127     christos  695:     int ac;
1.118     sjg       696:     int i;
                    697:
                    698:     if (isExport && (!str || !str[0])) {
                    699:        var_exportedVars = VAR_EXPORTED_ALL; /* use with caution! */
                    700:        return;
                    701:     }
                    702:
1.203     sjg       703:     flags = 0;
1.159     sjg       704:     if (strncmp(str, "-env", 4) == 0) {
                    705:        str += 4;
1.203     sjg       706:     } else if (strncmp(str, "-literal", 8) == 0) {
                    707:        str += 8;
                    708:        flags |= VAR_EXPORT_LITERAL;
1.159     sjg       709:     } else {
1.203     sjg       710:        flags |= VAR_EXPORT_PARENT;
1.159     sjg       711:     }
1.259     rillig    712:     val = Var_Subst(NULL, str, VAR_GLOBAL, VARE_WANTRES);
1.200     sjg       713:     if (*val) {
                    714:        av = brk_string(val, &ac, FALSE, &as);
                    715:        for (i = 0; i < ac; i++) {
                    716:            name = av[i];
                    717:            if (!name[1]) {
                    718:                /*
                    719:                 * A single char.
                    720:                 * If it is one of the vars that should only appear in
                    721:                 * local context, skip it, else we can get Var_Subst
                    722:                 * into a loop.
                    723:                 */
                    724:                switch (name[0]) {
                    725:                case '@':
                    726:                case '%':
                    727:                case '*':
                    728:                case '!':
                    729:                    continue;
                    730:                }
1.118     sjg       731:            }
1.203     sjg       732:            if (Var_Export1(name, flags)) {
1.200     sjg       733:                if (VAR_EXPORTED_ALL != var_exportedVars)
                    734:                    var_exportedVars = VAR_EXPORTED_YES;
1.203     sjg       735:                if (isExport && (flags & VAR_EXPORT_PARENT)) {
1.200     sjg       736:                    Var_Append(MAKE_EXPORTED, name, VAR_GLOBAL);
                    737:                }
1.118     sjg       738:            }
                    739:        }
1.200     sjg       740:        free(as);
                    741:        free(av);
1.118     sjg       742:     }
                    743:     free(val);
                    744: }
                    745:
1.155     sjg       746:
1.257     rillig    747: extern char **environ;
                    748:
1.155     sjg       749: /*
                    750:  * This is called when .unexport[-env] is seen.
                    751:  */
                    752: void
                    753: Var_UnExport(char *str)
                    754: {
                    755:     char tmp[BUFSIZ];
                    756:     char *vlist;
                    757:     char *cp;
                    758:     Boolean unexport_env;
                    759:     int n;
                    760:
1.257     rillig    761:     if (str == NULL || str[0] == '\0')
1.242     rillig    762:        return;                 /* assert? */
1.155     sjg       763:
                    764:     vlist = NULL;
                    765:
                    766:     str += 8;
                    767:     unexport_env = (strncmp(str, "-env", 4) == 0);
                    768:     if (unexport_env) {
                    769:        char **newenv;
                    770:
1.179     sjg       771:        cp = getenv(MAKE_LEVEL_ENV);    /* we should preserve this */
1.170     sjg       772:        if (environ == savedEnv) {
1.155     sjg       773:            /* we have been here before! */
                    774:            newenv = bmake_realloc(environ, 2 * sizeof(char *));
                    775:        } else {
1.170     sjg       776:            if (savedEnv) {
                    777:                free(savedEnv);
                    778:                savedEnv = NULL;
1.155     sjg       779:            }
                    780:            newenv = bmake_malloc(2 * sizeof(char *));
                    781:        }
                    782:        if (!newenv)
                    783:            return;
                    784:        /* Note: we cannot safely free() the original environ. */
1.170     sjg       785:        environ = savedEnv = newenv;
1.155     sjg       786:        newenv[0] = NULL;
                    787:        newenv[1] = NULL;
1.221     sjg       788:        if (cp && *cp)
                    789:            setenv(MAKE_LEVEL_ENV, cp, 1);
1.155     sjg       790:     } else {
                    791:        for (; *str != '\n' && isspace((unsigned char) *str); str++)
                    792:            continue;
                    793:        if (str[0] && str[0] != '\n') {
                    794:            vlist = str;
                    795:        }
                    796:     }
                    797:
                    798:     if (!vlist) {
                    799:        /* Using .MAKE.EXPORTED */
1.257     rillig    800:        vlist = Var_Subst(NULL, "${" MAKE_EXPORTED ":O:u}", VAR_GLOBAL,
1.259     rillig    801:                          VARE_WANTRES);
1.155     sjg       802:     }
                    803:     if (vlist) {
                    804:        Var *v;
                    805:        char **av;
                    806:        char *as;
                    807:        int ac;
                    808:        int i;
                    809:
                    810:        av = brk_string(vlist, &ac, FALSE, &as);
                    811:        for (i = 0; i < ac; i++) {
                    812:            v = VarFind(av[i], VAR_GLOBAL, 0);
                    813:            if (!v)
                    814:                continue;
                    815:            if (!unexport_env &&
1.257     rillig    816:                (v->flags & (VAR_EXPORTED|VAR_REEXPORT)) == VAR_EXPORTED)
                    817:            {
1.155     sjg       818:                unsetenv(v->name);
                    819:            }
                    820:            v->flags &= ~(VAR_EXPORTED|VAR_REEXPORT);
                    821:            /*
                    822:             * If we are unexporting a list,
                    823:             * remove each one from .MAKE.EXPORTED.
                    824:             * If we are removing them all,
                    825:             * just delete .MAKE.EXPORTED below.
                    826:             */
                    827:            if (vlist == str) {
                    828:                n = snprintf(tmp, sizeof(tmp),
                    829:                             "${" MAKE_EXPORTED ":N%s}", v->name);
                    830:                if (n < (int)sizeof(tmp)) {
1.259     rillig    831:                    cp = Var_Subst(NULL, tmp, VAR_GLOBAL, VARE_WANTRES);
1.230     rillig    832:                    Var_Set(MAKE_EXPORTED, cp, VAR_GLOBAL);
1.155     sjg       833:                    free(cp);
                    834:                }
                    835:            }
                    836:        }
                    837:        free(as);
                    838:        free(av);
                    839:        if (vlist != str) {
                    840:            Var_Delete(MAKE_EXPORTED, VAR_GLOBAL);
                    841:            free(vlist);
                    842:        }
                    843:     }
                    844: }
                    845:
1.230     rillig    846: static void
1.242     rillig    847: Var_Set_with_flags(const char *name, const char *val, GNode *ctxt,
                    848:                   VarSet_Flags flags)
1.1       cgd       849: {
1.249     rillig    850:     Var *v;
1.139     dsl       851:     char *expanded_name = NULL;
1.142     dsl       852:
1.1       cgd       853:     /*
                    854:      * We only look for a variable in the given context since anything set
                    855:      * here will override anything in a lower context, so there's not much
                    856:      * point in searching them all just to save a bit of memory...
                    857:      */
1.139     dsl       858:     if (strchr(name, '$') != NULL) {
1.259     rillig    859:        expanded_name = Var_Subst(NULL, name, ctxt, VARE_WANTRES);
1.257     rillig    860:        if (expanded_name[0] == '\0') {
1.139     dsl       861:            if (DEBUG(VAR)) {
                    862:                fprintf(debug_file, "Var_Set(\"%s\", \"%s\", ...) "
                    863:                        "name expands to empty string - ignored\n",
                    864:                        name, val);
                    865:            }
                    866:            free(expanded_name);
                    867:            return;
                    868:        }
                    869:        name = expanded_name;
                    870:     }
1.129     sjg       871:     if (ctxt == VAR_GLOBAL) {
                    872:        v = VarFind(name, VAR_CMD, 0);
1.136     dsl       873:        if (v != NULL) {
1.131     sjg       874:            if ((v->flags & VAR_FROM_CMD)) {
                    875:                if (DEBUG(VAR)) {
                    876:                    fprintf(debug_file, "%s:%s = %s ignored!\n", ctxt->name, name, val);
                    877:                }
                    878:                goto out;
                    879:            }
                    880:            VarFreeEnv(v, TRUE);
1.129     sjg       881:        }
                    882:     }
1.92      christos  883:     v = VarFind(name, ctxt, 0);
1.136     dsl       884:     if (v == NULL) {
1.183     sjg       885:        if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) {
                    886:            /*
                    887:             * This var would normally prevent the same name being added
                    888:             * to VAR_GLOBAL, so delete it from there if needed.
                    889:             * Otherwise -V name may show the wrong value.
                    890:             */
                    891:            Var_Delete(name, VAR_GLOBAL);
                    892:        }
1.92      christos  893:        VarAdd(name, val, ctxt);
1.1       cgd       894:     } else {
1.146     dsl       895:        Buf_Empty(&v->val);
1.218     sjg       896:        if (val)
                    897:            Buf_AddBytes(&v->val, strlen(val), val);
1.1       cgd       898:
                    899:        if (DEBUG(VAR)) {
1.114     dsl       900:            fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val);
1.1       cgd       901:        }
1.118     sjg       902:        if ((v->flags & VAR_EXPORTED)) {
1.152     sjg       903:            Var_Export1(name, VAR_EXPORT_PARENT);
1.118     sjg       904:        }
1.1       cgd       905:     }
                    906:     /*
                    907:      * Any variables given on the command line are automatically exported
                    908:      * to the environment (as per POSIX standard)
                    909:      */
1.65      sjg       910:     if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) {
1.136     dsl       911:        if (v == NULL) {
1.131     sjg       912:            /* we just added it */
                    913:            v = VarFind(name, ctxt, 0);
                    914:        }
1.151     christos  915:        if (v != NULL)
1.150     christos  916:            v->flags |= VAR_FROM_CMD;
1.71      thorpej   917:        /*
                    918:         * If requested, don't export these in the environment
                    919:         * individually.  We still put them in MAKEOVERRIDES so
                    920:         * that the command-line settings continue to override
                    921:         * Makefile settings.
                    922:         */
                    923:        if (varNoExportEnv != TRUE)
1.218     sjg       924:            setenv(name, val ? val : "", 1);
1.62      sjg       925:
1.64      sjg       926:        Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL);
1.1       cgd       927:     }
1.205     sjg       928:     if (*name == '.') {
                    929:        if (strcmp(name, SAVE_DOLLARS) == 0)
                    930:            save_dollars = s2Boolean(val, save_dollars);
                    931:     }
                    932:
1.242     rillig    933: out:
1.196     christos  934:     free(expanded_name);
1.136     dsl       935:     if (v != NULL)
1.107     christos  936:        VarFreeEnv(v, TRUE);
1.1       cgd       937: }
                    938:
                    939: /*-
                    940:  *-----------------------------------------------------------------------
1.230     rillig    941:  * Var_Set --
                    942:  *     Set the variable name to the value val in the given context.
                    943:  *
                    944:  * Input:
                    945:  *     name            name of variable to set
                    946:  *     val             value to give to the variable
                    947:  *     ctxt            context in which to set it
                    948:  *
                    949:  * Side Effects:
                    950:  *     If the variable doesn't yet exist, a new record is created for it.
                    951:  *     Else the old value is freed and the new one stuck in its place
                    952:  *
                    953:  * Notes:
                    954:  *     The variable is searched for only in its context before being
                    955:  *     created in that context. I.e. if the context is VAR_GLOBAL,
                    956:  *     only VAR_GLOBAL->context is searched. Likewise if it is VAR_CMD, only
                    957:  *     VAR_CMD->context is searched. This is done to avoid the literally
                    958:  *     thousands of unnecessary strcmp's that used to be done to
                    959:  *     set, say, $(@) or $(<).
                    960:  *     If the context is VAR_GLOBAL though, we check if the variable
                    961:  *     was set in VAR_CMD from the command line and skip it if so.
                    962:  *-----------------------------------------------------------------------
                    963:  */
                    964: void
                    965: Var_Set(const char *name, const char *val, GNode *ctxt)
                    966: {
1.242     rillig    967:     Var_Set_with_flags(name, val, ctxt, 0);
1.230     rillig    968: }
                    969:
                    970: /*-
                    971:  *-----------------------------------------------------------------------
1.1       cgd       972:  * Var_Append --
                    973:  *     The variable of the given name has the given value appended to it in
                    974:  *     the given context.
                    975:  *
1.70      wiz       976:  * Input:
                    977:  *     name            name of variable to modify
                    978:  *     val             String to append to it
                    979:  *     ctxt            Context in which this should occur
                    980:  *
1.1       cgd       981:  * Side Effects:
                    982:  *     If the variable doesn't exist, it is created. Else the strings
                    983:  *     are concatenated (with a space in between).
                    984:  *
                    985:  * Notes:
                    986:  *     Only if the variable is being sought in the global context is the
                    987:  *     environment searched.
                    988:  *     XXX: Knows its calling circumstances in that if called with ctxt
                    989:  *     an actual target, it will only search that context since only
                    990:  *     a local variable could be being appended to. This is actually
                    991:  *     a big win and must be tolerated.
                    992:  *-----------------------------------------------------------------------
                    993:  */
                    994: void
1.73      christos  995: Var_Append(const char *name, const char *val, GNode *ctxt)
1.1       cgd       996: {
1.249     rillig    997:     Var *v;
                    998:     Hash_Entry *h;
1.139     dsl       999:     char *expanded_name = NULL;
1.1       cgd      1000:
1.139     dsl      1001:     if (strchr(name, '$') != NULL) {
1.259     rillig   1002:        expanded_name = Var_Subst(NULL, name, ctxt, VARE_WANTRES);
1.257     rillig   1003:        if (expanded_name[0] == '\0') {
1.139     dsl      1004:            if (DEBUG(VAR)) {
                   1005:                fprintf(debug_file, "Var_Append(\"%s\", \"%s\", ...) "
                   1006:                        "name expands to empty string - ignored\n",
                   1007:                        name, val);
                   1008:            }
                   1009:            free(expanded_name);
                   1010:            return;
                   1011:        }
                   1012:        name = expanded_name;
                   1013:     }
1.142     dsl      1014:
1.260     rillig   1015:     v = VarFind(name, ctxt, ctxt == VAR_GLOBAL ? (FIND_CMD | FIND_ENV) : 0);
1.1       cgd      1016:
1.136     dsl      1017:     if (v == NULL) {
1.230     rillig   1018:        Var_Set(name, val, ctxt);
1.217     sjg      1019:     } else if (ctxt == VAR_CMD || !(v->flags & VAR_FROM_CMD)) {
1.146     dsl      1020:        Buf_AddByte(&v->val, ' ');
                   1021:        Buf_AddBytes(&v->val, strlen(val), val);
1.1       cgd      1022:
                   1023:        if (DEBUG(VAR)) {
1.114     dsl      1024:            fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name,
1.242     rillig   1025:                    Buf_GetAll(&v->val, NULL));
1.1       cgd      1026:        }
                   1027:
                   1028:        if (v->flags & VAR_FROM_ENV) {
                   1029:            /*
                   1030:             * If the original variable came from the environment, we
                   1031:             * have to install it in the global context (we could place
                   1032:             * it in the environment, but then we should provide a way to
                   1033:             * export other variables...)
                   1034:             */
                   1035:            v->flags &= ~VAR_FROM_ENV;
1.92      christos 1036:            h = Hash_CreateEntry(&ctxt->context, name, NULL);
1.36      mycroft  1037:            Hash_SetValue(h, v);
1.1       cgd      1038:        }
                   1039:     }
1.196     christos 1040:     free(expanded_name);
1.1       cgd      1041: }
                   1042:
                   1043: /*-
                   1044:  *-----------------------------------------------------------------------
                   1045:  * Var_Exists --
                   1046:  *     See if the given variable exists.
                   1047:  *
1.70      wiz      1048:  * Input:
                   1049:  *     name            Variable to find
                   1050:  *     ctxt            Context in which to start search
                   1051:  *
1.1       cgd      1052:  * Results:
                   1053:  *     TRUE if it does, FALSE if it doesn't
                   1054:  *
                   1055:  * Side Effects:
                   1056:  *     None.
                   1057:  *
                   1058:  *-----------------------------------------------------------------------
                   1059:  */
                   1060: Boolean
1.73      christos 1061: Var_Exists(const char *name, GNode *ctxt)
1.1       cgd      1062: {
1.138     dsl      1063:     Var                  *v;
1.128     sjg      1064:     char          *cp;
1.1       cgd      1065:
1.257     rillig   1066:     if ((cp = strchr(name, '$')) != NULL)
1.259     rillig   1067:        cp = Var_Subst(NULL, name, ctxt, VARE_WANTRES);
1.260     rillig   1068:     v = VarFind(cp ? cp : name, ctxt, FIND_CMD | FIND_GLOBAL | FIND_ENV);
1.196     christos 1069:     free(cp);
1.257     rillig   1070:     if (v == NULL)
1.231     rillig   1071:        return FALSE;
                   1072:
                   1073:     (void)VarFreeEnv(v, TRUE);
                   1074:     return TRUE;
1.1       cgd      1075: }
                   1076:
                   1077: /*-
                   1078:  *-----------------------------------------------------------------------
                   1079:  * Var_Value --
                   1080:  *     Return the value of the named variable in the given context
                   1081:  *
1.70      wiz      1082:  * Input:
                   1083:  *     name            name to find
                   1084:  *     ctxt            context in which to search for it
                   1085:  *
1.1       cgd      1086:  * Results:
                   1087:  *     The value if the variable exists, NULL if it doesn't
                   1088:  *
                   1089:  * Side Effects:
                   1090:  *     None
                   1091:  *-----------------------------------------------------------------------
                   1092:  */
                   1093: char *
1.73      christos 1094: Var_Value(const char *name, GNode *ctxt, char **frp)
1.1       cgd      1095: {
1.257     rillig   1096:     Var *v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
1.6       jtc      1097:     *frp = NULL;
1.231     rillig   1098:     if (v == NULL)
1.136     dsl      1099:        return NULL;
1.231     rillig   1100:
1.257     rillig   1101:     char *p = Buf_GetAll(&v->val, NULL);
1.231     rillig   1102:     if (VarFreeEnv(v, FALSE))
                   1103:        *frp = p;
                   1104:     return p;
1.1       cgd      1105: }
                   1106:
1.244     rillig   1107:
1.278     rillig   1108: /* SepBuf is a string being built from "words", interleaved with separators. */
                   1109: typedef struct {
                   1110:     Buffer buf;
                   1111:     Boolean needSep;
                   1112:     char sep;
                   1113: } SepBuf;
                   1114:
                   1115: static void
                   1116: SepBuf_Init(SepBuf *buf, char sep)
                   1117: {
                   1118:     Buf_Init(&buf->buf, 32 /* bytes */);
                   1119:     buf->needSep = FALSE;
                   1120:     buf->sep = sep;
                   1121: }
                   1122:
                   1123: static void
                   1124: SepBuf_Sep(SepBuf *buf)
                   1125: {
                   1126:     buf->needSep = TRUE;
                   1127: }
                   1128:
                   1129: static void
                   1130: SepBuf_AddBytes(SepBuf *buf, const void *mem, size_t mem_size)
                   1131: {
                   1132:     if (mem_size == 0)
                   1133:        return;
                   1134:     if (buf->needSep && buf->sep != '\0') {
                   1135:        Buf_AddByte(&buf->buf, buf->sep);
                   1136:        buf->needSep = FALSE;
                   1137:     }
                   1138:     Buf_AddBytes(&buf->buf, mem_size, mem);
                   1139: }
                   1140:
                   1141: static char *
                   1142: SepBuf_Destroy(SepBuf *buf, Boolean free_buf)
                   1143: {
                   1144:     return Buf_Destroy(&buf->buf, free_buf);
                   1145: }
                   1146:
                   1147:
1.244     rillig   1148: /* This callback for VarModify gets a single word from an expression and
                   1149:  * typically adds a modification of this word to the buffer. It may also do
1.278     rillig   1150:  * nothing or add several words. */
                   1151: typedef void (*VarModifyCallback)(GNode *ctxt, const char *word, SepBuf *buf,
                   1152:                                  void *data);
1.244     rillig   1153:
                   1154:
                   1155: /* Callback function for VarModify to implement the :H modifier.
                   1156:  * Add the dirname of the given word to the buffer. */
1.278     rillig   1157: static void
                   1158: VarHead(GNode *ctx MAKE_ATTR_UNUSED, const char *word, SepBuf *buf,
1.214     riastrad 1159:        void *dummy MAKE_ATTR_UNUSED)
1.1       cgd      1160: {
1.238     rillig   1161:     const char *slash = strrchr(word, '/');
                   1162:     if (slash != NULL)
1.278     rillig   1163:        SepBuf_AddBytes(buf, word, slash - word);
1.238     rillig   1164:     else
1.278     rillig   1165:        SepBuf_AddBytes(buf, ".", 1);
1.1       cgd      1166: }
                   1167:
1.244     rillig   1168: /* Callback function for VarModify to implement the :T modifier.
                   1169:  * Add the basename of the given word to the buffer. */
1.278     rillig   1170: static void
                   1171: VarTail(GNode *ctx MAKE_ATTR_UNUSED, const char *word, SepBuf *buf,
1.214     riastrad 1172:        void *dummy MAKE_ATTR_UNUSED)
1.1       cgd      1173: {
1.238     rillig   1174:     const char *slash = strrchr(word, '/');
                   1175:     const char *base = slash != NULL ? slash + 1 : word;
1.278     rillig   1176:     SepBuf_AddBytes(buf, base, strlen(base));
1.1       cgd      1177: }
                   1178:
1.244     rillig   1179: /* Callback function for VarModify to implement the :E modifier.
                   1180:  * Add the filename suffix of the given word to the buffer, if it exists. */
1.278     rillig   1181: static void
                   1182: VarSuffix(GNode *ctx MAKE_ATTR_UNUSED, const char *word, SepBuf *buf,
1.214     riastrad 1183:          void *dummy MAKE_ATTR_UNUSED)
1.1       cgd      1184: {
1.239     rillig   1185:     const char *dot = strrchr(word, '.');
1.278     rillig   1186:     if (dot != NULL)
                   1187:        SepBuf_AddBytes(buf, dot + 1, strlen(dot + 1));
1.1       cgd      1188: }
                   1189:
1.244     rillig   1190: /* Callback function for VarModify to implement the :R modifier.
                   1191:  * Add the filename basename of the given word to the buffer. */
1.278     rillig   1192: static void
                   1193: VarRoot(GNode *ctx MAKE_ATTR_UNUSED, const char *word, SepBuf *buf,
1.214     riastrad 1194:        void *dummy MAKE_ATTR_UNUSED)
1.1       cgd      1195: {
1.239     rillig   1196:     char *dot = strrchr(word, '.');
1.247     lukem    1197:     size_t len = dot != NULL ? (size_t)(dot - word) : strlen(word);
1.278     rillig   1198:     SepBuf_AddBytes(buf, word, len);
1.1       cgd      1199: }
                   1200:
1.244     rillig   1201: /* Callback function for VarModify to implement the :M modifier.
                   1202:  * Place the word in the buffer if it matches the given pattern. */
1.278     rillig   1203: static void
                   1204: VarMatch(GNode *ctx MAKE_ATTR_UNUSED, const char *word, SepBuf *buf,
1.244     rillig   1205:         void *data)
1.1       cgd      1206: {
1.244     rillig   1207:     const char *pattern = data;
1.137     christos 1208:     if (DEBUG(VAR))
1.244     rillig   1209:        fprintf(debug_file, "VarMatch [%s] [%s]\n", word, pattern);
1.278     rillig   1210:     if (Str_Match(word, pattern))
                   1211:        SepBuf_AddBytes(buf, word, strlen(word));
1.1       cgd      1212: }
                   1213:
1.13      christos 1214: #ifdef SYSVVARSUB
1.256     rillig   1215: /*-
                   1216:  *-----------------------------------------------------------------------
                   1217:  * Str_SYSVMatch --
                   1218:  *     Check word against pattern for a match (% is wild),
                   1219:  *
                   1220:  * Input:
                   1221:  *     word            Word to examine
                   1222:  *     pattern         Pattern to examine against
                   1223:  *     len             Number of characters to substitute
                   1224:  *
                   1225:  * Results:
                   1226:  *     Returns the beginning position of a match or null. The number
                   1227:  *     of characters matched is returned in len.
                   1228:  *-----------------------------------------------------------------------
                   1229:  */
1.277     rillig   1230: static const char *
1.256     rillig   1231: Str_SYSVMatch(const char *word, const char *pattern, size_t *len,
                   1232:     Boolean *hasPercent)
                   1233: {
                   1234:     const char *p = pattern;
                   1235:     const char *w = word;
                   1236:     const char *m;
                   1237:
                   1238:     *hasPercent = FALSE;
                   1239:     if (*p == '\0') {
                   1240:        /* Null pattern is the whole string */
                   1241:        *len = strlen(w);
1.277     rillig   1242:        return w;
1.256     rillig   1243:     }
                   1244:
                   1245:     if ((m = strchr(p, '%')) != NULL) {
                   1246:        *hasPercent = TRUE;
                   1247:        if (*w == '\0') {
                   1248:                /* empty word does not match pattern */
                   1249:                return NULL;
                   1250:        }
                   1251:        /* check that the prefix matches */
                   1252:        for (; p != m && *w && *w == *p; w++, p++)
                   1253:             continue;
                   1254:
                   1255:        if (p != m)
                   1256:            return NULL;        /* No match */
                   1257:
                   1258:        if (*++p == '\0') {
                   1259:            /* No more pattern, return the rest of the string */
                   1260:            *len = strlen(w);
1.277     rillig   1261:            return w;
1.256     rillig   1262:        }
                   1263:     }
                   1264:
                   1265:     m = w;
                   1266:
                   1267:     /* Find a matching tail */
1.277     rillig   1268:     do {
1.256     rillig   1269:        if (strcmp(p, w) == 0) {
                   1270:            *len = w - m;
1.277     rillig   1271:            return m;
1.256     rillig   1272:        }
1.277     rillig   1273:     } while (*w++ != '\0');
1.256     rillig   1274:
                   1275:     return NULL;
                   1276: }
                   1277:
                   1278:
                   1279: /*-
                   1280:  *-----------------------------------------------------------------------
                   1281:  * Str_SYSVSubst --
                   1282:  *     Substitute '%' on the pattern with len characters from src.
                   1283:  *     If the pattern does not contain a '%' prepend len characters
                   1284:  *     from src.
                   1285:  *
                   1286:  * Side Effects:
                   1287:  *     Places result on buf
                   1288:  *-----------------------------------------------------------------------
                   1289:  */
                   1290: static void
1.278     rillig   1291: Str_SYSVSubst(SepBuf *buf, const char *pat, const char *src, size_t len,
                   1292:              Boolean lhsHasPercent)
1.256     rillig   1293: {
                   1294:     const char *m;
                   1295:
                   1296:     if ((m = strchr(pat, '%')) != NULL && lhsHasPercent) {
                   1297:        /* Copy the prefix */
1.278     rillig   1298:        SepBuf_AddBytes(buf, pat, m - pat);
1.256     rillig   1299:        /* skip the % */
                   1300:        pat = m + 1;
                   1301:     }
                   1302:     if (m != NULL || !lhsHasPercent) {
                   1303:        /* Copy the pattern */
1.278     rillig   1304:        SepBuf_AddBytes(buf, src, len);
1.256     rillig   1305:     }
                   1306:
                   1307:     /* append the rest */
1.278     rillig   1308:     SepBuf_AddBytes(buf, pat, strlen(pat));
1.256     rillig   1309: }
                   1310:
                   1311:
1.276     rillig   1312: typedef struct {
                   1313:     const char *lhs;
                   1314:     const char *rhs;
                   1315: } VarSYSVSubstArgs;
                   1316:
1.244     rillig   1317: /* Callback function for VarModify to implement the :%.from=%.to modifier. */
1.278     rillig   1318: static void
                   1319: VarSYSVSubst(GNode *ctx, const char *word, SepBuf *buf, void *data)
1.5       cgd      1320: {
1.276     rillig   1321:     const VarSYSVSubstArgs *args = data;
1.5       cgd      1322:
1.276     rillig   1323:     size_t len;
                   1324:     Boolean hasPercent;
                   1325:     const char *ptr = Str_SYSVMatch(word, args->lhs, &len, &hasPercent);
                   1326:     if (ptr != NULL) {
                   1327:        char *varexp = Var_Subst(NULL, args->rhs, ctx, VARE_WANTRES);
1.223     christos 1328:        Str_SYSVSubst(buf, varexp, ptr, len, hasPercent);
1.61      explorer 1329:        free(varexp);
                   1330:     } else {
1.278     rillig   1331:        SepBuf_AddBytes(buf, word, strlen(word));
1.61      explorer 1332:     }
1.5       cgd      1333: }
1.13      christos 1334: #endif
1.5       cgd      1335:
1.244     rillig   1336: /* Callback function for VarModify to implement the :N modifier.
                   1337:  * Place the word in the buffer if it doesn't match the given pattern. */
1.278     rillig   1338: static void
                   1339: VarNoMatch(GNode *ctx MAKE_ATTR_UNUSED, const char *word, SepBuf *buf,
1.244     rillig   1340:           void *data)
1.1       cgd      1341: {
1.244     rillig   1342:     const char *pattern = data;
1.278     rillig   1343:     if (!Str_Match(word, pattern))
                   1344:        SepBuf_AddBytes(buf, word, strlen(word));
1.1       cgd      1345: }
                   1346:
1.244     rillig   1347: /* Callback function for VarModify to implement the :S,from,to, modifier.
                   1348:  * Perform a string substitution on the given word. */
1.278     rillig   1349: static void
                   1350: VarSubstitute(GNode *ctx MAKE_ATTR_UNUSED, const char *word, SepBuf *buf,
1.244     rillig   1351:              void *data)
1.1       cgd      1352: {
1.279     rillig   1353:     size_t wordLen = strlen(word);
1.281     rillig   1354:     VarSubstituteArgs *args = data;
                   1355:     const VarPatternFlags pflags = args->pflags;
1.1       cgd      1356:
1.279     rillig   1357:     if ((pflags & (VARP_SUB_ONE | VARP_SUB_MATCHED)) ==
                   1358:        (VARP_SUB_ONE | VARP_SUB_MATCHED))
                   1359:        goto nosub;
                   1360:
1.281     rillig   1361:     if (args->pflags & VARP_MATCH_START) {
1.282     rillig   1362:        if (wordLen < args->lhsLen ||
                   1363:            memcmp(word, args->lhs, args->lhsLen) != 0)
1.1       cgd      1364:            goto nosub;
1.279     rillig   1365:
1.281     rillig   1366:        if (args->pflags & VARP_MATCH_END) {
                   1367:            if (wordLen != args->lhsLen)
1.1       cgd      1368:                goto nosub;
1.279     rillig   1369:
1.281     rillig   1370:            SepBuf_AddBytes(buf, args->rhs, args->rhsLen);
                   1371:            args->pflags |= VARP_SUB_MATCHED;
1.1       cgd      1372:        } else {
1.281     rillig   1373:            SepBuf_AddBytes(buf, args->rhs, args->rhsLen);
                   1374:            SepBuf_AddBytes(buf, word + args->lhsLen, wordLen - args->lhsLen);
                   1375:            args->pflags |= VARP_SUB_MATCHED;
1.1       cgd      1376:        }
1.278     rillig   1377:        return;
1.1       cgd      1378:     }
1.279     rillig   1379:
1.281     rillig   1380:     if (args->pflags & VARP_MATCH_END) {
                   1381:        if (wordLen < args->lhsLen)
1.280     rillig   1382:            goto nosub;
1.281     rillig   1383:        const char *start = word + (wordLen - args->lhsLen);
                   1384:        if (memcmp(start, args->lhs, args->lhsLen) != 0)
1.279     rillig   1385:            goto nosub;
                   1386:
1.280     rillig   1387:        SepBuf_AddBytes(buf, word, start - word);
1.281     rillig   1388:        SepBuf_AddBytes(buf, args->rhs, args->rhsLen);
                   1389:        args->pflags |= VARP_SUB_MATCHED;
1.279     rillig   1390:        return;
                   1391:     }
                   1392:
                   1393:     /* unanchored */
                   1394:     const char *cp;
1.281     rillig   1395:     while ((cp = Str_FindSubstring(word, args->lhs)) != NULL) {
1.279     rillig   1396:        SepBuf_AddBytes(buf, word, cp - word);
1.281     rillig   1397:        SepBuf_AddBytes(buf, args->rhs, args->rhsLen);
                   1398:        wordLen -= (cp - word) + args->lhsLen;
                   1399:        word = cp + args->lhsLen;
                   1400:        if (wordLen == 0 || !(args->pflags & VARP_SUB_GLOBAL))
1.279     rillig   1401:            break;
1.281     rillig   1402:        args->pflags |= VARP_SUB_MATCHED;
1.279     rillig   1403:     }
1.242     rillig   1404: nosub:
1.278     rillig   1405:     SepBuf_AddBytes(buf, word, wordLen);
1.1       cgd      1406: }
                   1407:
1.31      gwr      1408: #ifndef NO_REGEX
1.16      christos 1409: /*-
                   1410:  *-----------------------------------------------------------------------
                   1411:  * VarREError --
                   1412:  *     Print the error caused by a regcomp or regexec call.
                   1413:  *
                   1414:  * Side Effects:
                   1415:  *     An error gets printed.
                   1416:  *
                   1417:  *-----------------------------------------------------------------------
                   1418:  */
                   1419: static void
1.202     christos 1420: VarREError(int reerr, regex_t *pat, const char *str)
1.16      christos 1421: {
                   1422:     char *errbuf;
1.127     christos 1423:     int errlen;
1.16      christos 1424:
1.202     christos 1425:     errlen = regerror(reerr, pat, 0, 0);
1.134     joerg    1426:     errbuf = bmake_malloc(errlen);
1.202     christos 1427:     regerror(reerr, pat, errbuf, errlen);
1.16      christos 1428:     Error("%s: %s", str, errbuf);
                   1429:     free(errbuf);
                   1430: }
                   1431:
1.244     rillig   1432: /* Callback function for VarModify to implement the :C/from/to/ modifier.
                   1433:  * Perform a regex substitution on the given word. */
1.278     rillig   1434: static void
                   1435: VarRESubstitute(GNode *ctx MAKE_ATTR_UNUSED, const char *word, SepBuf *buf,
1.244     rillig   1436:                void *data)
1.16      christos 1437: {
1.244     rillig   1438:     VarREPattern *pat = data;
1.16      christos 1439:     int xrv;
1.253     rillig   1440:     const char *wp = word;
1.16      christos 1441:     char *rp;
1.20      christos 1442:     int flags = 0;
1.16      christos 1443:
1.261     rillig   1444:     if ((pat->pflags & (VARP_SUB_ONE | VARP_SUB_MATCHED)) ==
                   1445:        (VARP_SUB_ONE | VARP_SUB_MATCHED))
1.16      christos 1446:        xrv = REG_NOMATCH;
                   1447:     else {
                   1448:     tryagain:
1.21      christos 1449:        xrv = regexec(&pat->re, wp, pat->nsub, pat->matches, flags);
1.16      christos 1450:     }
                   1451:
                   1452:     switch (xrv) {
                   1453:     case 0:
1.261     rillig   1454:        pat->pflags |= VARP_SUB_MATCHED;
1.278     rillig   1455:        SepBuf_AddBytes(buf, wp, pat->matches[0].rm_so);
1.16      christos 1456:
                   1457:        for (rp = pat->replace; *rp; rp++) {
1.278     rillig   1458:            if (*rp == '\\' && (rp[1] == '&' || rp[1] == '\\')) {
                   1459:                SepBuf_AddBytes(buf, rp + 1, 1);
1.16      christos 1460:                rp++;
1.278     rillig   1461:            } else if (*rp == '&' ||
                   1462:                (*rp == '\\' && isdigit((unsigned char)rp[1]))) {
1.16      christos 1463:                int n;
1.73      christos 1464:                const char *subbuf;
1.16      christos 1465:                int sublen;
                   1466:                char errstr[3];
                   1467:
                   1468:                if (*rp == '&') {
                   1469:                    n = 0;
                   1470:                    errstr[0] = '&';
                   1471:                    errstr[1] = '\0';
                   1472:                } else {
                   1473:                    n = rp[1] - '0';
                   1474:                    errstr[0] = '\\';
                   1475:                    errstr[1] = rp[1];
                   1476:                    errstr[2] = '\0';
                   1477:                    rp++;
                   1478:                }
                   1479:
1.271     rillig   1480:                if (n >= pat->nsub) {
1.16      christos 1481:                    Error("No subexpression %s", &errstr[0]);
                   1482:                    subbuf = "";
                   1483:                    sublen = 0;
                   1484:                } else if ((pat->matches[n].rm_so == -1) &&
                   1485:                           (pat->matches[n].rm_eo == -1)) {
                   1486:                    Error("No match for subexpression %s", &errstr[0]);
                   1487:                    subbuf = "";
                   1488:                    sublen = 0;
1.242     rillig   1489:                } else {
1.127     christos 1490:                    subbuf = wp + pat->matches[n].rm_so;
                   1491:                    sublen = pat->matches[n].rm_eo - pat->matches[n].rm_so;
1.16      christos 1492:                }
                   1493:
1.278     rillig   1494:                SepBuf_AddBytes(buf, subbuf, sublen);
1.16      christos 1495:            } else {
1.278     rillig   1496:                SepBuf_AddBytes(buf, rp, 1);
1.16      christos 1497:            }
                   1498:        }
1.127     christos 1499:        wp += pat->matches[0].rm_eo;
1.261     rillig   1500:        if (pat->pflags & VARP_SUB_GLOBAL) {
1.20      christos 1501:            flags |= REG_NOTBOL;
                   1502:            if (pat->matches[0].rm_so == 0 && pat->matches[0].rm_eo == 0) {
1.278     rillig   1503:                SepBuf_AddBytes(buf, wp, 1);
1.20      christos 1504:                wp++;
                   1505:            }
                   1506:            if (*wp)
                   1507:                goto tryagain;
                   1508:        }
1.16      christos 1509:        if (*wp) {
1.278     rillig   1510:            SepBuf_AddBytes(buf, wp, strlen(wp));
1.16      christos 1511:        }
                   1512:        break;
                   1513:     default:
                   1514:        VarREError(xrv, &pat->re, "Unexpected regex error");
1.242     rillig   1515:        /* fall through */
1.16      christos 1516:     case REG_NOMATCH:
1.278     rillig   1517:        SepBuf_AddBytes(buf, wp, strlen(wp));
1.16      christos 1518:        break;
                   1519:     }
                   1520: }
1.17      christos 1521: #endif
1.16      christos 1522:
                   1523:
1.267     rillig   1524: /* Callback for VarModify to implement the :@var@...@ modifier of ODE make. */
1.278     rillig   1525: static void
                   1526: VarLoopExpand(GNode *ctx, const char *word, SepBuf *buf, void *data)
1.40      sjg      1527: {
1.278     rillig   1528:     if (word[0] == '\0')
                   1529:        return;
                   1530:
                   1531:     const VarLoop *loop = data;
                   1532:     Var_Set_with_flags(loop->tvar, word, ctx, VAR_NO_EXPORT);
                   1533:     char *s = Var_Subst(NULL, loop->str, ctx, loop->eflags);
                   1534:     if (DEBUG(VAR)) {
                   1535:        fprintf(debug_file,
                   1536:                "VarLoopExpand: in \"%s\", replace \"%s\" with \"%s\" "
                   1537:                "to \"%s\"\n",
                   1538:                word, loop->tvar, loop->str, s ? s : "(null)");
                   1539:     }
1.64      sjg      1540:
1.278     rillig   1541:     if (s != NULL && s[0] != '\0') {
                   1542:        if (s[0] == '\n' || (buf->buf.count > 0 &&
                   1543:            buf->buf.buffer[buf->buf.count - 1] == '\n'))
                   1544:            buf->needSep = FALSE;
                   1545:        SepBuf_AddBytes(buf, s, strlen(s));
1.40      sjg      1546:     }
1.278     rillig   1547:     free(s);
1.40      sjg      1548: }
                   1549:
1.81      sjg      1550:
                   1551: /*-
                   1552:  *-----------------------------------------------------------------------
                   1553:  * VarSelectWords --
                   1554:  *     Implements the :[start..end] modifier.
                   1555:  *     This is a special case of VarModify since we want to be able
                   1556:  *     to scan the list backwards if start > end.
                   1557:  *
                   1558:  * Input:
                   1559:  *     str             String whose words should be trimmed
                   1560:  *     seldata         words to select
                   1561:  *
                   1562:  * Results:
                   1563:  *     A string of all the words selected.
                   1564:  *
                   1565:  * Side Effects:
                   1566:  *     None.
                   1567:  *
                   1568:  *-----------------------------------------------------------------------
                   1569:  */
                   1570: static char *
1.171     joerg    1571: VarSelectWords(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
1.81      sjg      1572:               const char *str, VarSelectWords_t *seldata)
                   1573: {
1.278     rillig   1574:     SepBuf buf;
1.240     rillig   1575:     char **av;                 /* word list */
                   1576:     char *as;                  /* word list memory */
1.127     christos 1577:     int ac, i;
1.81      sjg      1578:     int start, end, step;
1.142     dsl      1579:
1.278     rillig   1580:     SepBuf_Init(&buf, vpstate->varSpace);
1.81      sjg      1581:
                   1582:     if (vpstate->oneBigWord) {
                   1583:        /* fake what brk_string() would do if there were only one word */
                   1584:        ac = 1;
1.242     rillig   1585:        av = bmake_malloc((ac + 1) * sizeof(char *));
1.134     joerg    1586:        as = bmake_strdup(str);
1.81      sjg      1587:        av[0] = as;
                   1588:        av[1] = NULL;
                   1589:     } else {
                   1590:        av = brk_string(str, &ac, FALSE, &as);
                   1591:     }
                   1592:
                   1593:     /*
                   1594:      * Now sanitize seldata.
                   1595:      * If seldata->start or seldata->end are negative, convert them to
                   1596:      * the positive equivalents (-1 gets converted to argc, -2 gets
                   1597:      * converted to (argc-1), etc.).
                   1598:      */
                   1599:     if (seldata->start < 0)
                   1600:        seldata->start = ac + seldata->start + 1;
                   1601:     if (seldata->end < 0)
                   1602:        seldata->end = ac + seldata->end + 1;
                   1603:
                   1604:     /*
                   1605:      * We avoid scanning more of the list than we need to.
                   1606:      */
                   1607:     if (seldata->start > seldata->end) {
                   1608:        start = MIN(ac, seldata->start) - 1;
                   1609:        end = MAX(0, seldata->end - 1);
                   1610:        step = -1;
                   1611:     } else {
                   1612:        start = MAX(0, seldata->start - 1);
                   1613:        end = MIN(ac, seldata->end);
                   1614:        step = 1;
                   1615:     }
                   1616:
                   1617:     for (i = start;
                   1618:         (step < 0 && i >= end) || (step > 0 && i < end);
                   1619:         i += step) {
1.278     rillig   1620:        if (av[i][0] != '\0') {
                   1621:            SepBuf_AddBytes(&buf, av[i], strlen(av[i]));
                   1622:            SepBuf_Sep(&buf);
1.81      sjg      1623:        }
                   1624:     }
                   1625:
                   1626:     free(as);
                   1627:     free(av);
                   1628:
1.278     rillig   1629:     return SepBuf_Destroy(&buf, FALSE);
1.81      sjg      1630: }
                   1631:
1.156     sjg      1632:
1.244     rillig   1633: /* Callback function for VarModify to implement the :tA modifier.
                   1634:  * Replace each word with the result of realpath() if successful. */
1.278     rillig   1635: static void
                   1636: VarRealpath(GNode *ctx MAKE_ATTR_UNUSED, const char *word, SepBuf *buf,
1.171     joerg    1637:            void *patternp MAKE_ATTR_UNUSED)
1.156     sjg      1638: {
1.242     rillig   1639:     struct stat st;
                   1640:     char rbuf[MAXPATHLEN];
1.231     rillig   1641:
1.278     rillig   1642:     char *rp = cached_realpath(word, rbuf);
1.257     rillig   1643:     if (rp != NULL && *rp == '/' && stat(rp, &st) == 0)
1.242     rillig   1644:        word = rp;
1.231     rillig   1645:
1.278     rillig   1646:     SepBuf_AddBytes(buf, word, strlen(word));
1.156     sjg      1647: }
                   1648:
1.1       cgd      1649: /*-
                   1650:  *-----------------------------------------------------------------------
1.244     rillig   1651:  * Modify each of the words of the passed string using the given function.
1.1       cgd      1652:  *
1.70      wiz      1653:  * Input:
1.278     rillig   1654:  *     str             String whose words should be modified
                   1655:  *     modProc         Function that modifies a single word
1.244     rillig   1656:  *     data            Custom data for the modProc
1.70      wiz      1657:  *
1.1       cgd      1658:  * Results:
                   1659:  *     A string of all the words modified appropriately.
                   1660:  *-----------------------------------------------------------------------
                   1661:  */
                   1662: static char *
1.81      sjg      1663: VarModify(GNode *ctx, Var_Parse_State *vpstate,
1.278     rillig   1664:     const char *str, VarModifyCallback modProc, void *data)
1.1       cgd      1665: {
1.278     rillig   1666:     SepBuf result;
1.240     rillig   1667:     char **av;                 /* word list */
                   1668:     char *as;                  /* word list memory */
1.127     christos 1669:     int ac, i;
1.7       jtc      1670:
1.278     rillig   1671:     SepBuf_Init(&result, vpstate->varSpace);
1.1       cgd      1672:
1.81      sjg      1673:     if (vpstate->oneBigWord) {
                   1674:        /* fake what brk_string() would do if there were only one word */
                   1675:        ac = 1;
1.242     rillig   1676:        av = bmake_malloc((ac + 1) * sizeof(char *));
1.134     joerg    1677:        as = bmake_strdup(str);
1.81      sjg      1678:        av[0] = as;
                   1679:        av[1] = NULL;
                   1680:     } else {
                   1681:        av = brk_string(str, &ac, FALSE, &as);
                   1682:     }
1.1       cgd      1683:
1.255     rillig   1684:     if (DEBUG(VAR)) {
                   1685:        fprintf(debug_file, "VarModify: split \"%s\" into %d words\n",
                   1686:                str, ac);
                   1687:     }
                   1688:
1.278     rillig   1689:     for (i = 0; i < ac; i++) {
                   1690:        size_t orig_count = result.buf.count;
                   1691:        modProc(ctx, av[i], &result, data);
                   1692:        size_t count = result.buf.count;
                   1693:        if (count != orig_count)
                   1694:            SepBuf_Sep(&result);
                   1695:     }
1.24      christos 1696:
                   1697:     free(as);
                   1698:     free(av);
1.15      christos 1699:
1.278     rillig   1700:     vpstate->varSpace = result.sep;
                   1701:     return SepBuf_Destroy(&result, FALSE);
1.1       cgd      1702: }
                   1703:
1.35      christos 1704:
                   1705: static int
1.70      wiz      1706: VarWordCompare(const void *a, const void *b)
1.35      christos 1707: {
1.242     rillig   1708:     int r = strcmp(*(const char * const *)a, *(const char * const *)b);
                   1709:     return r;
1.35      christos 1710: }
                   1711:
1.224     sjg      1712: static int
                   1713: VarWordCompareReverse(const void *a, const void *b)
                   1714: {
1.242     rillig   1715:     int r = strcmp(*(const char * const *)b, *(const char * const *)a);
                   1716:     return r;
1.224     sjg      1717: }
                   1718:
1.35      christos 1719: /*-
                   1720:  *-----------------------------------------------------------------------
1.93      sjg      1721:  * VarOrder --
                   1722:  *     Order the words in the string.
1.35      christos 1723:  *
1.70      wiz      1724:  * Input:
1.93      sjg      1725:  *     str             String whose words should be sorted.
                   1726:  *     otype           How to order: s - sort, x - random.
1.70      wiz      1727:  *
1.35      christos 1728:  * Results:
1.93      sjg      1729:  *     A string containing the words ordered.
1.35      christos 1730:  *
                   1731:  * Side Effects:
                   1732:  *     None.
                   1733:  *
                   1734:  *-----------------------------------------------------------------------
                   1735:  */
                   1736: static char *
1.93      sjg      1737: VarOrder(const char *str, const char otype)
1.35      christos 1738: {
1.240     rillig   1739:     Buffer buf;                        /* Buffer for the new string */
                   1740:     char **av;                 /* word list [first word does not count] */
                   1741:     char *as;                  /* word list memory */
1.127     christos 1742:     int ac, i;
1.35      christos 1743:
1.146     dsl      1744:     Buf_Init(&buf, 0);
1.35      christos 1745:
                   1746:     av = brk_string(str, &ac, FALSE, &as);
                   1747:
1.240     rillig   1748:     if (ac > 0) {
1.93      sjg      1749:        switch (otype) {
1.240     rillig   1750:        case 'r':               /* reverse sort alphabetically */
1.224     sjg      1751:            qsort(av, ac, sizeof(char *), VarWordCompareReverse);
                   1752:            break;
1.240     rillig   1753:        case 's':               /* sort alphabetically */
1.93      sjg      1754:            qsort(av, ac, sizeof(char *), VarWordCompare);
                   1755:            break;
1.240     rillig   1756:        case 'x':               /* randomize */
                   1757:            {
                   1758:                /*
                   1759:                 * We will use [ac..2] range for mod factors. This will produce
                   1760:                 * random numbers in [(ac-1)..0] interval, and minimal
                   1761:                 * reasonable value for mod factor is 2 (the mod 1 will produce
                   1762:                 * 0 with probability 1).
                   1763:                 */
                   1764:                for (i = ac - 1; i > 0; i--) {
                   1765:                    int rndidx = random() % (i + 1);
                   1766:                    char *t = av[i];
1.93      sjg      1767:                    av[i] = av[rndidx];
                   1768:                    av[rndidx] = t;
                   1769:                }
                   1770:            }
                   1771:        }
1.240     rillig   1772:     }
1.35      christos 1773:
                   1774:     for (i = 0; i < ac; i++) {
1.146     dsl      1775:        Buf_AddBytes(&buf, strlen(av[i]), av[i]);
1.35      christos 1776:        if (i != ac - 1)
1.146     dsl      1777:            Buf_AddByte(&buf, ' ');
1.35      christos 1778:     }
                   1779:
                   1780:     free(as);
                   1781:     free(av);
                   1782:
1.146     dsl      1783:     return Buf_Destroy(&buf, FALSE);
1.35      christos 1784: }
                   1785:
                   1786:
1.1       cgd      1787: /*-
                   1788:  *-----------------------------------------------------------------------
1.55      christos 1789:  * VarUniq --
                   1790:  *     Remove adjacent duplicate words.
                   1791:  *
1.70      wiz      1792:  * Input:
                   1793:  *     str             String whose words should be sorted
                   1794:  *
1.55      christos 1795:  * Results:
                   1796:  *     A string containing the resulting words.
                   1797:  *
                   1798:  * Side Effects:
                   1799:  *     None.
                   1800:  *
                   1801:  *-----------------------------------------------------------------------
                   1802:  */
                   1803: static char *
1.73      christos 1804: VarUniq(const char *str)
1.55      christos 1805: {
1.240     rillig   1806:     Buffer       buf;          /* Buffer for new string */
                   1807:     char       **av;           /* List of words to affect */
                   1808:     char        *as;           /* Word list memory */
1.127     christos 1809:     int          ac, i, j;
1.55      christos 1810:
1.146     dsl      1811:     Buf_Init(&buf, 0);
1.55      christos 1812:     av = brk_string(str, &ac, FALSE, &as);
                   1813:
                   1814:     if (ac > 1) {
                   1815:        for (j = 0, i = 1; i < ac; i++)
                   1816:            if (strcmp(av[i], av[j]) != 0 && (++j != i))
                   1817:                av[j] = av[i];
                   1818:        ac = j + 1;
                   1819:     }
                   1820:
                   1821:     for (i = 0; i < ac; i++) {
1.146     dsl      1822:        Buf_AddBytes(&buf, strlen(av[i]), av[i]);
1.55      christos 1823:        if (i != ac - 1)
1.146     dsl      1824:            Buf_AddByte(&buf, ' ');
1.55      christos 1825:     }
                   1826:
                   1827:     free(as);
                   1828:     free(av);
                   1829:
1.146     dsl      1830:     return Buf_Destroy(&buf, FALSE);
1.55      christos 1831: }
                   1832:
1.210     sjg      1833: /*-
                   1834:  *-----------------------------------------------------------------------
                   1835:  * VarRange --
                   1836:  *     Return an integer sequence
                   1837:  *
                   1838:  * Input:
                   1839:  *     str             String whose words provide default range
                   1840:  *     ac              range length, if 0 use str words
                   1841:  *
                   1842:  * Side Effects:
                   1843:  *     None.
                   1844:  *
                   1845:  *-----------------------------------------------------------------------
                   1846:  */
                   1847: static char *
                   1848: VarRange(const char *str, int ac)
                   1849: {
1.240     rillig   1850:     Buffer       buf;          /* Buffer for new string */
                   1851:     char         tmp[32];      /* each element */
                   1852:     char       **av;           /* List of words to affect */
                   1853:     char        *as;           /* Word list memory */
1.210     sjg      1854:     int          i, n;
                   1855:
                   1856:     Buf_Init(&buf, 0);
                   1857:     if (ac > 0) {
                   1858:        as = NULL;
                   1859:        av = NULL;
                   1860:     } else {
                   1861:        av = brk_string(str, &ac, FALSE, &as);
                   1862:     }
                   1863:     for (i = 0; i < ac; i++) {
                   1864:        n = snprintf(tmp, sizeof(tmp), "%d", 1 + i);
                   1865:        if (n >= (int)sizeof(tmp))
                   1866:            break;
                   1867:        Buf_AddBytes(&buf, n, tmp);
                   1868:        if (i != ac - 1)
                   1869:            Buf_AddByte(&buf, ' ');
                   1870:     }
                   1871:
                   1872:     free(as);
                   1873:     free(av);
                   1874:
                   1875:     return Buf_Destroy(&buf, FALSE);
                   1876: }
                   1877:
1.55      christos 1878:
                   1879: /*-
1.265     rillig   1880:  * Parse a text part of a modifier such as the "from" and "to" in :S/from/to/
                   1881:  * or the :@ modifier. Nested variables in the text are expanded unless
                   1882:  * VAR_NOSUBST is set.
                   1883:  *
                   1884:  * The text part is parsed until the next delimiter.  To escape the delimiter,
                   1885:  * a backslash or a dollar, put a backslash before it.
                   1886:  *
                   1887:  * Return the expanded string or NULL if the delimiter was missing.
                   1888:  * If pattern is specified, handle escaped ampersands and replace unescaped
                   1889:  * ampersands with the lhs of the pattern (for the :S and :C modifiers).
                   1890:  *
                   1891:  * If length is specified, return the string length of the buffer.
                   1892:  * If mpflags is specified and the last character of the pattern is a $,
                   1893:  * set the VARP_MATCH_END bit of mpflags.
1.16      christos 1894:  */
                   1895: static char *
1.266     rillig   1896: ParseModifierPart(GNode *ctxt, const char **tstr, int delim,
                   1897:                  VarEvalFlags eflags, VarPatternFlags *mpflags,
1.281     rillig   1898:                  size_t *length, VarSubstituteArgs *subst)
1.16      christos 1899: {
1.73      christos 1900:     const char *cp;
1.146     dsl      1901:     char *rstr;
                   1902:     Buffer buf;
1.281     rillig   1903:     size_t junk;
1.261     rillig   1904:     VarEvalFlags errnum = eflags & VARE_UNDEFERR;
1.146     dsl      1905:
                   1906:     Buf_Init(&buf, 0);
1.16      christos 1907:     if (length == NULL)
                   1908:        length = &junk;
                   1909:
                   1910:     /*
                   1911:      * Skim through until the matching delimiter is found;
                   1912:      * pick up variable substitutions on the way. Also allow
                   1913:      * backslashes to quote the delimiter, $, and \, but don't
                   1914:      * touch other backslashes.
                   1915:      */
1.278     rillig   1916:     for (cp = *tstr; *cp != '\0' && *cp != delim; cp++) {
1.263     rillig   1917:        Boolean is_escaped = cp[0] == '\\' && (cp[1] == delim ||
1.281     rillig   1918:            cp[1] == '\\' || cp[1] == '$' || (subst != NULL && cp[1] == '&'));
1.263     rillig   1919:        if (is_escaped) {
1.146     dsl      1920:            Buf_AddByte(&buf, cp[1]);
1.16      christos 1921:            cp++;
                   1922:        } else if (*cp == '$') {
                   1923:            if (cp[1] == delim) {
1.261     rillig   1924:                if (mpflags == NULL)
1.146     dsl      1925:                    Buf_AddByte(&buf, *cp);
1.16      christos 1926:                else
                   1927:                    /*
                   1928:                     * Unescaped $ at end of pattern => anchor
                   1929:                     * pattern at end.
                   1930:                     */
1.261     rillig   1931:                    *mpflags |= VARP_MATCH_END;
1.40      sjg      1932:            } else {
1.261     rillig   1933:                /* FIXME: mismatch between mpflags and VAR_NOSUBST */
                   1934:                if (mpflags == NULL || !(*mpflags & VAR_NOSUBST)) {
1.40      sjg      1935:                    char   *cp2;
1.127     christos 1936:                    int     len;
1.104     christos 1937:                    void   *freeIt;
1.40      sjg      1938:
                   1939:                    /*
                   1940:                     * If unescaped dollar sign not before the
                   1941:                     * delimiter, assume it's a variable
                   1942:                     * substitution and recurse.
                   1943:                     */
1.261     rillig   1944:                    cp2 = Var_Parse(cp, ctxt, errnum | (eflags & VARE_WANTRES),
1.249     rillig   1945:                                    &len, &freeIt);
1.146     dsl      1946:                    Buf_AddBytes(&buf, strlen(cp2), cp2);
1.196     christos 1947:                    free(freeIt);
1.40      sjg      1948:                    cp += len - 1;
                   1949:                } else {
1.73      christos 1950:                    const char *cp2 = &cp[1];
1.16      christos 1951:
1.100     christos 1952:                    if (*cp2 == PROPEN || *cp2 == BROPEN) {
1.40      sjg      1953:                        /*
                   1954:                         * Find the end of this variable reference
                   1955:                         * and suck it in without further ado.
1.232     rillig   1956:                         * It will be interpreted later.
1.40      sjg      1957:                         */
                   1958:                        int have = *cp2;
1.100     christos 1959:                        int want = (*cp2 == PROPEN) ? PRCLOSE : BRCLOSE;
1.40      sjg      1960:                        int depth = 1;
                   1961:
                   1962:                        for (++cp2; *cp2 != '\0' && depth > 0; ++cp2) {
                   1963:                            if (cp2[-1] != '\\') {
                   1964:                                if (*cp2 == have)
                   1965:                                    ++depth;
                   1966:                                if (*cp2 == want)
                   1967:                                    --depth;
                   1968:                            }
                   1969:                        }
1.146     dsl      1970:                        Buf_AddBytes(&buf, cp2 - cp, cp);
1.40      sjg      1971:                        cp = --cp2;
                   1972:                    } else
1.146     dsl      1973:                        Buf_AddByte(&buf, *cp);
1.40      sjg      1974:                }
1.16      christos 1975:            }
1.281     rillig   1976:        } else if (subst != NULL && *cp == '&')
                   1977:            Buf_AddBytes(&buf, subst->lhsLen, subst->lhs);
1.16      christos 1978:        else
1.146     dsl      1979:            Buf_AddByte(&buf, *cp);
1.16      christos 1980:     }
                   1981:
                   1982:     if (*cp != delim) {
                   1983:        *tstr = cp;
                   1984:        *length = 0;
                   1985:        return NULL;
                   1986:     }
1.146     dsl      1987:
                   1988:     *tstr = ++cp;
                   1989:     *length = Buf_Size(&buf);
                   1990:     rstr = Buf_Destroy(&buf, FALSE);
                   1991:     if (DEBUG(VAR))
1.278     rillig   1992:        fprintf(debug_file, "Modifier part: \"%s\"\n", rstr);
1.146     dsl      1993:     return rstr;
1.16      christos 1994: }
                   1995:
                   1996: /*-
                   1997:  *-----------------------------------------------------------------------
                   1998:  * VarQuote --
1.194     mlelstv  1999:  *     Quote shell meta-characters and space characters in the string
1.220     christos 2000:  *     if quoteDollar is set, also quote and double any '$' characters.
1.16      christos 2001:  *
                   2002:  * Results:
                   2003:  *     The quoted string
                   2004:  *
                   2005:  * Side Effects:
                   2006:  *     None.
                   2007:  *
                   2008:  *-----------------------------------------------------------------------
                   2009:  */
                   2010: static char *
1.220     christos 2011: VarQuote(char *str, Boolean quoteDollar)
1.16      christos 2012: {
                   2013:     Buffer       buf;
1.111     rillig   2014:     const char *newline;
1.193     christos 2015:     size_t nlen;
1.111     rillig   2016:
1.133     joerg    2017:     if ((newline = Shell_GetNewline()) == NULL)
1.242     rillig   2018:        newline = "\\\n";
1.133     joerg    2019:     nlen = strlen(newline);
1.16      christos 2020:
1.146     dsl      2021:     Buf_Init(&buf, 0);
1.193     christos 2022:
                   2023:     for (; *str != '\0'; str++) {
                   2024:        if (*str == '\n') {
1.146     dsl      2025:            Buf_AddBytes(&buf, nlen, newline);
1.193     christos 2026:            continue;
                   2027:        }
1.195     christos 2028:        if (isspace((unsigned char)*str) || ismeta((unsigned char)*str))
1.146     dsl      2029:            Buf_AddByte(&buf, '\\');
1.193     christos 2030:        Buf_AddByte(&buf, *str);
1.220     christos 2031:        if (quoteDollar && *str == '$')
1.219     christos 2032:            Buf_AddBytes(&buf, 2, "\\$");
1.16      christos 2033:     }
1.193     christos 2034:
1.146     dsl      2035:     str = Buf_Destroy(&buf, FALSE);
1.137     christos 2036:     if (DEBUG(VAR))
                   2037:        fprintf(debug_file, "QuoteMeta: [%s]\n", str);
1.16      christos 2038:     return str;
                   2039: }
                   2040:
1.68      pk       2041: /*-
                   2042:  *-----------------------------------------------------------------------
1.163     joerg    2043:  * VarHash --
                   2044:  *      Hash the string using the MurmurHash3 algorithm.
                   2045:  *      Output is computed using 32bit Little Endian arithmetic.
                   2046:  *
                   2047:  * Input:
                   2048:  *     str             String to modify
                   2049:  *
                   2050:  * Results:
                   2051:  *      Hash value of str, encoded as 8 hex digits.
                   2052:  *
                   2053:  * Side Effects:
                   2054:  *      None.
                   2055:  *
                   2056:  *-----------------------------------------------------------------------
                   2057:  */
                   2058: static char *
1.252     rillig   2059: VarHash(const char *str)
1.163     joerg    2060: {
                   2061:     static const char    hexdigits[16] = "0123456789abcdef";
                   2062:     Buffer         buf;
                   2063:     size_t         len, len2;
1.252     rillig   2064:     const unsigned char *ustr = (const unsigned char *)str;
1.163     joerg    2065:     uint32_t       h, k, c1, c2;
                   2066:
                   2067:     h  = 0x971e137bU;
                   2068:     c1 = 0x95543787U;
                   2069:     c2 = 0x2ad7eb25U;
                   2070:     len2 = strlen(str);
                   2071:
                   2072:     for (len = len2; len; ) {
                   2073:        k = 0;
                   2074:        switch (len) {
                   2075:        default:
1.252     rillig   2076:            k = ((uint32_t)ustr[3] << 24) |
                   2077:                ((uint32_t)ustr[2] << 16) |
                   2078:                ((uint32_t)ustr[1] << 8) |
                   2079:                (uint32_t)ustr[0];
1.163     joerg    2080:            len -= 4;
                   2081:            ustr += 4;
                   2082:            break;
                   2083:        case 3:
1.252     rillig   2084:            k |= (uint32_t)ustr[2] << 16;
1.222     mrg      2085:            /* FALLTHROUGH */
1.163     joerg    2086:        case 2:
1.252     rillig   2087:            k |= (uint32_t)ustr[1] << 8;
1.222     mrg      2088:            /* FALLTHROUGH */
1.163     joerg    2089:        case 1:
1.252     rillig   2090:            k |= (uint32_t)ustr[0];
1.163     joerg    2091:            len = 0;
                   2092:        }
                   2093:        c1 = c1 * 5 + 0x7b7d159cU;
                   2094:        c2 = c2 * 5 + 0x6bce6396U;
                   2095:        k *= c1;
                   2096:        k = (k << 11) ^ (k >> 21);
                   2097:        k *= c2;
                   2098:        h = (h << 13) ^ (h >> 19);
                   2099:        h = h * 5 + 0x52dce729U;
                   2100:        h ^= k;
1.242     rillig   2101:     }
                   2102:     h ^= len2;
                   2103:     h *= 0x85ebca6b;
                   2104:     h ^= h >> 13;
                   2105:     h *= 0xc2b2ae35;
                   2106:     h ^= h >> 16;
                   2107:
                   2108:     Buf_Init(&buf, 0);
                   2109:     for (len = 0; len < 8; ++len) {
                   2110:        Buf_AddByte(&buf, hexdigits[h & 15]);
                   2111:        h >>= 4;
1.249     rillig   2112:     }
1.163     joerg    2113:
1.249     rillig   2114:     return Buf_Destroy(&buf, FALSE);
1.163     joerg    2115: }
                   2116:
1.164     sjg      2117: static char *
1.209     sjg      2118: VarStrftime(const char *fmt, int zulu, time_t utc)
1.164     sjg      2119: {
                   2120:     char buf[BUFSIZ];
                   2121:
1.209     sjg      2122:     if (!utc)
                   2123:        time(&utc);
1.164     sjg      2124:     if (!*fmt)
                   2125:        fmt = "%c";
                   2126:     strftime(buf, sizeof(buf), fmt, zulu ? gmtime(&utc) : localtime(&utc));
1.235     rillig   2127:
1.164     sjg      2128:     buf[sizeof(buf) - 1] = '\0';
                   2129:     return bmake_strdup(buf);
                   2130: }
                   2131:
1.236     rillig   2132: typedef struct {
                   2133:     /* const parameters */
1.267     rillig   2134:     int startc;                        /* '\0' or '{' or '(' */
1.236     rillig   2135:     int endc;
1.242     rillig   2136:     Var *v;
1.236     rillig   2137:     GNode *ctxt;
1.268     rillig   2138:     VarEvalFlags eflags;
1.242     rillig   2139:     int *lengthPtr;
                   2140:     void **freePtr;
1.236     rillig   2141:
                   2142:     /* read-write */
                   2143:     char *nstr;
                   2144:     const char *tstr;
                   2145:     const char *start;
                   2146:     const char *cp;            /* Secondary pointer into str (place marker
                   2147:                                 * for tstr) */
                   2148:     char termc;                        /* Character which terminated scan */
                   2149:     char delim;
                   2150:     int modifier;              /* that we are processing */
1.242     rillig   2151:     Var_Parse_State parsestate;        /* Flags passed to helper functions */
1.236     rillig   2152:
                   2153:     /* result */
                   2154:     char *newStr;              /* New value to return */
                   2155: } ApplyModifiersState;
                   2156:
                   2157: /* we now have some modifiers with long names */
                   2158: #define STRMOD_MATCH(s, want, n) \
                   2159:     (strncmp(s, want, n) == 0 && (s[n] == st->endc || s[n] == ':'))
                   2160: #define STRMOD_MATCHX(s, want, n) \
1.246     rillig   2161:     (strncmp(s, want, n) == 0 && \
                   2162:      (s[n] == st->endc || s[n] == ':' || s[n] == '='))
1.236     rillig   2163: #define CHARMOD_MATCH(c) (c == st->endc || c == ':')
                   2164:
                   2165: /* :@var@...${var}...@ */
                   2166: static Boolean
                   2167: ApplyModifier_At(ApplyModifiersState *st) {
1.251     rillig   2168:     VarLoop loop;
1.261     rillig   2169:     VarPatternFlags pflags = VAR_NOSUBST; /* FIXME: mismatch between pflags and VAR_NOSUBST */
1.236     rillig   2170:
1.261     rillig   2171:     st->cp = ++st->tstr;
1.236     rillig   2172:     st->delim = '@';
1.265     rillig   2173:     loop.tvar = ParseModifierPart(
1.268     rillig   2174:        st->ctxt, &st->cp, st->delim, st->eflags, &pflags, NULL, NULL);
1.236     rillig   2175:     if (loop.tvar == NULL)
                   2176:        return FALSE;
                   2177:
1.265     rillig   2178:     loop.str = ParseModifierPart(
1.268     rillig   2179:        st->ctxt, &st->cp, st->delim, st->eflags, &pflags, NULL, NULL);
1.236     rillig   2180:     if (loop.str == NULL)
                   2181:        return FALSE;
                   2182:
                   2183:     st->termc = *st->cp;
                   2184:     st->delim = '\0';
                   2185:
1.268     rillig   2186:     loop.eflags = st->eflags & (VARE_UNDEFERR | VARE_WANTRES);
1.278     rillig   2187:     int prev_sep = st->parsestate.varSpace;
                   2188:     st->parsestate.varSpace = ' ';
1.246     rillig   2189:     st->newStr = VarModify(
                   2190:        st->ctxt, &st->parsestate, st->nstr, VarLoopExpand, &loop);
1.278     rillig   2191:     st->parsestate.varSpace = prev_sep;
1.236     rillig   2192:     Var_Delete(loop.tvar, st->ctxt);
                   2193:     free(loop.tvar);
                   2194:     free(loop.str);
                   2195:     return TRUE;
                   2196: }
                   2197:
                   2198: /* :Ddefined or :Uundefined */
                   2199: static void
                   2200: ApplyModifier_Defined(ApplyModifiersState *st)
                   2201: {
1.242     rillig   2202:     Buffer buf;                        /* Buffer for patterns */
1.268     rillig   2203:     VarEvalFlags neflags;
1.236     rillig   2204:
1.268     rillig   2205:     if (st->eflags & VARE_WANTRES) {
                   2206:        Boolean wantres;
1.236     rillig   2207:        if (*st->tstr == 'U')
                   2208:            wantres = ((st->v->flags & VAR_JUNK) != 0);
                   2209:        else
                   2210:            wantres = ((st->v->flags & VAR_JUNK) == 0);
1.268     rillig   2211:        neflags = st->eflags & ~VARE_WANTRES;
1.236     rillig   2212:        if (wantres)
1.268     rillig   2213:            neflags |= VARE_WANTRES;
1.236     rillig   2214:     } else
1.268     rillig   2215:        neflags = st->eflags;
1.236     rillig   2216:
                   2217:     /*
                   2218:      * Pass through tstr looking for 1) escaped delimiters,
                   2219:      * '$'s and backslashes (place the escaped character in
                   2220:      * uninterpreted) and 2) unescaped $'s that aren't before
                   2221:      * the delimiter (expand the variable substitution).
                   2222:      * The result is left in the Buffer buf.
                   2223:      */
                   2224:     Buf_Init(&buf, 0);
                   2225:     for (st->cp = st->tstr + 1;
                   2226:         *st->cp != st->endc && *st->cp != ':' && *st->cp != '\0';
                   2227:         st->cp++) {
                   2228:        if (*st->cp == '\\' &&
                   2229:            (st->cp[1] == ':' || st->cp[1] == '$' || st->cp[1] == st->endc ||
                   2230:             st->cp[1] == '\\')) {
                   2231:            Buf_AddByte(&buf, st->cp[1]);
                   2232:            st->cp++;
                   2233:        } else if (*st->cp == '$') {
                   2234:            /*
                   2235:             * If unescaped dollar sign, assume it's a
                   2236:             * variable substitution and recurse.
                   2237:             */
                   2238:            char    *cp2;
                   2239:            int     len;
                   2240:            void    *freeIt;
                   2241:
1.268     rillig   2242:            cp2 = Var_Parse(st->cp, st->ctxt, neflags, &len, &freeIt);
1.236     rillig   2243:            Buf_AddBytes(&buf, strlen(cp2), cp2);
                   2244:            free(freeIt);
                   2245:            st->cp += len - 1;
                   2246:        } else {
                   2247:            Buf_AddByte(&buf, *st->cp);
                   2248:        }
                   2249:     }
                   2250:
                   2251:     st->termc = *st->cp;
                   2252:
1.257     rillig   2253:     if (st->v->flags & VAR_JUNK)
1.236     rillig   2254:        st->v->flags |= VAR_KEEP;
1.268     rillig   2255:     if (neflags & VARE_WANTRES) {
1.236     rillig   2256:        st->newStr = Buf_Destroy(&buf, FALSE);
                   2257:     } else {
                   2258:        st->newStr = st->nstr;
                   2259:        Buf_Destroy(&buf, TRUE);
                   2260:     }
                   2261: }
                   2262:
                   2263: /* :gmtime */
                   2264: static Boolean
                   2265: ApplyModifier_Gmtime(ApplyModifiersState *st)
                   2266: {
                   2267:     time_t utc;
                   2268:     char *ep;
                   2269:
                   2270:     st->cp = st->tstr + 1;     /* make sure it is set */
                   2271:     if (!STRMOD_MATCHX(st->tstr, "gmtime", 6))
                   2272:        return FALSE;
                   2273:     if (st->tstr[6] == '=') {
                   2274:        utc = strtoul(&st->tstr[7], &ep, 10);
                   2275:        st->cp = ep;
                   2276:     } else {
                   2277:        utc = 0;
                   2278:        st->cp = st->tstr + 6;
                   2279:     }
                   2280:     st->newStr = VarStrftime(st->nstr, 1, utc);
                   2281:     st->termc = *st->cp;
                   2282:     return TRUE;
                   2283: }
                   2284:
                   2285: /* :localtime */
                   2286: static Boolean
                   2287: ApplyModifier_Localtime(ApplyModifiersState *st)
                   2288: {
                   2289:     time_t utc;
                   2290:     char *ep;
                   2291:
                   2292:     st->cp = st->tstr + 1;     /* make sure it is set */
                   2293:     if (!STRMOD_MATCHX(st->tstr, "localtime", 9))
                   2294:        return FALSE;
                   2295:
                   2296:     if (st->tstr[9] == '=') {
                   2297:        utc = strtoul(&st->tstr[10], &ep, 10);
                   2298:        st->cp = ep;
                   2299:     } else {
                   2300:        utc = 0;
                   2301:        st->cp = st->tstr + 9;
                   2302:     }
                   2303:     st->newStr = VarStrftime(st->nstr, 0, utc);
                   2304:     st->termc = *st->cp;
                   2305:     return TRUE;
                   2306: }
                   2307:
                   2308: /* :hash */
                   2309: static Boolean
                   2310: ApplyModifier_Hash(ApplyModifiersState *st)
                   2311: {
                   2312:     st->cp = st->tstr + 1;     /* make sure it is set */
                   2313:     if (!STRMOD_MATCH(st->tstr, "hash", 4))
                   2314:        return FALSE;
                   2315:     st->newStr = VarHash(st->nstr);
                   2316:     st->cp = st->tstr + 4;
                   2317:     st->termc = *st->cp;
                   2318:     return TRUE;
                   2319: }
                   2320:
                   2321: /* :P */
                   2322: static void
                   2323: ApplyModifier_Path(ApplyModifiersState *st)
                   2324: {
                   2325:     GNode *gn;
                   2326:
                   2327:     if ((st->v->flags & VAR_JUNK) != 0)
                   2328:        st->v->flags |= VAR_KEEP;
                   2329:     gn = Targ_FindNode(st->v->name, TARG_NOCREATE);
                   2330:     if (gn == NULL || gn->type & OP_NOPATH) {
                   2331:        st->newStr = NULL;
                   2332:     } else if (gn->path) {
                   2333:        st->newStr = bmake_strdup(gn->path);
                   2334:     } else {
                   2335:        st->newStr = Dir_FindFile(st->v->name, Suff_FindPath(gn));
                   2336:     }
                   2337:     if (!st->newStr)
                   2338:        st->newStr = bmake_strdup(st->v->name);
                   2339:     st->cp = ++st->tstr;
                   2340:     st->termc = *st->tstr;
                   2341: }
                   2342:
                   2343: /* :!cmd! */
                   2344: static Boolean
                   2345: ApplyModifier_Exclam(ApplyModifiersState *st)
                   2346: {
                   2347:     st->delim = '!';
                   2348:     st->cp = ++st->tstr;
1.274     rillig   2349:     char *cmd = ParseModifierPart(st->ctxt, &st->cp, st->delim, st->eflags,
                   2350:                                  NULL, NULL, NULL);
                   2351:     if (cmd == NULL)
1.236     rillig   2352:        return FALSE;
1.274     rillig   2353:
                   2354:     const char *emsg = NULL;
1.268     rillig   2355:     if (st->eflags & VARE_WANTRES)
1.274     rillig   2356:        st->newStr = Cmd_Exec(cmd, &emsg);
1.236     rillig   2357:     else
                   2358:        st->newStr = varNoError;
1.274     rillig   2359:     free(cmd);
                   2360:
1.236     rillig   2361:     if (emsg)
                   2362:        Error(emsg, st->nstr);
1.274     rillig   2363:
1.236     rillig   2364:     st->termc = *st->cp;
                   2365:     st->delim = '\0';
                   2366:     if (st->v->flags & VAR_JUNK)
                   2367:        st->v->flags |= VAR_KEEP;
                   2368:     return TRUE;
                   2369: }
                   2370:
                   2371: /* :range */
                   2372: static Boolean
                   2373: ApplyModifier_Range(ApplyModifiersState *st)
                   2374: {
                   2375:     int n;
                   2376:     char *ep;
                   2377:
                   2378:     st->cp = st->tstr + 1;     /* make sure it is set */
                   2379:     if (!STRMOD_MATCHX(st->tstr, "range", 5))
                   2380:        return FALSE;
                   2381:
                   2382:     if (st->tstr[5] == '=') {
                   2383:        n = strtoul(&st->tstr[6], &ep, 10);
                   2384:        st->cp = ep;
                   2385:     } else {
                   2386:        n = 0;
                   2387:        st->cp = st->tstr + 5;
                   2388:     }
                   2389:     st->newStr = VarRange(st->nstr, n);
                   2390:     st->termc = *st->cp;
                   2391:     return TRUE;
                   2392: }
                   2393:
                   2394: /* :Mpattern or :Npattern */
                   2395: static void
                   2396: ApplyModifier_Match(ApplyModifiersState *st)
                   2397: {
                   2398:     char    *pattern;
1.240     rillig   2399:     const char *endpat;                /* points just after end of pattern */
1.236     rillig   2400:     char    *cp2;
1.240     rillig   2401:     Boolean copy;              /* pattern should be, or has been, copied */
1.236     rillig   2402:     Boolean needSubst;
                   2403:     int nest;
                   2404:
                   2405:     copy = FALSE;
                   2406:     needSubst = FALSE;
                   2407:     nest = 1;
                   2408:     /*
                   2409:      * In the loop below, ignore ':' unless we are at
                   2410:      * (or back to) the original brace level.
                   2411:      * XXX This will likely not work right if $() and ${}
                   2412:      * are intermixed.
                   2413:      */
                   2414:     for (st->cp = st->tstr + 1;
                   2415:         *st->cp != '\0' && !(*st->cp == ':' && nest == 1);
                   2416:         st->cp++) {
                   2417:        if (*st->cp == '\\' &&
                   2418:            (st->cp[1] == ':' || st->cp[1] == st->endc ||
                   2419:             st->cp[1] == st->startc)) {
                   2420:            if (!needSubst)
                   2421:                copy = TRUE;
                   2422:            st->cp++;
                   2423:            continue;
                   2424:        }
                   2425:        if (*st->cp == '$')
                   2426:            needSubst = TRUE;
                   2427:        if (*st->cp == '(' || *st->cp == '{')
                   2428:            ++nest;
                   2429:        if (*st->cp == ')' || *st->cp == '}') {
                   2430:            --nest;
                   2431:            if (nest == 0)
                   2432:                break;
                   2433:        }
                   2434:     }
                   2435:     st->termc = *st->cp;
                   2436:     endpat = st->cp;
                   2437:     if (copy) {
                   2438:        /*
                   2439:         * Need to compress the \:'s out of the pattern, so
                   2440:         * allocate enough room to hold the uncompressed
                   2441:         * pattern (note that st->cp started at st->tstr+1, so
                   2442:         * st->cp - st->tstr takes the null byte into account) and
                   2443:         * compress the pattern into the space.
                   2444:         */
                   2445:        pattern = bmake_malloc(st->cp - st->tstr);
                   2446:        for (cp2 = pattern, st->cp = st->tstr + 1;
                   2447:             st->cp < endpat;
                   2448:             st->cp++, cp2++) {
                   2449:            if ((*st->cp == '\\') && (st->cp+1 < endpat) &&
                   2450:                (st->cp[1] == ':' || st->cp[1] == st->endc))
                   2451:                st->cp++;
                   2452:            *cp2 = *st->cp;
                   2453:        }
                   2454:        *cp2 = '\0';
                   2455:        endpat = cp2;
                   2456:     } else {
                   2457:        /*
                   2458:         * Either Var_Subst or VarModify will need a
                   2459:         * nul-terminated string soon, so construct one now.
                   2460:         */
                   2461:        pattern = bmake_strndup(st->tstr+1, endpat - (st->tstr + 1));
                   2462:     }
                   2463:     if (needSubst) {
                   2464:        /* pattern contains embedded '$', so use Var_Subst to expand it. */
                   2465:        cp2 = pattern;
1.268     rillig   2466:        pattern = Var_Subst(NULL, cp2, st->ctxt, st->eflags);
1.236     rillig   2467:        free(cp2);
                   2468:     }
                   2469:     if (DEBUG(VAR))
                   2470:        fprintf(debug_file, "Pattern[%s] for [%s] is [%s]\n",
                   2471:            st->v->name, st->nstr, pattern);
1.268     rillig   2472:     VarModifyCallback callback = st->tstr[0] == 'M' ? VarMatch : VarNoMatch;
                   2473:     st->newStr = VarModify(st->ctxt, &st->parsestate, st->nstr, callback,
                   2474:                           pattern);
1.236     rillig   2475:     free(pattern);
                   2476: }
                   2477:
                   2478: /* :S,from,to, */
                   2479: static Boolean
                   2480: ApplyModifier_Subst(ApplyModifiersState *st)
                   2481: {
1.281     rillig   2482:     VarSubstituteArgs args;
                   2483:     Var_Parse_State tmpparsestate = st->parsestate;
1.236     rillig   2484:     st->delim = st->tstr[1];
                   2485:     st->tstr += 2;
                   2486:
                   2487:     /*
                   2488:      * If pattern begins with '^', it is anchored to the
                   2489:      * start of the word -- skip over it and flag pattern.
                   2490:      */
1.281     rillig   2491:     args.pflags = 0;
1.236     rillig   2492:     if (*st->tstr == '^') {
1.281     rillig   2493:        args.pflags |= VARP_MATCH_START;
1.261     rillig   2494:        st->tstr++;
1.236     rillig   2495:     }
                   2496:
                   2497:     st->cp = st->tstr;
1.281     rillig   2498:     char *lhs = ParseModifierPart(st->ctxt, &st->cp, st->delim, st->eflags,
                   2499:                                  &args.pflags, &args.lhsLen, NULL);
                   2500:     if (lhs == NULL)
1.236     rillig   2501:        return FALSE;
1.281     rillig   2502:     args.lhs = lhs;
1.236     rillig   2503:
1.281     rillig   2504:     char *rhs = ParseModifierPart(st->ctxt, &st->cp, st->delim, st->eflags,
                   2505:                                  NULL, &args.rhsLen, &args);
                   2506:     if (rhs == NULL)
1.236     rillig   2507:        return FALSE;
1.281     rillig   2508:     args.rhs = rhs;
1.236     rillig   2509:
                   2510:     /*
                   2511:      * Check for global substitution. If 'g' after the final
                   2512:      * delimiter, substitution is global and is marked that
                   2513:      * way.
                   2514:      */
                   2515:     for (;; st->cp++) {
                   2516:        switch (*st->cp) {
                   2517:        case 'g':
1.281     rillig   2518:            args.pflags |= VARP_SUB_GLOBAL;
1.236     rillig   2519:            continue;
                   2520:        case '1':
1.281     rillig   2521:            args.pflags |= VARP_SUB_ONE;
1.236     rillig   2522:            continue;
                   2523:        case 'W':
                   2524:            tmpparsestate.oneBigWord = TRUE;
                   2525:            continue;
                   2526:        }
                   2527:        break;
                   2528:     }
                   2529:
                   2530:     st->termc = *st->cp;
1.281     rillig   2531:     st->newStr = VarModify(st->ctxt, &tmpparsestate, st->nstr,
                   2532:                           VarSubstitute, &args);
1.236     rillig   2533:
1.281     rillig   2534:     free(lhs);
                   2535:     free(rhs);
1.236     rillig   2536:     st->delim = '\0';
                   2537:     return TRUE;
                   2538: }
                   2539:
                   2540: #ifndef NO_REGEX
                   2541: /* :C,from,to, */
                   2542: static Boolean
                   2543: ApplyModifier_Regex(ApplyModifiersState *st)
                   2544: {
                   2545:     VarREPattern    pattern;
                   2546:     char           *re;
                   2547:     int             error;
                   2548:     Var_Parse_State tmpparsestate;
                   2549:
1.261     rillig   2550:     pattern.pflags = 0;
1.236     rillig   2551:     tmpparsestate = st->parsestate;
                   2552:     st->delim = st->tstr[1];
                   2553:     st->tstr += 2;
                   2554:
                   2555:     st->cp = st->tstr;
                   2556:
1.268     rillig   2557:     re = ParseModifierPart(st->ctxt, &st->cp, st->delim, st->eflags,
1.266     rillig   2558:                           NULL, NULL, NULL);
1.236     rillig   2559:     if (re == NULL)
                   2560:        return FALSE;
                   2561:
1.266     rillig   2562:     pattern.replace = ParseModifierPart(st->ctxt, &st->cp, st->delim,
1.268     rillig   2563:                                        st->eflags, NULL, NULL, NULL);
1.236     rillig   2564:     if (pattern.replace == NULL) {
                   2565:        free(re);
                   2566:        return FALSE;
                   2567:     }
                   2568:
                   2569:     for (;; st->cp++) {
                   2570:        switch (*st->cp) {
                   2571:        case 'g':
1.261     rillig   2572:            pattern.pflags |= VARP_SUB_GLOBAL;
1.236     rillig   2573:            continue;
                   2574:        case '1':
1.261     rillig   2575:            pattern.pflags |= VARP_SUB_ONE;
1.236     rillig   2576:            continue;
                   2577:        case 'W':
                   2578:            tmpparsestate.oneBigWord = TRUE;
                   2579:            continue;
                   2580:        }
                   2581:        break;
                   2582:     }
                   2583:
                   2584:     st->termc = *st->cp;
                   2585:
                   2586:     error = regcomp(&pattern.re, re, REG_EXTENDED);
                   2587:     free(re);
1.242     rillig   2588:     if (error) {
1.236     rillig   2589:        *st->lengthPtr = st->cp - st->start + 1;
                   2590:        VarREError(error, &pattern.re, "RE substitution error");
                   2591:        free(pattern.replace);
                   2592:        return FALSE;
                   2593:     }
                   2594:
                   2595:     pattern.nsub = pattern.re.re_nsub + 1;
                   2596:     if (pattern.nsub < 1)
                   2597:        pattern.nsub = 1;
                   2598:     if (pattern.nsub > 10)
                   2599:        pattern.nsub = 10;
                   2600:     pattern.matches = bmake_malloc(pattern.nsub * sizeof(regmatch_t));
                   2601:     st->newStr = VarModify(
                   2602:        st->ctxt, &tmpparsestate, st->nstr, VarRESubstitute, &pattern);
                   2603:     regfree(&pattern.re);
                   2604:     free(pattern.replace);
                   2605:     free(pattern.matches);
                   2606:     st->delim = '\0';
                   2607:     return TRUE;
                   2608: }
                   2609: #endif
                   2610:
1.278     rillig   2611: static void
                   2612: VarModify_Copy(GNode *ctx MAKE_ATTR_UNUSED, const char *word, SepBuf *buf,
                   2613:               void *data MAKE_ATTR_UNUSED)
                   2614: {
                   2615:     SepBuf_AddBytes(buf, word, strlen(word));
1.275     rillig   2616: }
                   2617:
1.236     rillig   2618: /* :tA, :tu, :tl, etc. */
                   2619: static Boolean
                   2620: ApplyModifier_To(ApplyModifiersState *st)
                   2621: {
                   2622:     st->cp = st->tstr + 1;     /* make sure it is set */
                   2623:     if (st->tstr[1] != st->endc && st->tstr[1] != ':') {
                   2624:        if (st->tstr[1] == 's') {
1.240     rillig   2625:            /* Use the char (if any) at st->tstr[2] as the word separator. */
1.236     rillig   2626:
                   2627:            if (st->tstr[2] != st->endc &&
                   2628:                (st->tstr[3] == st->endc || st->tstr[3] == ':')) {
                   2629:                /* ":ts<unrecognised><endc>" or
                   2630:                 * ":ts<unrecognised>:" */
                   2631:                st->parsestate.varSpace = st->tstr[2];
                   2632:                st->cp = st->tstr + 3;
                   2633:            } else if (st->tstr[2] == st->endc || st->tstr[2] == ':') {
                   2634:                /* ":ts<endc>" or ":ts:" */
1.242     rillig   2635:                st->parsestate.varSpace = 0;    /* no separator */
1.236     rillig   2636:                st->cp = st->tstr + 2;
                   2637:            } else if (st->tstr[2] == '\\') {
                   2638:                const char *xp = &st->tstr[3];
1.240     rillig   2639:                int base = 8;   /* assume octal */
1.236     rillig   2640:
                   2641:                switch (st->tstr[3]) {
                   2642:                case 'n':
                   2643:                    st->parsestate.varSpace = '\n';
                   2644:                    st->cp = st->tstr + 4;
                   2645:                    break;
                   2646:                case 't':
                   2647:                    st->parsestate.varSpace = '\t';
                   2648:                    st->cp = st->tstr + 4;
                   2649:                    break;
                   2650:                case 'x':
                   2651:                    base = 16;
                   2652:                    xp++;
                   2653:                    goto get_numeric;
                   2654:                case '0':
                   2655:                    base = 0;
                   2656:                    goto get_numeric;
                   2657:                default:
                   2658:                    if (isdigit((unsigned char)st->tstr[3])) {
                   2659:                        char *ep;
                   2660:                    get_numeric:
                   2661:                        st->parsestate.varSpace = strtoul(xp, &ep, base);
                   2662:                        if (*ep != ':' && *ep != st->endc)
                   2663:                            return FALSE;
                   2664:                        st->cp = ep;
                   2665:                    } else {
                   2666:                        /* ":ts<backslash><unrecognised>". */
                   2667:                        return FALSE;
                   2668:                    }
                   2669:                    break;
                   2670:                }
                   2671:            } else {
                   2672:                /* Found ":ts<unrecognised><unrecognised>". */
                   2673:                return FALSE;
                   2674:            }
                   2675:
                   2676:            st->termc = *st->cp;
1.275     rillig   2677:            st->newStr = VarModify(st->ctxt, &st->parsestate, st->nstr,
                   2678:                                   VarModify_Copy, NULL);
1.236     rillig   2679:        } else if (st->tstr[2] == st->endc || st->tstr[2] == ':') {
                   2680:            /* Check for two-character options: ":tu", ":tl" */
1.242     rillig   2681:            if (st->tstr[1] == 'A') {   /* absolute path */
1.236     rillig   2682:                st->newStr = VarModify(
                   2683:                        st->ctxt, &st->parsestate, st->nstr, VarRealpath, NULL);
                   2684:                st->cp = st->tstr + 2;
                   2685:                st->termc = *st->cp;
                   2686:            } else if (st->tstr[1] == 'u') {
                   2687:                char *dp = bmake_strdup(st->nstr);
                   2688:                for (st->newStr = dp; *dp; dp++)
                   2689:                    *dp = toupper((unsigned char)*dp);
                   2690:                st->cp = st->tstr + 2;
                   2691:                st->termc = *st->cp;
                   2692:            } else if (st->tstr[1] == 'l') {
                   2693:                char *dp = bmake_strdup(st->nstr);
                   2694:                for (st->newStr = dp; *dp; dp++)
                   2695:                    *dp = tolower((unsigned char)*dp);
                   2696:                st->cp = st->tstr + 2;
                   2697:                st->termc = *st->cp;
                   2698:            } else if (st->tstr[1] == 'W' || st->tstr[1] == 'w') {
                   2699:                st->parsestate.oneBigWord = (st->tstr[1] == 'W');
                   2700:                st->newStr = st->nstr;
                   2701:                st->cp = st->tstr + 2;
                   2702:                st->termc = *st->cp;
                   2703:            } else {
                   2704:                /* Found ":t<unrecognised>:" or ":t<unrecognised><endc>". */
                   2705:                return FALSE;
                   2706:            }
                   2707:        } else {
                   2708:            /* Found ":t<unrecognised><unrecognised>". */
                   2709:            return FALSE;
                   2710:        }
                   2711:     } else {
                   2712:        /* Found ":t<endc>" or ":t:". */
                   2713:        return FALSE;
                   2714:     }
                   2715:     return TRUE;
                   2716: }
                   2717:
                   2718: /* :[#], :[1], etc. */
                   2719: static int
                   2720: ApplyModifier_Words(ApplyModifiersState *st)
                   2721: {
1.242     rillig   2722:     st->cp = st->tstr + 1;     /* point to char after '[' */
1.236     rillig   2723:     st->delim = ']';           /* look for closing ']' */
1.268     rillig   2724:     char *estr = ParseModifierPart(st->ctxt, &st->cp, st->delim, st->eflags,
1.266     rillig   2725:                                   NULL, NULL, NULL);
1.236     rillig   2726:     if (estr == NULL)
                   2727:        return 'c';             /* report missing ']' */
                   2728:     /* now st->cp points just after the closing ']' */
                   2729:     st->delim = '\0';
                   2730:     if (st->cp[0] != ':' && st->cp[0] != st->endc) {
                   2731:        /* Found junk after ']' */
                   2732:        free(estr);
                   2733:        return 'b';
                   2734:     }
                   2735:     if (estr[0] == '\0') {
                   2736:        /* Found empty square brackets in ":[]". */
                   2737:        free(estr);
                   2738:        return 'b';
                   2739:     } else if (estr[0] == '#' && estr[1] == '\0') {
                   2740:        /* Found ":[#]" */
                   2741:
                   2742:        /*
                   2743:         * We will need enough space for the decimal
                   2744:         * representation of an int.  We calculate the
                   2745:         * space needed for the octal representation,
                   2746:         * and add enough slop to cope with a '-' sign
                   2747:         * (which should never be needed) and a '\0'
                   2748:         * string terminator.
                   2749:         */
                   2750:        int newStrSize = (sizeof(int) * CHAR_BIT + 2) / 3 + 2;
                   2751:
                   2752:        st->newStr = bmake_malloc(newStrSize);
                   2753:        if (st->parsestate.oneBigWord) {
                   2754:            strncpy(st->newStr, "1", newStrSize);
                   2755:        } else {
                   2756:            /* XXX: brk_string() is a rather expensive
                   2757:             * way of counting words. */
                   2758:            char **av;
                   2759:            char *as;
                   2760:            int ac;
                   2761:
                   2762:            av = brk_string(st->nstr, &ac, FALSE, &as);
1.242     rillig   2763:            snprintf(st->newStr, newStrSize, "%d", ac);
1.236     rillig   2764:            free(as);
                   2765:            free(av);
                   2766:        }
                   2767:        st->termc = *st->cp;
                   2768:        free(estr);
                   2769:        return 0;
                   2770:     } else if (estr[0] == '*' && estr[1] == '\0') {
                   2771:        /* Found ":[*]" */
                   2772:        st->parsestate.oneBigWord = TRUE;
                   2773:        st->newStr = st->nstr;
                   2774:        st->termc = *st->cp;
                   2775:        free(estr);
                   2776:        return 0;
                   2777:     } else if (estr[0] == '@' && estr[1] == '\0') {
                   2778:        /* Found ":[@]" */
                   2779:        st->parsestate.oneBigWord = FALSE;
                   2780:        st->newStr = st->nstr;
                   2781:        st->termc = *st->cp;
                   2782:        free(estr);
                   2783:        return 0;
                   2784:     } else {
                   2785:        char *ep;
                   2786:        /*
                   2787:         * We expect estr to contain a single
                   2788:         * integer for :[N], or two integers
                   2789:         * separated by ".." for :[start..end].
                   2790:         */
                   2791:        VarSelectWords_t seldata = { 0, 0 };
                   2792:
                   2793:        seldata.start = strtol(estr, &ep, 0);
                   2794:        if (ep == estr) {
                   2795:            /* Found junk instead of a number */
                   2796:            free(estr);
                   2797:            return 'b';
                   2798:        } else if (ep[0] == '\0') {
                   2799:            /* Found only one integer in :[N] */
                   2800:            seldata.end = seldata.start;
                   2801:        } else if (ep[0] == '.' && ep[1] == '.' && ep[2] != '\0') {
                   2802:            /* Expecting another integer after ".." */
                   2803:            ep += 2;
                   2804:            seldata.end = strtol(ep, &ep, 0);
                   2805:            if (ep[0] != '\0') {
                   2806:                /* Found junk after ".." */
                   2807:                free(estr);
                   2808:                return 'b';
                   2809:            }
                   2810:        } else {
                   2811:            /* Found junk instead of ".." */
                   2812:            free(estr);
                   2813:            return 'b';
                   2814:        }
                   2815:        /*
                   2816:         * Now seldata is properly filled in,
                   2817:         * but we still have to check for 0 as
                   2818:         * a special case.
                   2819:         */
                   2820:        if (seldata.start == 0 && seldata.end == 0) {
                   2821:            /* ":[0]" or perhaps ":[0..0]" */
                   2822:            st->parsestate.oneBigWord = TRUE;
                   2823:            st->newStr = st->nstr;
                   2824:            st->termc = *st->cp;
                   2825:            free(estr);
                   2826:            return 0;
                   2827:        } else if (seldata.start == 0 || seldata.end == 0) {
                   2828:            /* ":[0..N]" or ":[N..0]" */
                   2829:            free(estr);
                   2830:            return 'b';
                   2831:        }
                   2832:        /* Normal case: select the words described by seldata. */
                   2833:        st->newStr = VarSelectWords(
                   2834:            st->ctxt, &st->parsestate, st->nstr, &seldata);
                   2835:
                   2836:        st->termc = *st->cp;
                   2837:        free(estr);
                   2838:        return 0;
                   2839:     }
                   2840: }
                   2841:
                   2842: /* :O or :Ox */
                   2843: static Boolean
                   2844: ApplyModifier_Order(ApplyModifiersState *st)
                   2845: {
                   2846:     char otype;
                   2847:
                   2848:     st->cp = st->tstr + 1;     /* skip to the rest in any case */
                   2849:     if (st->tstr[1] == st->endc || st->tstr[1] == ':') {
                   2850:        otype = 's';
                   2851:        st->termc = *st->cp;
                   2852:     } else if ((st->tstr[1] == 'r' || st->tstr[1] == 'x') &&
                   2853:               (st->tstr[2] == st->endc || st->tstr[2] == ':')) {
                   2854:        otype = st->tstr[1];
                   2855:        st->cp = st->tstr + 2;
                   2856:        st->termc = *st->cp;
                   2857:     } else {
                   2858:        return FALSE;
                   2859:     }
                   2860:     st->newStr = VarOrder(st->nstr, otype);
                   2861:     return TRUE;
                   2862: }
                   2863:
                   2864: /* :? then : else */
                   2865: static Boolean
                   2866: ApplyModifier_IfElse(ApplyModifiersState *st)
                   2867: {
                   2868:     Boolean value;
                   2869:     int cond_rc;
1.261     rillig   2870:     VarPatternFlags then_flags, else_flags;
                   2871:     /* FIXME: IfElse has nothing to do with VarPatternFlags */
1.236     rillig   2872:
                   2873:     /* find ':', and then substitute accordingly */
1.268     rillig   2874:     if (st->eflags & VARE_WANTRES) {
1.236     rillig   2875:        cond_rc = Cond_EvalExpression(NULL, st->v->name, &value, 0, FALSE);
1.258     rillig   2876:        then_flags = cond_rc != COND_INVALID && value ? 0 : VAR_NOSUBST;
                   2877:        else_flags = cond_rc != COND_INVALID && !value ? 0 : VAR_NOSUBST;
1.236     rillig   2878:     } else {
                   2879:        /* we are just consuming and discarding */
                   2880:        cond_rc = value = 0;
1.258     rillig   2881:        then_flags = else_flags = VAR_NOSUBST;
1.236     rillig   2882:     }
                   2883:
                   2884:     st->cp = ++st->tstr;
                   2885:     st->delim = ':';
1.265     rillig   2886:     char *then_expr = ParseModifierPart(
1.268     rillig   2887:        st->ctxt, &st->cp, st->delim, st->eflags, &then_flags, NULL, NULL);
1.258     rillig   2888:     if (then_expr == NULL)
1.236     rillig   2889:        return FALSE;
                   2890:
1.267     rillig   2891:     st->delim = st->endc;      /* BRCLOSE or PRCLOSE */
1.265     rillig   2892:     char *else_expr = ParseModifierPart(
1.268     rillig   2893:        st->ctxt, &st->cp, st->delim, st->eflags, &else_flags, NULL, NULL);
1.258     rillig   2894:     if (else_expr == NULL)
1.236     rillig   2895:        return FALSE;
                   2896:
                   2897:     st->termc = *--st->cp;
                   2898:     st->delim = '\0';
                   2899:     if (cond_rc == COND_INVALID) {
                   2900:        Error("Bad conditional expression `%s' in %s?%s:%s",
1.258     rillig   2901:            st->v->name, st->v->name, then_expr, else_expr);
1.236     rillig   2902:        return FALSE;
                   2903:     }
                   2904:
                   2905:     if (value) {
1.258     rillig   2906:        st->newStr = then_expr;
                   2907:        free(else_expr);
1.236     rillig   2908:     } else {
1.258     rillig   2909:        st->newStr = else_expr;
1.270     rillig   2910:        free(then_expr);
1.236     rillig   2911:     }
                   2912:     if (st->v->flags & VAR_JUNK)
                   2913:        st->v->flags |= VAR_KEEP;
                   2914:     return TRUE;
                   2915: }
                   2916:
1.283   ! rillig   2917: /*
        !          2918:  * The ::= modifiers actually assign a value to the variable.
        !          2919:  * Their main purpose is in supporting modifiers of .for loop
        !          2920:  * iterators and other obscure uses.  They always expand to
        !          2921:  * nothing.  In a target rule that would otherwise expand to an
        !          2922:  * empty line they can be preceded with @: to keep make happy.
        !          2923:  * Eg.
        !          2924:  *
        !          2925:  * foo:        .USE
        !          2926:  * .for i in ${.TARGET} ${.TARGET:R}.gz
        !          2927:  *     @: ${t::=$i}
        !          2928:  *     @echo blah ${t:T}
        !          2929:  * .endfor
        !          2930:  *
        !          2931:  *       ::=<str>      Assigns <str> as the new value of variable.
        !          2932:  *       ::?=<str>     Assigns <str> as value of variable if
        !          2933:  *                     it was not already set.
        !          2934:  *       ::+=<str>     Appends <str> to variable.
        !          2935:  *       ::!=<cmd>     Assigns output of <cmd> as the new value of
        !          2936:  *                     variable.
        !          2937:  */
1.236     rillig   2938: static int
                   2939: ApplyModifier_Assign(ApplyModifiersState *st)
                   2940: {
1.272     rillig   2941:     const char *op = st->tstr + 1;
                   2942:     if (!(op[0] == '=' ||
                   2943:        (op[1] == '=' &&
                   2944:         (op[0] == '!' || op[0] == '+' || op[0] == '?'))))
                   2945:        return 'd';             /* "::<unrecognised>" */
1.236     rillig   2946:
1.272     rillig   2947:     GNode *v_ctxt;             /* context where v belongs */
                   2948:     VarPatternFlags pflags;
                   2949:     /* FIXME: Assign has nothing to do with VarPatternFlags */
                   2950:
                   2951:     if (st->v->name[0] == 0)
                   2952:        return 'b';
                   2953:
                   2954:     v_ctxt = st->ctxt;
1.273     rillig   2955:     char *sv_name = NULL;
1.272     rillig   2956:     ++st->tstr;
                   2957:     if (st->v->flags & VAR_JUNK) {
                   2958:        /*
                   2959:         * We need to bmake_strdup() it incase ParseModifierPart() recurses.
                   2960:         */
                   2961:        sv_name = st->v->name;
                   2962:        st->v->name = bmake_strdup(st->v->name);
                   2963:     } else if (st->ctxt != VAR_GLOBAL) {
                   2964:        Var *gv = VarFind(st->v->name, st->ctxt, 0);
                   2965:        if (gv == NULL)
                   2966:            v_ctxt = VAR_GLOBAL;
                   2967:        else
                   2968:            VarFreeEnv(gv, TRUE);
                   2969:     }
                   2970:
1.273     rillig   2971:     switch (op[0]) {
1.272     rillig   2972:     case '+':
                   2973:     case '?':
                   2974:     case '!':
                   2975:        st->cp = &st->tstr[2];
                   2976:        break;
                   2977:     default:
                   2978:        st->cp = ++st->tstr;
                   2979:        break;
                   2980:     }
                   2981:     st->delim = st->startc == PROPEN ? PRCLOSE : BRCLOSE;
                   2982:
                   2983:     pflags = (st->eflags & VARE_WANTRES) ? 0 : VAR_NOSUBST;
1.273     rillig   2984:     char *val = ParseModifierPart(st->ctxt, &st->cp, st->delim, st->eflags,
                   2985:                                  &pflags, NULL, NULL);
1.272     rillig   2986:     if (st->v->flags & VAR_JUNK) {
                   2987:        /* restore original name */
                   2988:        free(st->v->name);
                   2989:        st->v->name = sv_name;
                   2990:     }
1.273     rillig   2991:     if (val == NULL)
1.272     rillig   2992:        return 'c';
1.236     rillig   2993:
1.272     rillig   2994:     st->termc = *--st->cp;
                   2995:     st->delim = '\0';
1.236     rillig   2996:
1.272     rillig   2997:     if (st->eflags & VARE_WANTRES) {
1.273     rillig   2998:        switch (op[0]) {
1.236     rillig   2999:        case '+':
1.273     rillig   3000:            Var_Append(st->v->name, val, v_ctxt);
1.272     rillig   3001:            break;
1.273     rillig   3002:        case '!': {
                   3003:            const char *emsg;
                   3004:            st->newStr = Cmd_Exec(val, &emsg);
1.272     rillig   3005:            if (emsg)
                   3006:                Error(emsg, st->nstr);
                   3007:            else
                   3008:                Var_Set(st->v->name, st->newStr, v_ctxt);
                   3009:            free(st->newStr);
1.236     rillig   3010:            break;
1.273     rillig   3011:        }
1.272     rillig   3012:        case '?':
                   3013:            if ((st->v->flags & VAR_JUNK) == 0)
                   3014:                break;
                   3015:            /* FALLTHROUGH */
1.236     rillig   3016:        default:
1.273     rillig   3017:            Var_Set(st->v->name, val, v_ctxt);
1.236     rillig   3018:            break;
                   3019:        }
                   3020:     }
1.273     rillig   3021:     free(val);
1.272     rillig   3022:     st->newStr = varNoError;
                   3023:     return 0;
1.236     rillig   3024: }
                   3025:
                   3026: /* remember current value */
                   3027: static Boolean
                   3028: ApplyModifier_Remember(ApplyModifiersState *st)
                   3029: {
                   3030:     st->cp = st->tstr + 1;     /* make sure it is set */
                   3031:     if (!STRMOD_MATCHX(st->tstr, "_", 1))
                   3032:        return FALSE;
                   3033:
                   3034:     if (st->tstr[1] == '=') {
                   3035:        char *np;
                   3036:        int n;
                   3037:
                   3038:        st->cp++;
                   3039:        n = strcspn(st->cp, ":)}");
1.249     rillig   3040:        np = bmake_strndup(st->cp, n + 1);
1.236     rillig   3041:        np[n] = '\0';
                   3042:        st->cp = st->tstr + 2 + n;
                   3043:        Var_Set(np, st->nstr, st->ctxt);
                   3044:        free(np);
                   3045:     } else {
                   3046:        Var_Set("_", st->nstr, st->ctxt);
                   3047:     }
                   3048:     st->newStr = st->nstr;
                   3049:     st->termc = *st->cp;
                   3050:     return TRUE;
                   3051: }
                   3052:
                   3053: #ifdef SYSVVARSUB
                   3054: /* :from=to */
                   3055: static int
                   3056: ApplyModifier_SysV(ApplyModifiersState *st)
                   3057: {
1.276     rillig   3058:     Boolean eqFound = FALSE;
1.245     rillig   3059:
1.236     rillig   3060:     /*
                   3061:      * First we make a pass through the string trying
                   3062:      * to verify it is a SYSV-make-style translation:
                   3063:      * it must be: <string1>=<string2>)
                   3064:      */
                   3065:     st->cp = st->tstr;
1.262     rillig   3066:     int nest = 1;
                   3067:     while (*st->cp != '\0' && nest > 0) {
1.236     rillig   3068:        if (*st->cp == '=') {
                   3069:            eqFound = TRUE;
                   3070:            /* continue looking for st->endc */
1.242     rillig   3071:        } else if (*st->cp == st->endc)
1.262     rillig   3072:            nest--;
1.236     rillig   3073:        else if (*st->cp == st->startc)
1.262     rillig   3074:            nest++;
                   3075:        if (nest > 0)
1.236     rillig   3076:            st->cp++;
                   3077:     }
1.245     rillig   3078:     if (*st->cp != st->endc || !eqFound)
                   3079:        return 0;
1.236     rillig   3080:
1.245     rillig   3081:     st->delim = '=';
                   3082:     st->cp = st->tstr;
1.276     rillig   3083:     VarPatternFlags pflags = 0;
1.261     rillig   3084:     /* FIXME: There's no point in having a single $ at the end of a
                   3085:      * SysV substitution since that will not be interpreted as an
                   3086:      * anchor anyway. */
1.276     rillig   3087:     char *lhs = ParseModifierPart(st->ctxt, &st->cp, st->delim, st->eflags,
                   3088:                                  &pflags, NULL, NULL);
                   3089:     if (lhs == NULL)
1.245     rillig   3090:        return 'c';
                   3091:
                   3092:     st->delim = st->endc;
1.276     rillig   3093:     char *rhs = ParseModifierPart(st->ctxt, &st->cp, st->delim, st->eflags,
                   3094:                                  NULL, NULL, NULL);
                   3095:     if (rhs == NULL)
1.245     rillig   3096:        return 'c';
1.236     rillig   3097:
1.245     rillig   3098:     /*
                   3099:      * SYSV modifications happen through the whole
                   3100:      * string. Note the pattern is anchored at the end.
                   3101:      */
                   3102:     st->termc = *--st->cp;
                   3103:     st->delim = '\0';
1.276     rillig   3104:     if (lhs[0] == '\0' && *st->nstr == '\0') {
1.245     rillig   3105:        st->newStr = st->nstr;  /* special case */
                   3106:     } else {
1.276     rillig   3107:        VarSYSVSubstArgs args = { lhs, rhs };
                   3108:        st->newStr = VarModify(st->ctxt, &st->parsestate, st->nstr,
                   3109:                               VarSYSVSubst, &args);
1.245     rillig   3110:     }
1.276     rillig   3111:     free(lhs);
                   3112:     free(rhs);
1.245     rillig   3113:     return '=';
1.236     rillig   3114: }
                   3115: #endif
                   3116:
1.108     sjg      3117: /*
                   3118:  * Now we need to apply any modifiers the user wants applied.
                   3119:  * These are:
                   3120:  *       :M<pattern>   words which match the given <pattern>.
1.138     dsl      3121:  *                     <pattern> is of the standard file
                   3122:  *                     wildcarding form.
1.108     sjg      3123:  *       :N<pattern>   words which do not match the given <pattern>.
                   3124:  *       :S<d><pat1><d><pat2><d>[1gW]
1.138     dsl      3125:  *                     Substitute <pat2> for <pat1> in the value
1.108     sjg      3126:  *       :C<d><pat1><d><pat2><d>[1gW]
1.138     dsl      3127:  *                     Substitute <pat2> for regex <pat1> in the value
                   3128:  *       :H            Substitute the head of each word
                   3129:  *       :T            Substitute the tail of each word
                   3130:  *       :E            Substitute the extension (minus '.') of
                   3131:  *                     each word
                   3132:  *       :R            Substitute the root of each word
                   3133:  *                     (pathname minus the suffix).
                   3134:  *       :O            ("Order") Alphabeticaly sort words in variable.
                   3135:  *       :Ox           ("intermiX") Randomize words in variable.
                   3136:  *       :u            ("uniq") Remove adjacent duplicate words.
                   3137:  *       :tu           Converts the variable contents to uppercase.
                   3138:  *       :tl           Converts the variable contents to lowercase.
                   3139:  *       :ts[c]        Sets varSpace - the char used to
                   3140:  *                     separate words to 'c'. If 'c' is
                   3141:  *                     omitted then no separation is used.
                   3142:  *       :tW           Treat the variable contents as a single
                   3143:  *                     word, even if it contains spaces.
                   3144:  *                     (Mnemonic: one big 'W'ord.)
                   3145:  *       :tw           Treat the variable contents as multiple
                   3146:  *                     space-separated words.
                   3147:  *                     (Mnemonic: many small 'w'ords.)
                   3148:  *       :[index]      Select a single word from the value.
                   3149:  *       :[start..end] Select multiple words from the value.
                   3150:  *       :[*] or :[0]  Select the entire value, as a single
                   3151:  *                     word.  Equivalent to :tW.
                   3152:  *       :[@]          Select the entire value, as multiple
                   3153:  *                     words.  Undoes the effect of :[*].
                   3154:  *                     Equivalent to :tw.
                   3155:  *       :[#]          Returns the number of words in the value.
                   3156:  *
                   3157:  *       :?<true-value>:<false-value>
                   3158:  *                     If the variable evaluates to true, return
                   3159:  *                     true value, else return the second value.
                   3160:  *       :lhs=rhs      Like :S, but the rhs goes to the end of
                   3161:  *                     the invocation.
                   3162:  *       :sh           Treat the current value as a command
                   3163:  *                     to be run, new value is its output.
1.108     sjg      3164:  * The following added so we can handle ODE makefiles.
1.138     dsl      3165:  *       :@<tmpvar>@<newval>@
                   3166:  *                     Assign a temporary local variable <tmpvar>
                   3167:  *                     to the current value of each word in turn
                   3168:  *                     and replace each word with the result of
                   3169:  *                     evaluating <newval>
                   3170:  *       :D<newval>    Use <newval> as value if variable defined
                   3171:  *       :U<newval>    Use <newval> as value if variable undefined
                   3172:  *       :L            Use the name of the variable as the value.
                   3173:  *       :P            Use the path of the node that has the same
                   3174:  *                     name as the variable as the value.  This
                   3175:  *                     basically includes an implied :L so that
                   3176:  *                     the common method of refering to the path
                   3177:  *                     of your dependent 'x' in a rule is to use
                   3178:  *                     the form '${x:P}'.
                   3179:  *       :!<cmd>!      Run cmd much the same as :sh run's the
                   3180:  *                     current value of the variable.
1.283   ! rillig   3181:  * Assignment operators (see ApplyModifier_Assign).
1.1       cgd      3182:  */
1.108     sjg      3183: static char *
                   3184: ApplyModifiers(char *nstr, const char *tstr,
1.236     rillig   3185:               int const startc, int const endc,
1.268     rillig   3186:               Var * const v, GNode * const ctxt, VarEvalFlags const eflags,
1.236     rillig   3187:               int * const lengthPtr, void ** const freePtr)
                   3188: {
                   3189:     ApplyModifiersState st = {
1.268     rillig   3190:        startc, endc, v, ctxt, eflags, lengthPtr, freePtr,
1.236     rillig   3191:        nstr, tstr, tstr, tstr,
1.262     rillig   3192:        '\0', '\0', 0, {' ', FALSE}, NULL
1.236     rillig   3193:     };
1.15      christos 3194:
1.236     rillig   3195:     while (*st.tstr && *st.tstr != st.endc) {
1.142     dsl      3196:
1.236     rillig   3197:        if (*st.tstr == '$') {
1.142     dsl      3198:            /*
1.167     sjg      3199:             * We may have some complex modifiers in a variable.
1.1       cgd      3200:             */
1.108     sjg      3201:            void *freeIt;
                   3202:            char *rval;
1.127     christos 3203:            int rlen;
1.167     sjg      3204:            int c;
1.22      christos 3205:
1.268     rillig   3206:            rval = Var_Parse(st.tstr, st.ctxt, st.eflags, &rlen, &freeIt);
1.1       cgd      3207:
1.167     sjg      3208:            /*
1.236     rillig   3209:             * If we have not parsed up to st.endc or ':',
1.167     sjg      3210:             * we are not interested.
                   3211:             */
                   3212:            if (rval != NULL && *rval &&
1.236     rillig   3213:                (c = st.tstr[rlen]) != '\0' &&
1.167     sjg      3214:                c != ':' &&
1.236     rillig   3215:                c != st.endc) {
1.196     christos 3216:                free(freeIt);
1.167     sjg      3217:                goto apply_mods;
                   3218:            }
                   3219:
1.108     sjg      3220:            if (DEBUG(VAR)) {
1.114     dsl      3221:                fprintf(debug_file, "Got '%s' from '%.*s'%.*s\n",
1.236     rillig   3222:                       rval, rlen, st.tstr, rlen, st.tstr + rlen);
1.22      christos 3223:            }
1.1       cgd      3224:
1.236     rillig   3225:            st.tstr += rlen;
1.15      christos 3226:
1.108     sjg      3227:            if (rval != NULL && *rval) {
1.127     christos 3228:                int used;
1.15      christos 3229:
1.236     rillig   3230:                st.nstr = ApplyModifiers(st.nstr, rval, 0, 0, st.v,
1.268     rillig   3231:                                      st.ctxt, st.eflags, &used, st.freePtr);
1.236     rillig   3232:                if (st.nstr == var_Error
1.268     rillig   3233:                    || (st.nstr == varNoError && (st.eflags & VARE_UNDEFERR) == 0)
1.111     rillig   3234:                    || strlen(rval) != (size_t) used) {
1.196     christos 3235:                    free(freeIt);
1.240     rillig   3236:                    goto out;   /* error already reported */
1.1       cgd      3237:                }
                   3238:            }
1.196     christos 3239:            free(freeIt);
1.236     rillig   3240:            if (*st.tstr == ':')
                   3241:                st.tstr++;
                   3242:            else if (!*st.tstr && st.endc) {
1.246     rillig   3243:                Error("Unclosed variable specification after complex "
                   3244:                    "modifier (expecting '%c') for %s", st.endc, st.v->name);
1.119     sjg      3245:                goto out;
                   3246:            }
1.108     sjg      3247:            continue;
                   3248:        }
1.167     sjg      3249:     apply_mods:
1.108     sjg      3250:        if (DEBUG(VAR)) {
1.236     rillig   3251:            fprintf(debug_file, "Applying[%s] :%c to \"%s\"\n", st.v->name,
                   3252:                *st.tstr, st.nstr);
1.1       cgd      3253:        }
1.236     rillig   3254:        st.newStr = var_Error;
                   3255:        switch ((st.modifier = *st.tstr)) {
1.108     sjg      3256:        case ':':
1.1       cgd      3257:            {
1.236     rillig   3258:                int res = ApplyModifier_Assign(&st);
                   3259:                if (res == 'b')
                   3260:                    goto bad_modifier;
                   3261:                if (res == 'c')
1.108     sjg      3262:                    goto cleanup;
1.236     rillig   3263:                if (res == 'd')
                   3264:                    goto default_case;
1.108     sjg      3265:                break;
                   3266:            }
1.236     rillig   3267:        case '@':
                   3268:            ApplyModifier_At(&st);
                   3269:            break;
                   3270:        case '_':
                   3271:            if (!ApplyModifier_Remember(&st))
                   3272:                goto default_case;
                   3273:            break;
1.108     sjg      3274:        case 'D':
                   3275:        case 'U':
1.236     rillig   3276:            ApplyModifier_Defined(&st);
                   3277:            break;
1.108     sjg      3278:        case 'L':
                   3279:            {
1.236     rillig   3280:                if ((st.v->flags & VAR_JUNK) != 0)
                   3281:                    st.v->flags |= VAR_KEEP;
                   3282:                st.newStr = bmake_strdup(st.v->name);
                   3283:                st.cp = ++st.tstr;
                   3284:                st.termc = *st.tstr;
1.108     sjg      3285:                break;
                   3286:            }
                   3287:        case 'P':
1.236     rillig   3288:            ApplyModifier_Path(&st);
                   3289:            break;
1.108     sjg      3290:        case '!':
1.236     rillig   3291:            if (!ApplyModifier_Exclam(&st))
                   3292:                goto cleanup;
                   3293:            break;
                   3294:        case '[':
1.108     sjg      3295:            {
1.236     rillig   3296:                int res = ApplyModifier_Words(&st);
                   3297:                if (res == 'b')
                   3298:                    goto bad_modifier;
                   3299:                if (res == 'c')
1.108     sjg      3300:                    goto cleanup;
                   3301:                break;
                   3302:            }
1.164     sjg      3303:        case 'g':
1.236     rillig   3304:            if (!ApplyModifier_Gmtime(&st))
1.165     sjg      3305:                goto default_case;
1.164     sjg      3306:            break;
1.163     joerg    3307:        case 'h':
1.236     rillig   3308:            if (!ApplyModifier_Hash(&st))
1.165     sjg      3309:                goto default_case;
1.163     joerg    3310:            break;
1.164     sjg      3311:        case 'l':
1.236     rillig   3312:            if (!ApplyModifier_Localtime(&st))
1.165     sjg      3313:                goto default_case;
1.164     sjg      3314:            break;
1.108     sjg      3315:        case 't':
1.236     rillig   3316:            if (!ApplyModifier_To(&st))
                   3317:                goto bad_modifier;
                   3318:            break;
1.108     sjg      3319:        case 'N':
                   3320:        case 'M':
1.236     rillig   3321:            ApplyModifier_Match(&st);
                   3322:            break;
1.108     sjg      3323:        case 'S':
1.236     rillig   3324:            if (!ApplyModifier_Subst(&st))
                   3325:                goto cleanup;
                   3326:            break;
1.108     sjg      3327:        case '?':
1.236     rillig   3328:            if (!ApplyModifier_IfElse(&st))
                   3329:                goto cleanup;
                   3330:            break;
1.108     sjg      3331: #ifndef NO_REGEX
                   3332:        case 'C':
1.236     rillig   3333:            if (!ApplyModifier_Regex(&st))
                   3334:                goto cleanup;
                   3335:            break;
1.108     sjg      3336: #endif
1.220     christos 3337:        case 'q':
1.108     sjg      3338:        case 'Q':
1.236     rillig   3339:            if (st.tstr[1] == st.endc || st.tstr[1] == ':') {
                   3340:                st.newStr = VarQuote(st.nstr, st.modifier == 'q');
                   3341:                st.cp = st.tstr + 1;
                   3342:                st.termc = *st.cp;
1.108     sjg      3343:                break;
                   3344:            }
                   3345:            goto default_case;
                   3346:        case 'T':
1.236     rillig   3347:            if (st.tstr[1] == st.endc || st.tstr[1] == ':') {
                   3348:                st.newStr = VarModify(st.ctxt, &st.parsestate, st.nstr, VarTail,
1.278     rillig   3349:                                      NULL);
1.236     rillig   3350:                st.cp = st.tstr + 1;
                   3351:                st.termc = *st.cp;
1.108     sjg      3352:                break;
                   3353:            }
                   3354:            goto default_case;
                   3355:        case 'H':
1.236     rillig   3356:            if (st.tstr[1] == st.endc || st.tstr[1] == ':') {
                   3357:                st.newStr = VarModify(st.ctxt, &st.parsestate, st.nstr, VarHead,
1.278     rillig   3358:                                      NULL);
1.236     rillig   3359:                st.cp = st.tstr + 1;
                   3360:                st.termc = *st.cp;
1.108     sjg      3361:                break;
                   3362:            }
                   3363:            goto default_case;
                   3364:        case 'E':
1.236     rillig   3365:            if (st.tstr[1] == st.endc || st.tstr[1] == ':') {
                   3366:                st.newStr = VarModify(st.ctxt, &st.parsestate, st.nstr, VarSuffix,
1.278     rillig   3367:                                      NULL);
1.236     rillig   3368:                st.cp = st.tstr + 1;
                   3369:                st.termc = *st.cp;
1.108     sjg      3370:                break;
                   3371:            }
                   3372:            goto default_case;
                   3373:        case 'R':
1.236     rillig   3374:            if (st.tstr[1] == st.endc || st.tstr[1] == ':') {
                   3375:                st.newStr = VarModify(st.ctxt, &st.parsestate, st.nstr, VarRoot,
1.278     rillig   3376:                                      NULL);
1.236     rillig   3377:                st.cp = st.tstr + 1;
                   3378:                st.termc = *st.cp;
1.108     sjg      3379:                break;
                   3380:            }
                   3381:            goto default_case;
1.210     sjg      3382:        case 'r':
1.236     rillig   3383:            if (!ApplyModifier_Range(&st))
                   3384:                goto default_case;
                   3385:            break;
1.108     sjg      3386:        case 'O':
1.236     rillig   3387:            if (!ApplyModifier_Order(&st))
                   3388:                goto bad_modifier;
                   3389:            break;
1.108     sjg      3390:        case 'u':
1.236     rillig   3391:            if (st.tstr[1] == st.endc || st.tstr[1] == ':') {
                   3392:                st.newStr = VarUniq(st.nstr);
                   3393:                st.cp = st.tstr + 1;
                   3394:                st.termc = *st.cp;
1.108     sjg      3395:                break;
                   3396:            }
                   3397:            goto default_case;
                   3398: #ifdef SUNSHCMD
                   3399:        case 's':
1.236     rillig   3400:            if (st.tstr[1] == 'h' && (st.tstr[2] == st.endc || st.tstr[2] == ':')) {
1.108     sjg      3401:                const char *emsg;
1.268     rillig   3402:                if (st.eflags & VARE_WANTRES) {
1.236     rillig   3403:                    st.newStr = Cmd_Exec(st.nstr, &emsg);
1.197     sjg      3404:                    if (emsg)
1.236     rillig   3405:                        Error(emsg, st.nstr);
1.197     sjg      3406:                } else
1.236     rillig   3407:                    st.newStr = varNoError;
                   3408:                st.cp = st.tstr + 2;
                   3409:                st.termc = *st.cp;
1.108     sjg      3410:                break;
                   3411:            }
                   3412:            goto default_case;
                   3413: #endif
                   3414:        default:
1.142     dsl      3415:        default_case:
1.236     rillig   3416:            {
1.108     sjg      3417: #ifdef SYSVVARSUB
1.236     rillig   3418:                int res = ApplyModifier_SysV(&st);
                   3419:                if (res == 'c')
1.108     sjg      3420:                    goto cleanup;
1.236     rillig   3421:                if (res != '=')
1.108     sjg      3422: #endif
                   3423:                {
1.236     rillig   3424:                    Error("Unknown modifier '%c'", *st.tstr);
                   3425:                    for (st.cp = st.tstr+1;
                   3426:                         *st.cp != ':' && *st.cp != st.endc && *st.cp != '\0';
                   3427:                         st.cp++)
1.108     sjg      3428:                        continue;
1.236     rillig   3429:                    st.termc = *st.cp;
                   3430:                    st.newStr = var_Error;
1.108     sjg      3431:                }
                   3432:            }
                   3433:        }
                   3434:        if (DEBUG(VAR)) {
1.172     christos 3435:            fprintf(debug_file, "Result[%s] of :%c is \"%s\"\n",
1.236     rillig   3436:                st.v->name, st.modifier, st.newStr);
1.108     sjg      3437:        }
1.25      christos 3438:
1.236     rillig   3439:        if (st.newStr != st.nstr) {
                   3440:            if (*st.freePtr) {
                   3441:                free(st.nstr);
                   3442:                *st.freePtr = NULL;
1.108     sjg      3443:            }
1.236     rillig   3444:            st.nstr = st.newStr;
                   3445:            if (st.nstr != var_Error && st.nstr != varNoError) {
                   3446:                *st.freePtr = st.nstr;
1.108     sjg      3447:            }
                   3448:        }
1.236     rillig   3449:        if (st.termc == '\0' && st.endc != '\0') {
1.246     rillig   3450:            Error("Unclosed variable specification (expecting '%c') "
                   3451:                "for \"%s\" (value \"%s\") modifier %c",
                   3452:                st.endc, st.v->name, st.nstr, st.modifier);
1.236     rillig   3453:        } else if (st.termc == ':') {
                   3454:            st.cp++;
1.108     sjg      3455:        }
1.236     rillig   3456:        st.tstr = st.cp;
1.108     sjg      3457:     }
1.240     rillig   3458: out:
1.236     rillig   3459:     *st.lengthPtr = st.tstr - st.start;
                   3460:     return st.nstr;
1.25      christos 3461:
1.240     rillig   3462: bad_modifier:
1.108     sjg      3463:     /* "{(" */
1.236     rillig   3464:     Error("Bad modifier `:%.*s' for %s", (int)strcspn(st.tstr, ":)}"), st.tstr,
                   3465:          st.v->name);
1.25      christos 3466:
1.240     rillig   3467: cleanup:
1.236     rillig   3468:     *st.lengthPtr = st.cp - st.start;
                   3469:     if (st.delim != '\0')
1.108     sjg      3470:        Error("Unclosed substitution for %s (%c missing)",
1.236     rillig   3471:              st.v->name, st.delim);
                   3472:     free(*st.freePtr);
                   3473:     *st.freePtr = NULL;
1.231     rillig   3474:     return var_Error;
1.108     sjg      3475: }
1.25      christos 3476:
1.108     sjg      3477: /*-
                   3478:  *-----------------------------------------------------------------------
                   3479:  * Var_Parse --
                   3480:  *     Given the start of a variable invocation, extract the variable
                   3481:  *     name and find its value, then modify it according to the
                   3482:  *     specification.
                   3483:  *
                   3484:  * Input:
                   3485:  *     str             The string to parse
                   3486:  *     ctxt            The context for the variable
1.259     rillig   3487:  *     flags           VARE_UNDEFERR   if undefineds are an error
                   3488:  *                     VARE_WANTRES    if we actually want the result
                   3489:  *                     VARE_ASSIGN     if we are in a := assignment
1.108     sjg      3490:  *     lengthPtr       OUT: The length of the specification
1.121     apb      3491:  *     freePtr         OUT: Non-NULL if caller should free *freePtr
1.108     sjg      3492:  *
                   3493:  * Results:
                   3494:  *     The (possibly-modified) value of the variable or var_Error if the
                   3495:  *     specification is invalid. The length of the specification is
                   3496:  *     placed in *lengthPtr (for invalid specifications, this is just
                   3497:  *     2...?).
1.121     apb      3498:  *     If *freePtr is non-NULL then it's a pointer that the caller
                   3499:  *     should pass to free() to free memory used by the result.
1.108     sjg      3500:  *
                   3501:  * Side Effects:
                   3502:  *     None.
                   3503:  *
                   3504:  *-----------------------------------------------------------------------
                   3505:  */
                   3506: /* coverity[+alloc : arg-*4] */
                   3507: char *
1.259     rillig   3508: Var_Parse(const char *str, GNode *ctxt, VarEvalFlags flags,
1.202     christos 3509:          int *lengthPtr, void **freePtr)
1.108     sjg      3510: {
1.240     rillig   3511:     const char *tstr;          /* Pointer into str */
                   3512:     Var                *v;             /* Variable in invocation */
                   3513:     Boolean     haveModifier;  /* TRUE if have modifiers for the variable */
                   3514:     char        endc;          /* Ending character when variable in parens
1.108     sjg      3515:                                 * or braces */
1.240     rillig   3516:     char        startc;        /* Starting character when variable in parens
1.108     sjg      3517:                                 * or braces */
1.240     rillig   3518:     int                 vlen;          /* Length of variable name */
                   3519:     const char         *start;         /* Points to original start of str */
                   3520:     char       *nstr;          /* New string, used during expansion */
                   3521:     Boolean     dynamic;       /* TRUE if the variable is local and we're
1.108     sjg      3522:                                 * expanding it in a non-local context. This
                   3523:                                 * is done to support dynamic sources. The
                   3524:                                 * result is just the invocation, unaltered */
1.240     rillig   3525:     const char *extramodifiers; /* extra modifiers to apply first */
                   3526:     char        name[2];
1.1       cgd      3527:
1.108     sjg      3528:     *freePtr = NULL;
1.191     dholland 3529:     extramodifiers = NULL;
1.108     sjg      3530:     dynamic = FALSE;
                   3531:     start = str;
1.1       cgd      3532:
1.141     dsl      3533:     startc = str[1];
                   3534:     if (startc != PROPEN && startc != BROPEN) {
1.108     sjg      3535:        /*
                   3536:         * If it's not bounded by braces of some sort, life is much simpler.
                   3537:         * We just need to check for the first character and return the
                   3538:         * value if it exists.
                   3539:         */
1.15      christos 3540:
1.141     dsl      3541:        /* Error out some really stupid names */
                   3542:        if (startc == '\0' || strchr(")}:$", startc)) {
                   3543:            *lengthPtr = 1;
                   3544:            return var_Error;
                   3545:        }
                   3546:        name[0] = startc;
1.108     sjg      3547:        name[1] = '\0';
1.16      christos 3548:
1.108     sjg      3549:        v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
1.136     dsl      3550:        if (v == NULL) {
1.108     sjg      3551:            *lengthPtr = 2;
1.1       cgd      3552:
1.108     sjg      3553:            if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
                   3554:                /*
                   3555:                 * If substituting a local variable in a non-local context,
                   3556:                 * assume it's for dynamic source stuff. We have to handle
                   3557:                 * this specially and return the longhand for the variable
                   3558:                 * with the dollar sign escaped so it makes it back to the
                   3559:                 * caller. Only four of the local variables are treated
                   3560:                 * specially as they are the only four that will be set
                   3561:                 * when dynamic sources are expanded.
                   3562:                 */
                   3563:                switch (str[1]) {
1.242     rillig   3564:                case '@':
                   3565:                    return UNCONST("$(.TARGET)");
                   3566:                case '%':
                   3567:                    return UNCONST("$(.MEMBER)");
                   3568:                case '*':
                   3569:                    return UNCONST("$(.PREFIX)");
                   3570:                case '!':
                   3571:                    return UNCONST("$(.ARCHIVE)");
1.108     sjg      3572:                }
                   3573:            }
1.259     rillig   3574:            return (flags & VARE_UNDEFERR) ? var_Error : varNoError;
1.108     sjg      3575:        } else {
                   3576:            haveModifier = FALSE;
                   3577:            tstr = &str[1];
                   3578:            endc = str[1];
                   3579:        }
1.123     apb      3580:     } else {
1.240     rillig   3581:        Buffer buf;             /* Holds the variable name */
1.185     sjg      3582:        int depth = 1;
1.1       cgd      3583:
1.108     sjg      3584:        endc = startc == PROPEN ? PRCLOSE : BRCLOSE;
1.146     dsl      3585:        Buf_Init(&buf, 0);
1.1       cgd      3586:
1.108     sjg      3587:        /*
                   3588:         * Skip to the end character or a colon, whichever comes first.
                   3589:         */
1.249     rillig   3590:        for (tstr = str + 2; *tstr != '\0'; tstr++) {
1.240     rillig   3591:            /* Track depth so we can spot parse errors. */
                   3592:            if (*tstr == startc)
1.185     sjg      3593:                depth++;
                   3594:            if (*tstr == endc) {
                   3595:                if (--depth == 0)
                   3596:                    break;
                   3597:            }
1.240     rillig   3598:            if (depth == 1 && *tstr == ':')
1.185     sjg      3599:                break;
1.240     rillig   3600:            /* A variable inside a variable, expand. */
1.108     sjg      3601:            if (*tstr == '$') {
1.127     christos 3602:                int rlen;
1.108     sjg      3603:                void *freeIt;
1.226     rillig   3604:                char *rval = Var_Parse(tstr, ctxt, flags, &rlen, &freeIt);
1.240     rillig   3605:                if (rval != NULL)
1.146     dsl      3606:                    Buf_AddBytes(&buf, strlen(rval), rval);
1.196     christos 3607:                free(freeIt);
1.108     sjg      3608:                tstr += rlen - 1;
1.242     rillig   3609:            } else
1.146     dsl      3610:                Buf_AddByte(&buf, *tstr);
1.108     sjg      3611:        }
                   3612:        if (*tstr == ':') {
                   3613:            haveModifier = TRUE;
1.185     sjg      3614:        } else if (*tstr == endc) {
1.108     sjg      3615:            haveModifier = FALSE;
                   3616:        } else {
                   3617:            /*
                   3618:             * If we never did find the end character, return NULL
                   3619:             * right now, setting the length to be the distance to
                   3620:             * the end of the string, since that's what make does.
                   3621:             */
                   3622:            *lengthPtr = tstr - str;
1.146     dsl      3623:            Buf_Destroy(&buf, TRUE);
1.231     rillig   3624:            return var_Error;
1.108     sjg      3625:        }
1.146     dsl      3626:        str = Buf_GetAll(&buf, &vlen);
1.93      sjg      3627:
1.123     apb      3628:        /*
                   3629:         * At this point, str points into newly allocated memory from
                   3630:         * buf, containing only the name of the variable.
                   3631:         *
                   3632:         * start and tstr point into the const string that was pointed
                   3633:         * to by the original value of the str parameter.  start points
                   3634:         * to the '$' at the beginning of the string, while tstr points
                   3635:         * to the char just after the end of the variable name -- this
                   3636:         * will be '\0', ':', PRCLOSE, or BRCLOSE.
                   3637:         */
                   3638:
1.108     sjg      3639:        v = VarFind(str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
1.141     dsl      3640:        /*
                   3641:         * Check also for bogus D and F forms of local variables since we're
                   3642:         * in a local context and the name is the right length.
                   3643:         */
1.136     dsl      3644:        if ((v == NULL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
1.141     dsl      3645:                (vlen == 2) && (str[1] == 'F' || str[1] == 'D') &&
1.190     dholland 3646:                strchr("@%?*!<>", str[0]) != NULL) {
1.108     sjg      3647:            /*
1.141     dsl      3648:             * Well, it's local -- go look for it.
1.108     sjg      3649:             */
1.141     dsl      3650:            name[0] = *str;
                   3651:            name[1] = '\0';
                   3652:            v = VarFind(name, ctxt, 0);
1.15      christos 3653:
1.141     dsl      3654:            if (v != NULL) {
                   3655:                if (str[1] == 'D') {
1.240     rillig   3656:                    extramodifiers = "H:";
1.242     rillig   3657:                } else { /* F */
1.240     rillig   3658:                    extramodifiers = "T:";
1.1       cgd      3659:                }
                   3660:            }
1.108     sjg      3661:        }
                   3662:
1.136     dsl      3663:        if (v == NULL) {
1.108     sjg      3664:            if (((vlen == 1) ||
1.141     dsl      3665:                 (((vlen == 2) && (str[1] == 'F' || str[1] == 'D')))) &&
1.108     sjg      3666:                ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
                   3667:            {
                   3668:                /*
                   3669:                 * If substituting a local variable in a non-local context,
                   3670:                 * assume it's for dynamic source stuff. We have to handle
                   3671:                 * this specially and return the longhand for the variable
                   3672:                 * with the dollar sign escaped so it makes it back to the
                   3673:                 * caller. Only four of the local variables are treated
                   3674:                 * specially as they are the only four that will be set
                   3675:                 * when dynamic sources are expanded.
                   3676:                 */
                   3677:                switch (*str) {
1.242     rillig   3678:                case '@':
                   3679:                case '%':
                   3680:                case '*':
                   3681:                case '!':
                   3682:                    dynamic = TRUE;
                   3683:                    break;
1.108     sjg      3684:                }
1.240     rillig   3685:            } else if (vlen > 2 && *str == '.' &&
1.108     sjg      3686:                       isupper((unsigned char) str[1]) &&
1.240     rillig   3687:                       (ctxt == VAR_CMD || ctxt == VAR_GLOBAL))
1.108     sjg      3688:            {
1.240     rillig   3689:                int len = vlen - 1;
1.108     sjg      3690:                if ((strncmp(str, ".TARGET", len) == 0) ||
                   3691:                    (strncmp(str, ".ARCHIVE", len) == 0) ||
                   3692:                    (strncmp(str, ".PREFIX", len) == 0) ||
                   3693:                    (strncmp(str, ".MEMBER", len) == 0))
                   3694:                {
                   3695:                    dynamic = TRUE;
                   3696:                }
1.1       cgd      3697:            }
1.15      christos 3698:
1.108     sjg      3699:            if (!haveModifier) {
                   3700:                /*
                   3701:                 * No modifiers -- have specification length so we can return
                   3702:                 * now.
                   3703:                 */
                   3704:                *lengthPtr = tstr - start + 1;
                   3705:                if (dynamic) {
1.134     joerg    3706:                    char *pstr = bmake_strndup(start, *lengthPtr);
1.108     sjg      3707:                    *freePtr = pstr;
1.146     dsl      3708:                    Buf_Destroy(&buf, TRUE);
1.231     rillig   3709:                    return pstr;
1.40      sjg      3710:                } else {
1.146     dsl      3711:                    Buf_Destroy(&buf, TRUE);
1.259     rillig   3712:                    return (flags & VARE_UNDEFERR) ? var_Error : varNoError;
1.40      sjg      3713:                }
1.1       cgd      3714:            } else {
1.108     sjg      3715:                /*
                   3716:                 * Still need to get to the end of the variable specification,
                   3717:                 * so kludge up a Var structure for the modifications
                   3718:                 */
1.134     joerg    3719:                v = bmake_malloc(sizeof(Var));
1.108     sjg      3720:                v->name = UNCONST(str);
1.146     dsl      3721:                Buf_Init(&v->val, 1);
1.108     sjg      3722:                v->flags = VAR_JUNK;
1.146     dsl      3723:                Buf_Destroy(&buf, FALSE);
1.1       cgd      3724:            }
1.108     sjg      3725:        } else
1.146     dsl      3726:            Buf_Destroy(&buf, TRUE);
1.108     sjg      3727:     }
                   3728:
1.188     joerg    3729:     if (v->flags & VAR_IN_USE) {
                   3730:        Fatal("Variable %s is recursive.", v->name);
                   3731:        /*NOTREACHED*/
                   3732:     } else {
                   3733:        v->flags |= VAR_IN_USE;
                   3734:     }
                   3735:     /*
                   3736:      * Before doing any modification, we have to make sure the value
                   3737:      * has been fully expanded. If it looks like recursion might be
                   3738:      * necessary (there's a dollar sign somewhere in the variable's value)
                   3739:      * we just call Var_Subst to do any other substitutions that are
                   3740:      * necessary. Note that the value returned by Var_Subst will have
                   3741:      * been dynamically-allocated, so it will need freeing when we
                   3742:      * return.
                   3743:      */
                   3744:     nstr = Buf_GetAll(&v->val, NULL);
1.259     rillig   3745:     if (strchr(nstr, '$') != NULL && (flags & VARE_WANTRES) != 0) {
1.202     christos 3746:        nstr = Var_Subst(NULL, nstr, ctxt, flags);
1.188     joerg    3747:        *freePtr = nstr;
                   3748:     }
1.187     christos 3749:
1.188     joerg    3750:     v->flags &= ~VAR_IN_USE;
1.108     sjg      3751:
1.240     rillig   3752:     if (nstr != NULL && (haveModifier || extramodifiers != NULL)) {
1.191     dholland 3753:        void *extraFree;
1.127     christos 3754:        int used;
1.108     sjg      3755:
1.191     dholland 3756:        extraFree = NULL;
                   3757:        if (extramodifiers != NULL) {
1.240     rillig   3758:            nstr = ApplyModifiers(nstr, extramodifiers, '(', ')',
                   3759:                                  v, ctxt, flags, &used, &extraFree);
1.191     dholland 3760:        }
                   3761:
                   3762:        if (haveModifier) {
1.240     rillig   3763:            /* Skip initial colon. */
                   3764:            tstr++;
1.191     dholland 3765:
1.240     rillig   3766:            nstr = ApplyModifiers(nstr, tstr, startc, endc,
                   3767:                                  v, ctxt, flags, &used, freePtr);
                   3768:            tstr += used;
                   3769:            free(extraFree);
1.191     dholland 3770:        } else {
1.240     rillig   3771:            *freePtr = extraFree;
1.191     dholland 3772:        }
1.119     sjg      3773:     }
1.240     rillig   3774:     *lengthPtr = tstr - start + (*tstr ? 1 : 0);
1.15      christos 3775:
1.1       cgd      3776:     if (v->flags & VAR_FROM_ENV) {
1.249     rillig   3777:        Boolean destroy = FALSE;
1.15      christos 3778:
1.146     dsl      3779:        if (nstr != Buf_GetAll(&v->val, NULL)) {
1.1       cgd      3780:            destroy = TRUE;
                   3781:        } else {
                   3782:            /*
                   3783:             * Returning the value unmodified, so tell the caller to free
                   3784:             * the thing.
                   3785:             */
1.104     christos 3786:            *freePtr = nstr;
1.1       cgd      3787:        }
1.105     christos 3788:        VarFreeEnv(v, destroy);
1.1       cgd      3789:     } else if (v->flags & VAR_JUNK) {
                   3790:        /*
1.121     apb      3791:         * Perform any free'ing needed and set *freePtr to NULL so the caller
1.1       cgd      3792:         * doesn't try to free a static pointer.
1.40      sjg      3793:         * If VAR_KEEP is also set then we want to keep str as is.
1.1       cgd      3794:         */
1.58      itojun   3795:        if (!(v->flags & VAR_KEEP)) {
1.40      sjg      3796:            if (*freePtr) {
1.73      christos 3797:                free(nstr);
1.108     sjg      3798:                *freePtr = NULL;
1.40      sjg      3799:            }
                   3800:            if (dynamic) {
1.134     joerg    3801:                nstr = bmake_strndup(start, *lengthPtr);
1.104     christos 3802:                *freePtr = nstr;
1.40      sjg      3803:            } else {
1.259     rillig   3804:                nstr = (flags & VARE_UNDEFERR) ? var_Error : varNoError;
1.40      sjg      3805:            }
1.34      christos 3806:        }
1.146     dsl      3807:        if (nstr != Buf_GetAll(&v->val, NULL))
                   3808:            Buf_Destroy(&v->val, TRUE);
1.98      christos 3809:        free(v->name);
                   3810:        free(v);
1.1       cgd      3811:     }
1.231     rillig   3812:     return nstr;
1.1       cgd      3813: }
                   3814:
                   3815: /*-
                   3816:  *-----------------------------------------------------------------------
                   3817:  * Var_Subst  --
1.250     rillig   3818:  *     Substitute for all variables in the given string in the given context.
1.259     rillig   3819:  *     If flags & VARE_UNDEFERR, Parse_Error will be called when an undefined
1.1       cgd      3820:  *     variable is encountered.
                   3821:  *
1.70      wiz      3822:  * Input:
                   3823:  *     var             Named variable || NULL for all
                   3824:  *     str             the string which to substitute
                   3825:  *     ctxt            the context wherein to find variables
1.259     rillig   3826:  *     flags           VARE_UNDEFERR   if undefineds are an error
                   3827:  *                     VARE_WANTRES    if we actually want the result
                   3828:  *                     VARE_ASSIGN     if we are in a := assignment
1.70      wiz      3829:  *
1.1       cgd      3830:  * Results:
                   3831:  *     The resulting string.
                   3832:  *
                   3833:  * Side Effects:
1.250     rillig   3834:  *     None.
1.1       cgd      3835:  *-----------------------------------------------------------------------
                   3836:  */
                   3837: char *
1.259     rillig   3838: Var_Subst(const char *var, const char *str, GNode *ctxt, VarEvalFlags flags)
1.1       cgd      3839: {
1.240     rillig   3840:     Buffer     buf;            /* Buffer for forming things */
                   3841:     char       *val;           /* Value to substitute for a variable */
                   3842:     int                length;         /* Length of the variable invocation */
                   3843:     Boolean    trailingBslash; /* variable ends in \ */
                   3844:     void       *freeIt = NULL; /* Set if it should be freed */
                   3845:     static Boolean errorReported; /* Set true if an error has already
                   3846:                                 * been reported to prevent a plethora
                   3847:                                 * of messages when recursing */
1.1       cgd      3848:
1.146     dsl      3849:     Buf_Init(&buf, 0);
1.1       cgd      3850:     errorReported = FALSE;
1.96      christos 3851:     trailingBslash = FALSE;
1.1       cgd      3852:
                   3853:     while (*str) {
1.96      christos 3854:        if (*str == '\n' && trailingBslash)
1.146     dsl      3855:            Buf_AddByte(&buf, ' ');
1.48      mycroft  3856:        if (var == NULL && (*str == '$') && (str[1] == '$')) {
1.1       cgd      3857:            /*
                   3858:             * A dollar sign may be escaped either with another dollar sign.
                   3859:             * In such a case, we skip over the escape character and store the
                   3860:             * dollar sign into the buffer directly.
                   3861:             */
1.259     rillig   3862:            if (save_dollars && (flags & VARE_ASSIGN))
1.201     christos 3863:                Buf_AddByte(&buf, *str);
1.1       cgd      3864:            str++;
1.146     dsl      3865:            Buf_AddByte(&buf, *str);
1.1       cgd      3866:            str++;
                   3867:        } else if (*str != '$') {
                   3868:            /*
                   3869:             * Skip as many characters as possible -- either to the end of
                   3870:             * the string or to the next dollar sign (variable invocation).
                   3871:             */
1.249     rillig   3872:            const char *cp;
1.1       cgd      3873:
1.5       cgd      3874:            for (cp = str++; *str != '$' && *str != '\0'; str++)
                   3875:                continue;
1.146     dsl      3876:            Buf_AddBytes(&buf, str - cp, cp);
1.1       cgd      3877:        } else {
1.48      mycroft  3878:            if (var != NULL) {
                   3879:                int expand;
                   3880:                for (;;) {
1.100     christos 3881:                    if (str[1] == '\0') {
                   3882:                        /* A trailing $ is kind of a special case */
1.146     dsl      3883:                        Buf_AddByte(&buf, str[0]);
1.100     christos 3884:                        str++;
                   3885:                        expand = FALSE;
                   3886:                    } else if (str[1] != PROPEN && str[1] != BROPEN) {
1.48      mycroft  3887:                        if (str[1] != *var || strlen(var) > 1) {
1.146     dsl      3888:                            Buf_AddBytes(&buf, 2, str);
1.48      mycroft  3889:                            str += 2;
                   3890:                            expand = FALSE;
1.242     rillig   3891:                        } else
1.48      mycroft  3892:                            expand = TRUE;
                   3893:                        break;
1.240     rillig   3894:                    } else {
1.73      christos 3895:                        const char *p;
1.48      mycroft  3896:
1.242     rillig   3897:                        /* Scan up to the end of the variable name. */
1.48      mycroft  3898:                        for (p = &str[2]; *p &&
1.100     christos 3899:                             *p != ':' && *p != PRCLOSE && *p != BRCLOSE; p++)
1.48      mycroft  3900:                            if (*p == '$')
                   3901:                                break;
                   3902:                        /*
                   3903:                         * A variable inside the variable. We cannot expand
                   3904:                         * the external variable yet, so we try again with
                   3905:                         * the nested one
                   3906:                         */
                   3907:                        if (*p == '$') {
1.146     dsl      3908:                            Buf_AddBytes(&buf, p - str, str);
1.48      mycroft  3909:                            str = p;
                   3910:                            continue;
                   3911:                        }
                   3912:
1.127     christos 3913:                        if (strncmp(var, str + 2, p - str - 2) != 0 ||
1.48      mycroft  3914:                            var[p - str - 2] != '\0') {
                   3915:                            /*
                   3916:                             * Not the variable we want to expand, scan
                   3917:                             * until the next variable
                   3918:                             */
1.249     rillig   3919:                            for (; *p != '$' && *p != '\0'; p++)
1.48      mycroft  3920:                                continue;
1.146     dsl      3921:                            Buf_AddBytes(&buf, p - str, str);
1.48      mycroft  3922:                            str = p;
                   3923:                            expand = FALSE;
1.240     rillig   3924:                        } else
1.48      mycroft  3925:                            expand = TRUE;
                   3926:                        break;
                   3927:                    }
                   3928:                }
                   3929:                if (!expand)
                   3930:                    continue;
                   3931:            }
                   3932:
1.202     christos 3933:            val = Var_Parse(str, ctxt, flags, &length, &freeIt);
1.1       cgd      3934:
                   3935:            /*
                   3936:             * When we come down here, val should either point to the
                   3937:             * value of this variable, suitably modified, or be NULL.
                   3938:             * Length should be the total length of the potential
                   3939:             * variable invocation (from $ to end character...)
                   3940:             */
                   3941:            if (val == var_Error || val == varNoError) {
                   3942:                /*
                   3943:                 * If performing old-time variable substitution, skip over
                   3944:                 * the variable and continue with the substitution. Otherwise,
                   3945:                 * store the dollar sign and advance str so we continue with
                   3946:                 * the string...
                   3947:                 */
                   3948:                if (oldVars) {
                   3949:                    str += length;
1.259     rillig   3950:                } else if ((flags & VARE_UNDEFERR) || val == var_Error) {
1.1       cgd      3951:                    /*
                   3952:                     * If variable is undefined, complain and skip the
                   3953:                     * variable. The complaint will stop us from doing anything
                   3954:                     * when the file is parsed.
                   3955:                     */
                   3956:                    if (!errorReported) {
1.231     rillig   3957:                        Parse_Error(PARSE_FATAL, "Undefined variable \"%.*s\"",
                   3958:                                    length, str);
1.1       cgd      3959:                    }
                   3960:                    str += length;
                   3961:                    errorReported = TRUE;
                   3962:                } else {
1.146     dsl      3963:                    Buf_AddByte(&buf, *str);
1.1       cgd      3964:                    str += 1;
                   3965:                }
                   3966:            } else {
                   3967:                /*
                   3968:                 * We've now got a variable structure to store in. But first,
                   3969:                 * advance the string pointer.
                   3970:                 */
                   3971:                str += length;
1.15      christos 3972:
1.1       cgd      3973:                /*
                   3974:                 * Copy all the characters from the variable value straight
                   3975:                 * into the new string.
                   3976:                 */
1.96      christos 3977:                length = strlen(val);
1.146     dsl      3978:                Buf_AddBytes(&buf, length, val);
1.96      christos 3979:                trailingBslash = length > 0 && val[length - 1] == '\\';
1.104     christos 3980:            }
1.196     christos 3981:            free(freeIt);
                   3982:            freeIt = NULL;
1.1       cgd      3983:        }
                   3984:     }
1.15      christos 3985:
1.168     sjg      3986:     return Buf_DestroyCompact(&buf);
1.1       cgd      3987: }
                   3988:
1.250     rillig   3989: /* Initialize the module. */
1.1       cgd      3990: void
1.70      wiz      3991: Var_Init(void)
1.1       cgd      3992: {
1.184     sjg      3993:     VAR_INTERNAL = Targ_NewGN("Internal");
1.92      christos 3994:     VAR_GLOBAL = Targ_NewGN("Global");
                   3995:     VAR_CMD = Targ_NewGN("Command");
1.6       jtc      3996: }
                   3997:
1.1       cgd      3998:
1.6       jtc      3999: void
1.70      wiz      4000: Var_End(void)
1.6       jtc      4001: {
1.1       cgd      4002: }
1.15      christos 4003:
1.1       cgd      4004:
                   4005: /****************** PRINT DEBUGGING INFO *****************/
1.36      mycroft  4006: static void
1.241     rillig   4007: VarPrintVar(void *vp, void *data MAKE_ATTR_UNUSED)
1.1       cgd      4008: {
1.242     rillig   4009:     Var *v = (Var *)vp;
1.146     dsl      4010:     fprintf(debug_file, "%-16s = %s\n", v->name, Buf_GetAll(&v->val, NULL));
1.1       cgd      4011: }
                   4012:
                   4013: /*-
                   4014:  *-----------------------------------------------------------------------
                   4015:  * Var_Dump --
                   4016:  *     print all variables in a context
                   4017:  *-----------------------------------------------------------------------
                   4018:  */
1.5       cgd      4019: void
1.70      wiz      4020: Var_Dump(GNode *ctxt)
1.1       cgd      4021: {
1.241     rillig   4022:     Hash_ForEach(&ctxt->context, VarPrintVar, NULL);
1.1       cgd      4023: }

CVSweb <webmaster@jp.NetBSD.org>