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

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

CVSweb <webmaster@jp.NetBSD.org>