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

1.300   ! rillig      1: /*     $NetBSD: var.c,v 1.299 2020/07/24 07:24:21 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.300   ! rillig     72: static char rcsid[] = "$NetBSD: var.c,v 1.299 2020/07/24 07:24:21 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.300   ! rillig     79: __RCSID("$NetBSD: var.c,v 1.299 2020/07/24 07:24:21 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.295     rillig   1108: typedef void (*ModifyWordsCallback)(const char *word, SepBuf *buf, void *data);
1.244     rillig   1109:
                   1110:
1.291     rillig   1111: /* Callback for ModifyWords to implement the :H modifier.
1.244     rillig   1112:  * Add the dirname of the given word to the buffer. */
1.278     rillig   1113: static void
1.295     rillig   1114: ModifyWord_Head(const char *word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
1.1       cgd      1115: {
1.238     rillig   1116:     const char *slash = strrchr(word, '/');
                   1117:     if (slash != NULL)
1.278     rillig   1118:        SepBuf_AddBytes(buf, word, slash - word);
1.238     rillig   1119:     else
1.278     rillig   1120:        SepBuf_AddBytes(buf, ".", 1);
1.1       cgd      1121: }
                   1122:
1.291     rillig   1123: /* Callback for ModifyWords to implement the :T modifier.
1.244     rillig   1124:  * Add the basename of the given word to the buffer. */
1.278     rillig   1125: static void
1.295     rillig   1126: ModifyWord_Tail(const char *word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
1.1       cgd      1127: {
1.238     rillig   1128:     const char *slash = strrchr(word, '/');
                   1129:     const char *base = slash != NULL ? slash + 1 : word;
1.278     rillig   1130:     SepBuf_AddBytes(buf, base, strlen(base));
1.1       cgd      1131: }
                   1132:
1.291     rillig   1133: /* Callback for ModifyWords to implement the :E modifier.
1.244     rillig   1134:  * Add the filename suffix of the given word to the buffer, if it exists. */
1.278     rillig   1135: static void
1.295     rillig   1136: ModifyWord_Suffix(const char *word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
1.1       cgd      1137: {
1.239     rillig   1138:     const char *dot = strrchr(word, '.');
1.278     rillig   1139:     if (dot != NULL)
                   1140:        SepBuf_AddBytes(buf, dot + 1, strlen(dot + 1));
1.1       cgd      1141: }
                   1142:
1.291     rillig   1143: /* Callback for ModifyWords to implement the :R modifier.
                   1144:  * Add the basename of the given word to the buffer. */
1.278     rillig   1145: static void
1.295     rillig   1146: ModifyWord_Root(const char *word, SepBuf *buf, void *dummy MAKE_ATTR_UNUSED)
1.1       cgd      1147: {
1.239     rillig   1148:     char *dot = strrchr(word, '.');
1.247     lukem    1149:     size_t len = dot != NULL ? (size_t)(dot - word) : strlen(word);
1.278     rillig   1150:     SepBuf_AddBytes(buf, word, len);
1.1       cgd      1151: }
                   1152:
1.291     rillig   1153: /* Callback for ModifyWords to implement the :M modifier.
1.244     rillig   1154:  * Place the word in the buffer if it matches the given pattern. */
1.278     rillig   1155: static void
1.295     rillig   1156: ModifyWord_Match(const char *word, SepBuf *buf, void *data)
1.1       cgd      1157: {
1.244     rillig   1158:     const char *pattern = data;
1.137     christos 1159:     if (DEBUG(VAR))
1.244     rillig   1160:        fprintf(debug_file, "VarMatch [%s] [%s]\n", word, pattern);
1.278     rillig   1161:     if (Str_Match(word, pattern))
                   1162:        SepBuf_AddBytes(buf, word, strlen(word));
1.1       cgd      1163: }
                   1164:
1.291     rillig   1165: /* Callback for ModifyWords to implement the :N modifier.
                   1166:  * Place the word in the buffer if it doesn't match the given pattern. */
                   1167: static void
1.295     rillig   1168: ModifyWord_NoMatch(const char *word, SepBuf *buf, void *data)
1.291     rillig   1169: {
                   1170:     const char *pattern = data;
                   1171:     if (!Str_Match(word, pattern))
                   1172:        SepBuf_AddBytes(buf, word, strlen(word));
                   1173: }
                   1174:
1.13      christos 1175: #ifdef SYSVVARSUB
1.256     rillig   1176: /*-
                   1177:  *-----------------------------------------------------------------------
                   1178:  * Str_SYSVMatch --
                   1179:  *     Check word against pattern for a match (% is wild),
                   1180:  *
                   1181:  * Input:
                   1182:  *     word            Word to examine
                   1183:  *     pattern         Pattern to examine against
                   1184:  *     len             Number of characters to substitute
                   1185:  *
                   1186:  * Results:
                   1187:  *     Returns the beginning position of a match or null. The number
                   1188:  *     of characters matched is returned in len.
                   1189:  *-----------------------------------------------------------------------
                   1190:  */
1.277     rillig   1191: static const char *
1.256     rillig   1192: Str_SYSVMatch(const char *word, const char *pattern, size_t *len,
                   1193:     Boolean *hasPercent)
                   1194: {
                   1195:     const char *p = pattern;
                   1196:     const char *w = word;
                   1197:     const char *m;
                   1198:
                   1199:     *hasPercent = FALSE;
                   1200:     if (*p == '\0') {
                   1201:        /* Null pattern is the whole string */
                   1202:        *len = strlen(w);
1.277     rillig   1203:        return w;
1.256     rillig   1204:     }
                   1205:
                   1206:     if ((m = strchr(p, '%')) != NULL) {
                   1207:        *hasPercent = TRUE;
                   1208:        if (*w == '\0') {
                   1209:                /* empty word does not match pattern */
                   1210:                return NULL;
                   1211:        }
                   1212:        /* check that the prefix matches */
                   1213:        for (; p != m && *w && *w == *p; w++, p++)
                   1214:             continue;
                   1215:
                   1216:        if (p != m)
                   1217:            return NULL;        /* No match */
                   1218:
                   1219:        if (*++p == '\0') {
                   1220:            /* No more pattern, return the rest of the string */
                   1221:            *len = strlen(w);
1.277     rillig   1222:            return w;
1.256     rillig   1223:        }
                   1224:     }
                   1225:
                   1226:     m = w;
                   1227:
                   1228:     /* Find a matching tail */
1.277     rillig   1229:     do {
1.256     rillig   1230:        if (strcmp(p, w) == 0) {
                   1231:            *len = w - m;
1.277     rillig   1232:            return m;
1.256     rillig   1233:        }
1.277     rillig   1234:     } while (*w++ != '\0');
1.256     rillig   1235:
                   1236:     return NULL;
                   1237: }
                   1238:
                   1239:
                   1240: /*-
                   1241:  *-----------------------------------------------------------------------
                   1242:  * Str_SYSVSubst --
                   1243:  *     Substitute '%' on the pattern with len characters from src.
                   1244:  *     If the pattern does not contain a '%' prepend len characters
                   1245:  *     from src.
                   1246:  *
                   1247:  * Side Effects:
                   1248:  *     Places result on buf
                   1249:  *-----------------------------------------------------------------------
                   1250:  */
                   1251: static void
1.278     rillig   1252: Str_SYSVSubst(SepBuf *buf, const char *pat, const char *src, size_t len,
                   1253:              Boolean lhsHasPercent)
1.256     rillig   1254: {
                   1255:     const char *m;
                   1256:
                   1257:     if ((m = strchr(pat, '%')) != NULL && lhsHasPercent) {
                   1258:        /* Copy the prefix */
1.278     rillig   1259:        SepBuf_AddBytes(buf, pat, m - pat);
1.256     rillig   1260:        /* skip the % */
                   1261:        pat = m + 1;
                   1262:     }
                   1263:     if (m != NULL || !lhsHasPercent) {
                   1264:        /* Copy the pattern */
1.278     rillig   1265:        SepBuf_AddBytes(buf, src, len);
1.256     rillig   1266:     }
                   1267:
                   1268:     /* append the rest */
1.278     rillig   1269:     SepBuf_AddBytes(buf, pat, strlen(pat));
1.256     rillig   1270: }
                   1271:
                   1272:
1.276     rillig   1273: typedef struct {
1.295     rillig   1274:     GNode *ctx;
1.276     rillig   1275:     const char *lhs;
                   1276:     const char *rhs;
1.291     rillig   1277: } ModifyWord_SYSVSubstArgs;
1.276     rillig   1278:
1.291     rillig   1279: /* Callback for ModifyWords to implement the :%.from=%.to modifier. */
1.278     rillig   1280: static void
1.295     rillig   1281: ModifyWord_SYSVSubst(const char *word, SepBuf *buf, void *data)
1.5       cgd      1282: {
1.291     rillig   1283:     const ModifyWord_SYSVSubstArgs *args = data;
1.5       cgd      1284:
1.276     rillig   1285:     size_t len;
                   1286:     Boolean hasPercent;
                   1287:     const char *ptr = Str_SYSVMatch(word, args->lhs, &len, &hasPercent);
                   1288:     if (ptr != NULL) {
1.295     rillig   1289:        char *varexp = Var_Subst(NULL, args->rhs, args->ctx, VARE_WANTRES);
1.223     christos 1290:        Str_SYSVSubst(buf, varexp, ptr, len, hasPercent);
1.61      explorer 1291:        free(varexp);
                   1292:     } else {
1.278     rillig   1293:        SepBuf_AddBytes(buf, word, strlen(word));
1.61      explorer 1294:     }
1.5       cgd      1295: }
1.13      christos 1296: #endif
1.5       cgd      1297:
1.1       cgd      1298:
1.291     rillig   1299: typedef struct {
                   1300:     const char *lhs;
                   1301:     size_t     lhsLen;
                   1302:     const char *rhs;
                   1303:     size_t     rhsLen;
                   1304:     VarPatternFlags pflags;
                   1305: } ModifyWord_SubstArgs;
                   1306:
                   1307: /* Callback for ModifyWords to implement the :S,from,to, modifier.
1.244     rillig   1308:  * Perform a string substitution on the given word. */
1.278     rillig   1309: static void
1.295     rillig   1310: ModifyWord_Subst(const char *word, SepBuf *buf, void *data)
1.1       cgd      1311: {
1.279     rillig   1312:     size_t wordLen = strlen(word);
1.291     rillig   1313:     ModifyWord_SubstArgs *args = data;
1.281     rillig   1314:     const VarPatternFlags pflags = args->pflags;
1.1       cgd      1315:
1.279     rillig   1316:     if ((pflags & (VARP_SUB_ONE | VARP_SUB_MATCHED)) ==
                   1317:        (VARP_SUB_ONE | VARP_SUB_MATCHED))
                   1318:        goto nosub;
                   1319:
1.288     rillig   1320:     if (args->pflags & VARP_ANCHOR_START) {
1.282     rillig   1321:        if (wordLen < args->lhsLen ||
                   1322:            memcmp(word, args->lhs, args->lhsLen) != 0)
1.1       cgd      1323:            goto nosub;
1.279     rillig   1324:
1.288     rillig   1325:        if (args->pflags & VARP_ANCHOR_END) {
1.281     rillig   1326:            if (wordLen != args->lhsLen)
1.1       cgd      1327:                goto nosub;
1.279     rillig   1328:
1.281     rillig   1329:            SepBuf_AddBytes(buf, args->rhs, args->rhsLen);
                   1330:            args->pflags |= VARP_SUB_MATCHED;
1.1       cgd      1331:        } else {
1.281     rillig   1332:            SepBuf_AddBytes(buf, args->rhs, args->rhsLen);
                   1333:            SepBuf_AddBytes(buf, word + args->lhsLen, wordLen - args->lhsLen);
                   1334:            args->pflags |= VARP_SUB_MATCHED;
1.1       cgd      1335:        }
1.278     rillig   1336:        return;
1.1       cgd      1337:     }
1.279     rillig   1338:
1.288     rillig   1339:     if (args->pflags & VARP_ANCHOR_END) {
1.281     rillig   1340:        if (wordLen < args->lhsLen)
1.280     rillig   1341:            goto nosub;
1.281     rillig   1342:        const char *start = word + (wordLen - args->lhsLen);
                   1343:        if (memcmp(start, args->lhs, args->lhsLen) != 0)
1.279     rillig   1344:            goto nosub;
                   1345:
1.280     rillig   1346:        SepBuf_AddBytes(buf, word, start - word);
1.281     rillig   1347:        SepBuf_AddBytes(buf, args->rhs, args->rhsLen);
                   1348:        args->pflags |= VARP_SUB_MATCHED;
1.279     rillig   1349:        return;
                   1350:     }
                   1351:
                   1352:     /* unanchored */
                   1353:     const char *cp;
1.281     rillig   1354:     while ((cp = Str_FindSubstring(word, args->lhs)) != NULL) {
1.279     rillig   1355:        SepBuf_AddBytes(buf, word, cp - word);
1.281     rillig   1356:        SepBuf_AddBytes(buf, args->rhs, args->rhsLen);
                   1357:        wordLen -= (cp - word) + args->lhsLen;
                   1358:        word = cp + args->lhsLen;
                   1359:        if (wordLen == 0 || !(args->pflags & VARP_SUB_GLOBAL))
1.279     rillig   1360:            break;
1.281     rillig   1361:        args->pflags |= VARP_SUB_MATCHED;
1.279     rillig   1362:     }
1.242     rillig   1363: nosub:
1.278     rillig   1364:     SepBuf_AddBytes(buf, word, wordLen);
1.1       cgd      1365: }
                   1366:
1.31      gwr      1367: #ifndef NO_REGEX
1.16      christos 1368: /*-
                   1369:  *-----------------------------------------------------------------------
                   1370:  * VarREError --
                   1371:  *     Print the error caused by a regcomp or regexec call.
                   1372:  *
                   1373:  * Side Effects:
                   1374:  *     An error gets printed.
                   1375:  *
                   1376:  *-----------------------------------------------------------------------
                   1377:  */
                   1378: static void
1.202     christos 1379: VarREError(int reerr, regex_t *pat, const char *str)
1.16      christos 1380: {
                   1381:     char *errbuf;
1.127     christos 1382:     int errlen;
1.16      christos 1383:
1.202     christos 1384:     errlen = regerror(reerr, pat, 0, 0);
1.134     joerg    1385:     errbuf = bmake_malloc(errlen);
1.202     christos 1386:     regerror(reerr, pat, errbuf, errlen);
1.16      christos 1387:     Error("%s: %s", str, errbuf);
                   1388:     free(errbuf);
                   1389: }
                   1390:
1.291     rillig   1391: typedef struct {
                   1392:     regex_t       re;
                   1393:     int                   nsub;
                   1394:     regmatch_t           *matches;
                   1395:     char         *replace;
                   1396:     VarPatternFlags pflags;
                   1397: } ModifyWord_SubstRegexArgs;
                   1398:
                   1399: /* Callback for ModifyWords to implement the :C/from/to/ modifier.
1.244     rillig   1400:  * Perform a regex substitution on the given word. */
1.278     rillig   1401: static void
1.295     rillig   1402: ModifyWord_SubstRegex(const char *word, SepBuf *buf, void *data)
1.16      christos 1403: {
1.291     rillig   1404:     ModifyWord_SubstRegexArgs *pat = data;
1.16      christos 1405:     int xrv;
1.253     rillig   1406:     const char *wp = word;
1.16      christos 1407:     char *rp;
1.20      christos 1408:     int flags = 0;
1.16      christos 1409:
1.261     rillig   1410:     if ((pat->pflags & (VARP_SUB_ONE | VARP_SUB_MATCHED)) ==
                   1411:        (VARP_SUB_ONE | VARP_SUB_MATCHED))
1.16      christos 1412:        xrv = REG_NOMATCH;
                   1413:     else {
                   1414:     tryagain:
1.21      christos 1415:        xrv = regexec(&pat->re, wp, pat->nsub, pat->matches, flags);
1.16      christos 1416:     }
                   1417:
                   1418:     switch (xrv) {
                   1419:     case 0:
1.261     rillig   1420:        pat->pflags |= VARP_SUB_MATCHED;
1.278     rillig   1421:        SepBuf_AddBytes(buf, wp, pat->matches[0].rm_so);
1.16      christos 1422:
                   1423:        for (rp = pat->replace; *rp; rp++) {
1.278     rillig   1424:            if (*rp == '\\' && (rp[1] == '&' || rp[1] == '\\')) {
                   1425:                SepBuf_AddBytes(buf, rp + 1, 1);
1.16      christos 1426:                rp++;
1.278     rillig   1427:            } else if (*rp == '&' ||
                   1428:                (*rp == '\\' && isdigit((unsigned char)rp[1]))) {
1.16      christos 1429:                int n;
                   1430:                char errstr[3];
                   1431:
                   1432:                if (*rp == '&') {
                   1433:                    n = 0;
                   1434:                    errstr[0] = '&';
                   1435:                    errstr[1] = '\0';
                   1436:                } else {
                   1437:                    n = rp[1] - '0';
                   1438:                    errstr[0] = '\\';
                   1439:                    errstr[1] = rp[1];
                   1440:                    errstr[2] = '\0';
                   1441:                    rp++;
                   1442:                }
                   1443:
1.271     rillig   1444:                if (n >= pat->nsub) {
1.294     rillig   1445:                    Error("No subexpression %s", errstr);
1.16      christos 1446:                } else if ((pat->matches[n].rm_so == -1) &&
                   1447:                           (pat->matches[n].rm_eo == -1)) {
1.294     rillig   1448:                    Error("No match for subexpression %s", errstr);
1.242     rillig   1449:                } else {
1.294     rillig   1450:                    const char *subbuf = wp + pat->matches[n].rm_so;
                   1451:                    int sublen = pat->matches[n].rm_eo - pat->matches[n].rm_so;
                   1452:                    SepBuf_AddBytes(buf, subbuf, sublen);
1.16      christos 1453:                }
                   1454:
                   1455:            } else {
1.278     rillig   1456:                SepBuf_AddBytes(buf, rp, 1);
1.16      christos 1457:            }
                   1458:        }
1.127     christos 1459:        wp += pat->matches[0].rm_eo;
1.261     rillig   1460:        if (pat->pflags & VARP_SUB_GLOBAL) {
1.20      christos 1461:            flags |= REG_NOTBOL;
                   1462:            if (pat->matches[0].rm_so == 0 && pat->matches[0].rm_eo == 0) {
1.278     rillig   1463:                SepBuf_AddBytes(buf, wp, 1);
1.20      christos 1464:                wp++;
                   1465:            }
                   1466:            if (*wp)
                   1467:                goto tryagain;
                   1468:        }
1.16      christos 1469:        if (*wp) {
1.278     rillig   1470:            SepBuf_AddBytes(buf, wp, strlen(wp));
1.16      christos 1471:        }
                   1472:        break;
                   1473:     default:
                   1474:        VarREError(xrv, &pat->re, "Unexpected regex error");
1.242     rillig   1475:        /* fall through */
1.16      christos 1476:     case REG_NOMATCH:
1.278     rillig   1477:        SepBuf_AddBytes(buf, wp, strlen(wp));
1.16      christos 1478:        break;
                   1479:     }
                   1480: }
1.17      christos 1481: #endif
1.16      christos 1482:
                   1483:
1.291     rillig   1484: typedef struct {
1.295     rillig   1485:     GNode      *ctx;
1.291     rillig   1486:     char       *tvar;          /* name of temporary variable */
                   1487:     char       *str;           /* string to expand */
                   1488:     VarEvalFlags eflags;
                   1489: } ModifyWord_LoopArgs;
                   1490:
                   1491: /* Callback for ModifyWords to implement the :@var@...@ modifier of ODE make. */
1.278     rillig   1492: static void
1.295     rillig   1493: ModifyWord_Loop(const char *word, SepBuf *buf, void *data)
1.40      sjg      1494: {
1.278     rillig   1495:     if (word[0] == '\0')
                   1496:        return;
                   1497:
1.295     rillig   1498:     const ModifyWord_LoopArgs *args = data;
                   1499:     Var_Set_with_flags(args->tvar, word, args->ctx, VAR_NO_EXPORT);
                   1500:     char *s = Var_Subst(NULL, args->str, args->ctx, args->eflags);
1.278     rillig   1501:     if (DEBUG(VAR)) {
                   1502:        fprintf(debug_file,
1.291     rillig   1503:                "ModifyWord_Loop: in \"%s\", replace \"%s\" with \"%s\" "
1.278     rillig   1504:                "to \"%s\"\n",
1.295     rillig   1505:                word, args->tvar, args->str, s ? s : "(null)");
1.278     rillig   1506:     }
1.64      sjg      1507:
1.278     rillig   1508:     if (s != NULL && s[0] != '\0') {
                   1509:        if (s[0] == '\n' || (buf->buf.count > 0 &&
                   1510:            buf->buf.buffer[buf->buf.count - 1] == '\n'))
                   1511:            buf->needSep = FALSE;
                   1512:        SepBuf_AddBytes(buf, s, strlen(s));
1.40      sjg      1513:     }
1.278     rillig   1514:     free(s);
1.40      sjg      1515: }
                   1516:
1.81      sjg      1517:
                   1518: /*-
1.291     rillig   1519:  * Implements the :[first..last] modifier.
1.292     rillig   1520:  * This is a special case of ModifyWords since we want to be able
1.291     rillig   1521:  * to scan the list backwards if first > last.
1.81      sjg      1522:  */
                   1523: static char *
1.295     rillig   1524: VarSelectWords(Var_Parse_State *vpstate, const char *str, int first, int last)
1.81      sjg      1525: {
1.278     rillig   1526:     SepBuf buf;
1.240     rillig   1527:     char **av;                 /* word list */
                   1528:     char *as;                  /* word list memory */
1.127     christos 1529:     int ac, i;
1.81      sjg      1530:     int start, end, step;
1.142     dsl      1531:
1.278     rillig   1532:     SepBuf_Init(&buf, vpstate->varSpace);
1.81      sjg      1533:
                   1534:     if (vpstate->oneBigWord) {
                   1535:        /* fake what brk_string() would do if there were only one word */
                   1536:        ac = 1;
1.242     rillig   1537:        av = bmake_malloc((ac + 1) * sizeof(char *));
1.134     joerg    1538:        as = bmake_strdup(str);
1.81      sjg      1539:        av[0] = as;
                   1540:        av[1] = NULL;
                   1541:     } else {
                   1542:        av = brk_string(str, &ac, FALSE, &as);
                   1543:     }
                   1544:
                   1545:     /*
                   1546:      * Now sanitize seldata.
                   1547:      * If seldata->start or seldata->end are negative, convert them to
                   1548:      * the positive equivalents (-1 gets converted to argc, -2 gets
                   1549:      * converted to (argc-1), etc.).
                   1550:      */
1.290     rillig   1551:     if (first < 0)
                   1552:        first += ac + 1;
                   1553:     if (last < 0)
                   1554:        last += ac + 1;
1.81      sjg      1555:
                   1556:     /*
                   1557:      * We avoid scanning more of the list than we need to.
                   1558:      */
1.290     rillig   1559:     if (first > last) {
                   1560:        start = MIN(ac, first) - 1;
                   1561:        end = MAX(0, last - 1);
1.81      sjg      1562:        step = -1;
                   1563:     } else {
1.290     rillig   1564:        start = MAX(0, first - 1);
                   1565:        end = MIN(ac, last);
1.81      sjg      1566:        step = 1;
                   1567:     }
                   1568:
1.296     rillig   1569:     for (i = start; (step < 0) == (i >= end); i += step) {
1.278     rillig   1570:        if (av[i][0] != '\0') {
                   1571:            SepBuf_AddBytes(&buf, av[i], strlen(av[i]));
                   1572:            SepBuf_Sep(&buf);
1.81      sjg      1573:        }
                   1574:     }
                   1575:
                   1576:     free(as);
                   1577:     free(av);
                   1578:
1.278     rillig   1579:     return SepBuf_Destroy(&buf, FALSE);
1.81      sjg      1580: }
                   1581:
1.156     sjg      1582:
1.291     rillig   1583: /* Callback for ModifyWords to implement the :tA modifier.
1.244     rillig   1584:  * Replace each word with the result of realpath() if successful. */
1.278     rillig   1585: static void
1.295     rillig   1586: ModifyWord_Realpath(const char *word, SepBuf *buf, void *data MAKE_ATTR_UNUSED)
1.156     sjg      1587: {
1.242     rillig   1588:     struct stat st;
                   1589:     char rbuf[MAXPATHLEN];
1.231     rillig   1590:
1.278     rillig   1591:     char *rp = cached_realpath(word, rbuf);
1.257     rillig   1592:     if (rp != NULL && *rp == '/' && stat(rp, &st) == 0)
1.242     rillig   1593:        word = rp;
1.231     rillig   1594:
1.278     rillig   1595:     SepBuf_AddBytes(buf, word, strlen(word));
1.156     sjg      1596: }
                   1597:
1.1       cgd      1598: /*-
                   1599:  *-----------------------------------------------------------------------
1.244     rillig   1600:  * Modify each of the words of the passed string using the given function.
1.1       cgd      1601:  *
1.70      wiz      1602:  * Input:
1.278     rillig   1603:  *     str             String whose words should be modified
1.291     rillig   1604:  *     modifyWord      Function that modifies a single word
                   1605:  *     data            Custom data for modifyWord
1.70      wiz      1606:  *
1.1       cgd      1607:  * Results:
                   1608:  *     A string of all the words modified appropriately.
                   1609:  *-----------------------------------------------------------------------
                   1610:  */
                   1611: static char *
1.291     rillig   1612: ModifyWords(GNode *ctx, Var_Parse_State *vpstate,
                   1613:            const char *str, ModifyWordsCallback modifyWord, void *data)
1.1       cgd      1614: {
1.278     rillig   1615:     SepBuf result;
1.240     rillig   1616:     char **av;                 /* word list */
                   1617:     char *as;                  /* word list memory */
1.127     christos 1618:     int ac, i;
1.7       jtc      1619:
1.278     rillig   1620:     SepBuf_Init(&result, vpstate->varSpace);
1.1       cgd      1621:
1.81      sjg      1622:     if (vpstate->oneBigWord) {
                   1623:        /* fake what brk_string() would do if there were only one word */
                   1624:        ac = 1;
1.242     rillig   1625:        av = bmake_malloc((ac + 1) * sizeof(char *));
1.134     joerg    1626:        as = bmake_strdup(str);
1.81      sjg      1627:        av[0] = as;
                   1628:        av[1] = NULL;
                   1629:     } else {
                   1630:        av = brk_string(str, &ac, FALSE, &as);
                   1631:     }
1.1       cgd      1632:
1.255     rillig   1633:     if (DEBUG(VAR)) {
1.292     rillig   1634:        fprintf(debug_file, "ModifyWords: split \"%s\" into %d words\n",
1.255     rillig   1635:                str, ac);
                   1636:     }
                   1637:
1.278     rillig   1638:     for (i = 0; i < ac; i++) {
                   1639:        size_t orig_count = result.buf.count;
1.295     rillig   1640:        modifyWord(av[i], &result, data);
1.278     rillig   1641:        size_t count = result.buf.count;
                   1642:        if (count != orig_count)
                   1643:            SepBuf_Sep(&result);
                   1644:     }
1.24      christos 1645:
                   1646:     free(as);
                   1647:     free(av);
1.15      christos 1648:
1.278     rillig   1649:     vpstate->varSpace = result.sep;
                   1650:     return SepBuf_Destroy(&result, FALSE);
1.1       cgd      1651: }
                   1652:
1.35      christos 1653:
                   1654: static int
1.70      wiz      1655: VarWordCompare(const void *a, const void *b)
1.35      christos 1656: {
1.242     rillig   1657:     int r = strcmp(*(const char * const *)a, *(const char * const *)b);
                   1658:     return r;
1.35      christos 1659: }
                   1660:
1.224     sjg      1661: static int
                   1662: VarWordCompareReverse(const void *a, const void *b)
                   1663: {
1.242     rillig   1664:     int r = strcmp(*(const char * const *)b, *(const char * const *)a);
                   1665:     return r;
1.224     sjg      1666: }
                   1667:
1.35      christos 1668: /*-
                   1669:  *-----------------------------------------------------------------------
1.93      sjg      1670:  * VarOrder --
                   1671:  *     Order the words in the string.
1.35      christos 1672:  *
1.70      wiz      1673:  * Input:
1.93      sjg      1674:  *     str             String whose words should be sorted.
                   1675:  *     otype           How to order: s - sort, x - random.
1.70      wiz      1676:  *
1.35      christos 1677:  * Results:
1.93      sjg      1678:  *     A string containing the words ordered.
1.35      christos 1679:  *
                   1680:  * Side Effects:
                   1681:  *     None.
                   1682:  *
                   1683:  *-----------------------------------------------------------------------
                   1684:  */
                   1685: static char *
1.93      sjg      1686: VarOrder(const char *str, const char otype)
1.35      christos 1687: {
1.240     rillig   1688:     Buffer buf;                        /* Buffer for the new string */
                   1689:     char **av;                 /* word list [first word does not count] */
                   1690:     char *as;                  /* word list memory */
1.127     christos 1691:     int ac, i;
1.35      christos 1692:
1.146     dsl      1693:     Buf_Init(&buf, 0);
1.35      christos 1694:
                   1695:     av = brk_string(str, &ac, FALSE, &as);
                   1696:
1.240     rillig   1697:     if (ac > 0) {
1.93      sjg      1698:        switch (otype) {
1.240     rillig   1699:        case 'r':               /* reverse sort alphabetically */
1.224     sjg      1700:            qsort(av, ac, sizeof(char *), VarWordCompareReverse);
                   1701:            break;
1.240     rillig   1702:        case 's':               /* sort alphabetically */
1.93      sjg      1703:            qsort(av, ac, sizeof(char *), VarWordCompare);
                   1704:            break;
1.240     rillig   1705:        case 'x':               /* randomize */
                   1706:            {
                   1707:                /*
                   1708:                 * We will use [ac..2] range for mod factors. This will produce
                   1709:                 * random numbers in [(ac-1)..0] interval, and minimal
                   1710:                 * reasonable value for mod factor is 2 (the mod 1 will produce
                   1711:                 * 0 with probability 1).
                   1712:                 */
                   1713:                for (i = ac - 1; i > 0; i--) {
                   1714:                    int rndidx = random() % (i + 1);
                   1715:                    char *t = av[i];
1.93      sjg      1716:                    av[i] = av[rndidx];
                   1717:                    av[rndidx] = t;
                   1718:                }
                   1719:            }
                   1720:        }
1.240     rillig   1721:     }
1.35      christos 1722:
                   1723:     for (i = 0; i < ac; i++) {
1.146     dsl      1724:        Buf_AddBytes(&buf, strlen(av[i]), av[i]);
1.35      christos 1725:        if (i != ac - 1)
1.146     dsl      1726:            Buf_AddByte(&buf, ' ');
1.35      christos 1727:     }
                   1728:
                   1729:     free(as);
                   1730:     free(av);
                   1731:
1.146     dsl      1732:     return Buf_Destroy(&buf, FALSE);
1.35      christos 1733: }
                   1734:
                   1735:
1.1       cgd      1736: /*-
                   1737:  *-----------------------------------------------------------------------
1.55      christos 1738:  * VarUniq --
                   1739:  *     Remove adjacent duplicate words.
                   1740:  *
1.70      wiz      1741:  * Input:
                   1742:  *     str             String whose words should be sorted
                   1743:  *
1.55      christos 1744:  * Results:
                   1745:  *     A string containing the resulting words.
                   1746:  *
                   1747:  * Side Effects:
                   1748:  *     None.
                   1749:  *
                   1750:  *-----------------------------------------------------------------------
                   1751:  */
                   1752: static char *
1.73      christos 1753: VarUniq(const char *str)
1.55      christos 1754: {
1.240     rillig   1755:     Buffer       buf;          /* Buffer for new string */
                   1756:     char       **av;           /* List of words to affect */
                   1757:     char        *as;           /* Word list memory */
1.127     christos 1758:     int          ac, i, j;
1.55      christos 1759:
1.146     dsl      1760:     Buf_Init(&buf, 0);
1.55      christos 1761:     av = brk_string(str, &ac, FALSE, &as);
                   1762:
                   1763:     if (ac > 1) {
                   1764:        for (j = 0, i = 1; i < ac; i++)
                   1765:            if (strcmp(av[i], av[j]) != 0 && (++j != i))
                   1766:                av[j] = av[i];
                   1767:        ac = j + 1;
                   1768:     }
                   1769:
                   1770:     for (i = 0; i < ac; i++) {
1.146     dsl      1771:        Buf_AddBytes(&buf, strlen(av[i]), av[i]);
1.55      christos 1772:        if (i != ac - 1)
1.146     dsl      1773:            Buf_AddByte(&buf, ' ');
1.55      christos 1774:     }
                   1775:
                   1776:     free(as);
                   1777:     free(av);
                   1778:
1.146     dsl      1779:     return Buf_Destroy(&buf, FALSE);
1.55      christos 1780: }
                   1781:
1.210     sjg      1782: /*-
                   1783:  *-----------------------------------------------------------------------
                   1784:  * VarRange --
                   1785:  *     Return an integer sequence
                   1786:  *
                   1787:  * Input:
                   1788:  *     str             String whose words provide default range
                   1789:  *     ac              range length, if 0 use str words
                   1790:  *
                   1791:  * Side Effects:
                   1792:  *     None.
                   1793:  *
                   1794:  *-----------------------------------------------------------------------
                   1795:  */
                   1796: static char *
                   1797: VarRange(const char *str, int ac)
                   1798: {
1.240     rillig   1799:     Buffer       buf;          /* Buffer for new string */
                   1800:     char         tmp[32];      /* each element */
                   1801:     char       **av;           /* List of words to affect */
                   1802:     char        *as;           /* Word list memory */
1.210     sjg      1803:     int          i, n;
                   1804:
                   1805:     Buf_Init(&buf, 0);
                   1806:     if (ac > 0) {
                   1807:        as = NULL;
                   1808:        av = NULL;
                   1809:     } else {
                   1810:        av = brk_string(str, &ac, FALSE, &as);
                   1811:     }
                   1812:     for (i = 0; i < ac; i++) {
                   1813:        n = snprintf(tmp, sizeof(tmp), "%d", 1 + i);
                   1814:        if (n >= (int)sizeof(tmp))
                   1815:            break;
                   1816:        Buf_AddBytes(&buf, n, tmp);
                   1817:        if (i != ac - 1)
                   1818:            Buf_AddByte(&buf, ' ');
                   1819:     }
                   1820:
                   1821:     free(as);
                   1822:     free(av);
                   1823:
                   1824:     return Buf_Destroy(&buf, FALSE);
                   1825: }
                   1826:
1.55      christos 1827:
                   1828: /*-
1.265     rillig   1829:  * Parse a text part of a modifier such as the "from" and "to" in :S/from/to/
                   1830:  * or the :@ modifier. Nested variables in the text are expanded unless
1.287     rillig   1831:  * VARE_NOSUBST is set.
1.265     rillig   1832:  *
                   1833:  * The text part is parsed until the next delimiter.  To escape the delimiter,
                   1834:  * a backslash or a dollar, put a backslash before it.
                   1835:  *
                   1836:  * Return the expanded string or NULL if the delimiter was missing.
                   1837:  * If pattern is specified, handle escaped ampersands and replace unescaped
                   1838:  * ampersands with the lhs of the pattern (for the :S and :C modifiers).
                   1839:  *
                   1840:  * If length is specified, return the string length of the buffer.
                   1841:  * If mpflags is specified and the last character of the pattern is a $,
1.288     rillig   1842:  * set the VARP_ANCHOR_END bit of mpflags.
1.16      christos 1843:  */
                   1844: static char *
1.266     rillig   1845: ParseModifierPart(GNode *ctxt, const char **tstr, int delim,
                   1846:                  VarEvalFlags eflags, VarPatternFlags *mpflags,
1.291     rillig   1847:                  size_t *length, ModifyWord_SubstArgs *subst)
1.16      christos 1848: {
1.73      christos 1849:     const char *cp;
1.146     dsl      1850:     char *rstr;
                   1851:     Buffer buf;
1.281     rillig   1852:     size_t junk;
1.261     rillig   1853:     VarEvalFlags errnum = eflags & VARE_UNDEFERR;
1.146     dsl      1854:
                   1855:     Buf_Init(&buf, 0);
1.16      christos 1856:     if (length == NULL)
                   1857:        length = &junk;
                   1858:
                   1859:     /*
                   1860:      * Skim through until the matching delimiter is found;
                   1861:      * pick up variable substitutions on the way. Also allow
                   1862:      * backslashes to quote the delimiter, $, and \, but don't
                   1863:      * touch other backslashes.
                   1864:      */
1.278     rillig   1865:     for (cp = *tstr; *cp != '\0' && *cp != delim; cp++) {
1.263     rillig   1866:        Boolean is_escaped = cp[0] == '\\' && (cp[1] == delim ||
1.281     rillig   1867:            cp[1] == '\\' || cp[1] == '$' || (subst != NULL && cp[1] == '&'));
1.263     rillig   1868:        if (is_escaped) {
1.146     dsl      1869:            Buf_AddByte(&buf, cp[1]);
1.16      christos 1870:            cp++;
                   1871:        } else if (*cp == '$') {
1.288     rillig   1872:            if (cp[1] == delim) {       /* Unescaped $ at end of pattern */
1.261     rillig   1873:                if (mpflags == NULL)
1.146     dsl      1874:                    Buf_AddByte(&buf, *cp);
1.16      christos 1875:                else
1.288     rillig   1876:                    *mpflags |= VARP_ANCHOR_END;
1.40      sjg      1877:            } else {
1.287     rillig   1878:                if (!(eflags & VARE_NOSUBST)) {
1.40      sjg      1879:                    char   *cp2;
1.127     christos 1880:                    int     len;
1.104     christos 1881:                    void   *freeIt;
1.40      sjg      1882:
                   1883:                    /*
                   1884:                     * If unescaped dollar sign not before the
                   1885:                     * delimiter, assume it's a variable
                   1886:                     * substitution and recurse.
                   1887:                     */
1.261     rillig   1888:                    cp2 = Var_Parse(cp, ctxt, errnum | (eflags & VARE_WANTRES),
1.249     rillig   1889:                                    &len, &freeIt);
1.146     dsl      1890:                    Buf_AddBytes(&buf, strlen(cp2), cp2);
1.196     christos 1891:                    free(freeIt);
1.40      sjg      1892:                    cp += len - 1;
                   1893:                } else {
1.73      christos 1894:                    const char *cp2 = &cp[1];
1.16      christos 1895:
1.100     christos 1896:                    if (*cp2 == PROPEN || *cp2 == BROPEN) {
1.40      sjg      1897:                        /*
                   1898:                         * Find the end of this variable reference
                   1899:                         * and suck it in without further ado.
1.232     rillig   1900:                         * It will be interpreted later.
1.40      sjg      1901:                         */
                   1902:                        int have = *cp2;
1.100     christos 1903:                        int want = (*cp2 == PROPEN) ? PRCLOSE : BRCLOSE;
1.40      sjg      1904:                        int depth = 1;
                   1905:
                   1906:                        for (++cp2; *cp2 != '\0' && depth > 0; ++cp2) {
                   1907:                            if (cp2[-1] != '\\') {
                   1908:                                if (*cp2 == have)
                   1909:                                    ++depth;
                   1910:                                if (*cp2 == want)
                   1911:                                    --depth;
                   1912:                            }
                   1913:                        }
1.146     dsl      1914:                        Buf_AddBytes(&buf, cp2 - cp, cp);
1.40      sjg      1915:                        cp = --cp2;
                   1916:                    } else
1.146     dsl      1917:                        Buf_AddByte(&buf, *cp);
1.40      sjg      1918:                }
1.16      christos 1919:            }
1.281     rillig   1920:        } else if (subst != NULL && *cp == '&')
                   1921:            Buf_AddBytes(&buf, subst->lhsLen, subst->lhs);
1.16      christos 1922:        else
1.146     dsl      1923:            Buf_AddByte(&buf, *cp);
1.16      christos 1924:     }
                   1925:
                   1926:     if (*cp != delim) {
                   1927:        *tstr = cp;
                   1928:        *length = 0;
                   1929:        return NULL;
                   1930:     }
1.146     dsl      1931:
                   1932:     *tstr = ++cp;
                   1933:     *length = Buf_Size(&buf);
                   1934:     rstr = Buf_Destroy(&buf, FALSE);
                   1935:     if (DEBUG(VAR))
1.278     rillig   1936:        fprintf(debug_file, "Modifier part: \"%s\"\n", rstr);
1.146     dsl      1937:     return rstr;
1.16      christos 1938: }
                   1939:
                   1940: /*-
                   1941:  *-----------------------------------------------------------------------
                   1942:  * VarQuote --
1.194     mlelstv  1943:  *     Quote shell meta-characters and space characters in the string
1.220     christos 1944:  *     if quoteDollar is set, also quote and double any '$' characters.
1.16      christos 1945:  *
                   1946:  * Results:
                   1947:  *     The quoted string
                   1948:  *
                   1949:  * Side Effects:
                   1950:  *     None.
                   1951:  *
                   1952:  *-----------------------------------------------------------------------
                   1953:  */
                   1954: static char *
1.220     christos 1955: VarQuote(char *str, Boolean quoteDollar)
1.16      christos 1956: {
1.293     rillig   1957:     Buffer buf;
1.146     dsl      1958:     Buf_Init(&buf, 0);
1.193     christos 1959:
                   1960:     for (; *str != '\0'; str++) {
                   1961:        if (*str == '\n') {
1.293     rillig   1962:            const char *newline = Shell_GetNewline();
                   1963:            if (newline == NULL)
                   1964:                newline = "\\\n";
                   1965:            Buf_AddBytes(&buf, strlen(newline), newline);
1.193     christos 1966:            continue;
                   1967:        }
1.195     christos 1968:        if (isspace((unsigned char)*str) || ismeta((unsigned char)*str))
1.146     dsl      1969:            Buf_AddByte(&buf, '\\');
1.193     christos 1970:        Buf_AddByte(&buf, *str);
1.220     christos 1971:        if (quoteDollar && *str == '$')
1.219     christos 1972:            Buf_AddBytes(&buf, 2, "\\$");
1.16      christos 1973:     }
1.193     christos 1974:
1.146     dsl      1975:     str = Buf_Destroy(&buf, FALSE);
1.137     christos 1976:     if (DEBUG(VAR))
                   1977:        fprintf(debug_file, "QuoteMeta: [%s]\n", str);
1.16      christos 1978:     return str;
                   1979: }
                   1980:
1.68      pk       1981: /*-
                   1982:  *-----------------------------------------------------------------------
1.163     joerg    1983:  * VarHash --
                   1984:  *      Hash the string using the MurmurHash3 algorithm.
                   1985:  *      Output is computed using 32bit Little Endian arithmetic.
                   1986:  *
                   1987:  * Input:
                   1988:  *     str             String to modify
                   1989:  *
                   1990:  * Results:
                   1991:  *      Hash value of str, encoded as 8 hex digits.
                   1992:  *
                   1993:  * Side Effects:
                   1994:  *      None.
                   1995:  *
                   1996:  *-----------------------------------------------------------------------
                   1997:  */
                   1998: static char *
1.252     rillig   1999: VarHash(const char *str)
1.163     joerg    2000: {
                   2001:     static const char    hexdigits[16] = "0123456789abcdef";
                   2002:     Buffer         buf;
                   2003:     size_t         len, len2;
1.252     rillig   2004:     const unsigned char *ustr = (const unsigned char *)str;
1.163     joerg    2005:     uint32_t       h, k, c1, c2;
                   2006:
                   2007:     h  = 0x971e137bU;
                   2008:     c1 = 0x95543787U;
                   2009:     c2 = 0x2ad7eb25U;
                   2010:     len2 = strlen(str);
                   2011:
                   2012:     for (len = len2; len; ) {
                   2013:        k = 0;
                   2014:        switch (len) {
                   2015:        default:
1.252     rillig   2016:            k = ((uint32_t)ustr[3] << 24) |
                   2017:                ((uint32_t)ustr[2] << 16) |
                   2018:                ((uint32_t)ustr[1] << 8) |
                   2019:                (uint32_t)ustr[0];
1.163     joerg    2020:            len -= 4;
                   2021:            ustr += 4;
                   2022:            break;
                   2023:        case 3:
1.252     rillig   2024:            k |= (uint32_t)ustr[2] << 16;
1.222     mrg      2025:            /* FALLTHROUGH */
1.163     joerg    2026:        case 2:
1.252     rillig   2027:            k |= (uint32_t)ustr[1] << 8;
1.222     mrg      2028:            /* FALLTHROUGH */
1.163     joerg    2029:        case 1:
1.252     rillig   2030:            k |= (uint32_t)ustr[0];
1.163     joerg    2031:            len = 0;
                   2032:        }
                   2033:        c1 = c1 * 5 + 0x7b7d159cU;
                   2034:        c2 = c2 * 5 + 0x6bce6396U;
                   2035:        k *= c1;
                   2036:        k = (k << 11) ^ (k >> 21);
                   2037:        k *= c2;
                   2038:        h = (h << 13) ^ (h >> 19);
                   2039:        h = h * 5 + 0x52dce729U;
                   2040:        h ^= k;
1.242     rillig   2041:     }
                   2042:     h ^= len2;
                   2043:     h *= 0x85ebca6b;
                   2044:     h ^= h >> 13;
                   2045:     h *= 0xc2b2ae35;
                   2046:     h ^= h >> 16;
                   2047:
                   2048:     Buf_Init(&buf, 0);
                   2049:     for (len = 0; len < 8; ++len) {
                   2050:        Buf_AddByte(&buf, hexdigits[h & 15]);
                   2051:        h >>= 4;
1.249     rillig   2052:     }
1.163     joerg    2053:
1.249     rillig   2054:     return Buf_Destroy(&buf, FALSE);
1.163     joerg    2055: }
                   2056:
1.164     sjg      2057: static char *
1.209     sjg      2058: VarStrftime(const char *fmt, int zulu, time_t utc)
1.164     sjg      2059: {
                   2060:     char buf[BUFSIZ];
                   2061:
1.209     sjg      2062:     if (!utc)
                   2063:        time(&utc);
1.164     sjg      2064:     if (!*fmt)
                   2065:        fmt = "%c";
                   2066:     strftime(buf, sizeof(buf), fmt, zulu ? gmtime(&utc) : localtime(&utc));
1.235     rillig   2067:
1.164     sjg      2068:     buf[sizeof(buf) - 1] = '\0';
                   2069:     return bmake_strdup(buf);
                   2070: }
                   2071:
1.236     rillig   2072: typedef struct {
                   2073:     /* const parameters */
1.267     rillig   2074:     int startc;                        /* '\0' or '{' or '(' */
1.236     rillig   2075:     int endc;
1.242     rillig   2076:     Var *v;
1.236     rillig   2077:     GNode *ctxt;
1.268     rillig   2078:     VarEvalFlags eflags;
1.242     rillig   2079:     int *lengthPtr;
                   2080:     void **freePtr;
1.236     rillig   2081:
                   2082:     /* read-write */
                   2083:     char *nstr;
                   2084:     const char *start;
1.300   ! rillig   2085:     const char *cp;            /* The position where parsing continues
        !          2086:                                 * after the current modifier. */
1.236     rillig   2087:     char termc;                        /* Character which terminated scan */
1.298     rillig   2088:     char missing_delim;                /* For error reporting */
1.236     rillig   2089:     int modifier;              /* that we are processing */
1.242     rillig   2090:     Var_Parse_State parsestate;        /* Flags passed to helper functions */
1.236     rillig   2091:
                   2092:     /* result */
                   2093:     char *newStr;              /* New value to return */
                   2094: } ApplyModifiersState;
                   2095:
                   2096: /* we now have some modifiers with long names */
                   2097: #define STRMOD_MATCH(s, want, n) \
                   2098:     (strncmp(s, want, n) == 0 && (s[n] == st->endc || s[n] == ':'))
                   2099: #define STRMOD_MATCHX(s, want, n) \
1.246     rillig   2100:     (strncmp(s, want, n) == 0 && \
                   2101:      (s[n] == st->endc || s[n] == ':' || s[n] == '='))
1.236     rillig   2102: #define CHARMOD_MATCH(c) (c == st->endc || c == ':')
                   2103:
                   2104: /* :@var@...${var}...@ */
                   2105: static Boolean
1.299     rillig   2106: ApplyModifier_Loop(const char *mod, ApplyModifiersState *st) {
1.291     rillig   2107:     ModifyWord_LoopArgs args;
1.236     rillig   2108:
1.295     rillig   2109:     args.ctx = st->ctxt;
1.299     rillig   2110:     st->cp = mod + 1;
1.298     rillig   2111:     char delim = '@';
                   2112:     args.tvar = ParseModifierPart(st->ctxt, &st->cp, delim,
1.288     rillig   2113:                                  st->eflags | VARE_NOSUBST,
                   2114:                                  NULL, NULL, NULL);
1.298     rillig   2115:     if (args.tvar == NULL) {
                   2116:        st->missing_delim = delim;
1.236     rillig   2117:        return FALSE;
1.298     rillig   2118:     }
1.236     rillig   2119:
1.298     rillig   2120:     args.str = ParseModifierPart(st->ctxt, &st->cp, delim,
1.288     rillig   2121:                                 st->eflags | VARE_NOSUBST,
                   2122:                                 NULL, NULL, NULL);
1.298     rillig   2123:     if (args.str == NULL) {
                   2124:        st->missing_delim = delim;
1.236     rillig   2125:        return FALSE;
1.298     rillig   2126:     }
1.236     rillig   2127:
                   2128:     st->termc = *st->cp;
                   2129:
1.291     rillig   2130:     args.eflags = st->eflags & (VARE_UNDEFERR | VARE_WANTRES);
1.278     rillig   2131:     int prev_sep = st->parsestate.varSpace;
                   2132:     st->parsestate.varSpace = ' ';
1.291     rillig   2133:     st->newStr = ModifyWords(st->ctxt, &st->parsestate, st->nstr,
                   2134:                             ModifyWord_Loop, &args);
1.278     rillig   2135:     st->parsestate.varSpace = prev_sep;
1.291     rillig   2136:     Var_Delete(args.tvar, st->ctxt);
                   2137:     free(args.tvar);
                   2138:     free(args.str);
1.236     rillig   2139:     return TRUE;
                   2140: }
                   2141:
                   2142: /* :Ddefined or :Uundefined */
                   2143: static void
1.299     rillig   2144: ApplyModifier_Defined(const char *mod, ApplyModifiersState *st)
1.236     rillig   2145: {
1.242     rillig   2146:     Buffer buf;                        /* Buffer for patterns */
1.268     rillig   2147:     VarEvalFlags neflags;
1.236     rillig   2148:
1.268     rillig   2149:     if (st->eflags & VARE_WANTRES) {
                   2150:        Boolean wantres;
1.299     rillig   2151:        if (*mod == 'U')
1.236     rillig   2152:            wantres = ((st->v->flags & VAR_JUNK) != 0);
                   2153:        else
                   2154:            wantres = ((st->v->flags & VAR_JUNK) == 0);
1.268     rillig   2155:        neflags = st->eflags & ~VARE_WANTRES;
1.236     rillig   2156:        if (wantres)
1.268     rillig   2157:            neflags |= VARE_WANTRES;
1.236     rillig   2158:     } else
1.268     rillig   2159:        neflags = st->eflags;
1.236     rillig   2160:
                   2161:     /*
                   2162:      * Pass through tstr looking for 1) escaped delimiters,
                   2163:      * '$'s and backslashes (place the escaped character in
                   2164:      * uninterpreted) and 2) unescaped $'s that aren't before
                   2165:      * the delimiter (expand the variable substitution).
                   2166:      * The result is left in the Buffer buf.
                   2167:      */
                   2168:     Buf_Init(&buf, 0);
1.299     rillig   2169:     for (st->cp = mod + 1;
1.236     rillig   2170:         *st->cp != st->endc && *st->cp != ':' && *st->cp != '\0';
                   2171:         st->cp++) {
                   2172:        if (*st->cp == '\\' &&
                   2173:            (st->cp[1] == ':' || st->cp[1] == '$' || st->cp[1] == st->endc ||
                   2174:             st->cp[1] == '\\')) {
                   2175:            Buf_AddByte(&buf, st->cp[1]);
                   2176:            st->cp++;
                   2177:        } else if (*st->cp == '$') {
                   2178:            /*
                   2179:             * If unescaped dollar sign, assume it's a
                   2180:             * variable substitution and recurse.
                   2181:             */
                   2182:            char    *cp2;
                   2183:            int     len;
                   2184:            void    *freeIt;
                   2185:
1.268     rillig   2186:            cp2 = Var_Parse(st->cp, st->ctxt, neflags, &len, &freeIt);
1.236     rillig   2187:            Buf_AddBytes(&buf, strlen(cp2), cp2);
                   2188:            free(freeIt);
                   2189:            st->cp += len - 1;
                   2190:        } else {
                   2191:            Buf_AddByte(&buf, *st->cp);
                   2192:        }
                   2193:     }
                   2194:
                   2195:     st->termc = *st->cp;
                   2196:
1.257     rillig   2197:     if (st->v->flags & VAR_JUNK)
1.236     rillig   2198:        st->v->flags |= VAR_KEEP;
1.268     rillig   2199:     if (neflags & VARE_WANTRES) {
1.236     rillig   2200:        st->newStr = Buf_Destroy(&buf, FALSE);
                   2201:     } else {
                   2202:        st->newStr = st->nstr;
                   2203:        Buf_Destroy(&buf, TRUE);
                   2204:     }
                   2205: }
                   2206:
                   2207: /* :gmtime */
                   2208: static Boolean
1.299     rillig   2209: ApplyModifier_Gmtime(const char *mod, ApplyModifiersState *st)
1.236     rillig   2210: {
                   2211:     time_t utc;
                   2212:     char *ep;
                   2213:
1.299     rillig   2214:     st->cp = mod + 1;          /* make sure it is set */
                   2215:     if (!STRMOD_MATCHX(mod, "gmtime", 6))
1.236     rillig   2216:        return FALSE;
1.299     rillig   2217:     if (mod[6] == '=') {
                   2218:        utc = strtoul(mod + 7, &ep, 10);
1.236     rillig   2219:        st->cp = ep;
                   2220:     } else {
                   2221:        utc = 0;
1.299     rillig   2222:        st->cp = mod + 6;
1.236     rillig   2223:     }
                   2224:     st->newStr = VarStrftime(st->nstr, 1, utc);
                   2225:     st->termc = *st->cp;
                   2226:     return TRUE;
                   2227: }
                   2228:
                   2229: /* :localtime */
                   2230: static Boolean
1.299     rillig   2231: ApplyModifier_Localtime(const char *mod, ApplyModifiersState *st)
1.236     rillig   2232: {
                   2233:     time_t utc;
                   2234:     char *ep;
                   2235:
1.299     rillig   2236:     st->cp = mod + 1;  /* make sure it is set */
                   2237:     if (!STRMOD_MATCHX(mod, "localtime", 9))
1.236     rillig   2238:        return FALSE;
                   2239:
1.299     rillig   2240:     if (mod[9] == '=') {
                   2241:        utc = strtoul(mod + 10, &ep, 10);
1.236     rillig   2242:        st->cp = ep;
                   2243:     } else {
                   2244:        utc = 0;
1.299     rillig   2245:        st->cp = mod + 9;
1.236     rillig   2246:     }
                   2247:     st->newStr = VarStrftime(st->nstr, 0, utc);
                   2248:     st->termc = *st->cp;
                   2249:     return TRUE;
                   2250: }
                   2251:
                   2252: /* :hash */
                   2253: static Boolean
1.299     rillig   2254: ApplyModifier_Hash(const char *mod, ApplyModifiersState *st)
1.236     rillig   2255: {
1.299     rillig   2256:     st->cp = mod + 1;  /* make sure it is set */
                   2257:     if (!STRMOD_MATCH(mod, "hash", 4))
1.236     rillig   2258:        return FALSE;
                   2259:     st->newStr = VarHash(st->nstr);
1.299     rillig   2260:     st->cp = mod + 4;
1.236     rillig   2261:     st->termc = *st->cp;
                   2262:     return TRUE;
                   2263: }
                   2264:
                   2265: /* :P */
                   2266: static void
1.299     rillig   2267: ApplyModifier_Path(const char *mod, ApplyModifiersState *st)
1.236     rillig   2268: {
                   2269:     if ((st->v->flags & VAR_JUNK) != 0)
                   2270:        st->v->flags |= VAR_KEEP;
1.299     rillig   2271:     GNode *gn = Targ_FindNode(st->v->name, TARG_NOCREATE);
1.236     rillig   2272:     if (gn == NULL || gn->type & OP_NOPATH) {
                   2273:        st->newStr = NULL;
                   2274:     } else if (gn->path) {
                   2275:        st->newStr = bmake_strdup(gn->path);
                   2276:     } else {
                   2277:        st->newStr = Dir_FindFile(st->v->name, Suff_FindPath(gn));
                   2278:     }
                   2279:     if (!st->newStr)
                   2280:        st->newStr = bmake_strdup(st->v->name);
1.299     rillig   2281:     st->cp = mod + 1;
                   2282:     st->termc = *st->cp;
1.236     rillig   2283: }
                   2284:
                   2285: /* :!cmd! */
                   2286: static Boolean
1.299     rillig   2287: ApplyModifier_Exclam(const char *mod, ApplyModifiersState *st)
1.236     rillig   2288: {
1.299     rillig   2289:     st->cp = mod + 1;
1.298     rillig   2290:     char delim = '!';
                   2291:     char *cmd = ParseModifierPart(st->ctxt, &st->cp, delim, st->eflags,
1.274     rillig   2292:                                  NULL, NULL, NULL);
1.298     rillig   2293:     if (cmd == NULL) {
                   2294:        st->missing_delim = delim;
1.236     rillig   2295:        return FALSE;
1.298     rillig   2296:     }
1.274     rillig   2297:
                   2298:     const char *emsg = NULL;
1.268     rillig   2299:     if (st->eflags & VARE_WANTRES)
1.274     rillig   2300:        st->newStr = Cmd_Exec(cmd, &emsg);
1.236     rillig   2301:     else
                   2302:        st->newStr = varNoError;
1.274     rillig   2303:     free(cmd);
                   2304:
1.236     rillig   2305:     if (emsg)
                   2306:        Error(emsg, st->nstr);
1.274     rillig   2307:
1.236     rillig   2308:     st->termc = *st->cp;
                   2309:     if (st->v->flags & VAR_JUNK)
                   2310:        st->v->flags |= VAR_KEEP;
                   2311:     return TRUE;
                   2312: }
                   2313:
                   2314: /* :range */
                   2315: static Boolean
1.299     rillig   2316: ApplyModifier_Range(const char *mod, ApplyModifiersState *st)
1.236     rillig   2317: {
                   2318:     int n;
                   2319:     char *ep;
                   2320:
1.299     rillig   2321:     st->cp = mod + 1;  /* make sure it is set */
                   2322:     if (!STRMOD_MATCHX(mod, "range", 5))
1.236     rillig   2323:        return FALSE;
                   2324:
1.299     rillig   2325:     if (mod[5] == '=') {
                   2326:        n = strtoul(mod + 6, &ep, 10);
1.236     rillig   2327:        st->cp = ep;
                   2328:     } else {
                   2329:        n = 0;
1.299     rillig   2330:        st->cp = mod + 5;
1.236     rillig   2331:     }
                   2332:     st->newStr = VarRange(st->nstr, n);
                   2333:     st->termc = *st->cp;
                   2334:     return TRUE;
                   2335: }
                   2336:
                   2337: /* :Mpattern or :Npattern */
                   2338: static void
1.299     rillig   2339: ApplyModifier_Match(const char *mod, ApplyModifiersState *st)
1.236     rillig   2340: {
1.288     rillig   2341:     Boolean copy = FALSE;      /* pattern should be, or has been, copied */
                   2342:     Boolean needSubst = FALSE;
1.236     rillig   2343:     /*
1.288     rillig   2344:      * In the loop below, ignore ':' unless we are at (or back to) the
                   2345:      * original brace level.
                   2346:      * XXX This will likely not work right if $() and ${} are intermixed.
1.236     rillig   2347:      */
1.288     rillig   2348:     int nest = 1;
1.299     rillig   2349:     for (st->cp = mod + 1;
1.236     rillig   2350:         *st->cp != '\0' && !(*st->cp == ':' && nest == 1);
                   2351:         st->cp++) {
                   2352:        if (*st->cp == '\\' &&
                   2353:            (st->cp[1] == ':' || st->cp[1] == st->endc ||
                   2354:             st->cp[1] == st->startc)) {
                   2355:            if (!needSubst)
                   2356:                copy = TRUE;
                   2357:            st->cp++;
                   2358:            continue;
                   2359:        }
                   2360:        if (*st->cp == '$')
                   2361:            needSubst = TRUE;
                   2362:        if (*st->cp == '(' || *st->cp == '{')
                   2363:            ++nest;
                   2364:        if (*st->cp == ')' || *st->cp == '}') {
                   2365:            --nest;
                   2366:            if (nest == 0)
                   2367:                break;
                   2368:        }
                   2369:     }
                   2370:     st->termc = *st->cp;
1.288     rillig   2371:     const char *endpat = st->cp;
                   2372:
                   2373:     char *pattern = NULL;
1.236     rillig   2374:     if (copy) {
                   2375:        /*
                   2376:         * Need to compress the \:'s out of the pattern, so
                   2377:         * allocate enough room to hold the uncompressed
1.299     rillig   2378:         * pattern (note that st->cp started at mod+1, so
                   2379:         * st->cp - mod takes the null byte into account) and
1.236     rillig   2380:         * compress the pattern into the space.
                   2381:         */
1.299     rillig   2382:        pattern = bmake_malloc(st->cp - mod);
1.288     rillig   2383:        char *cp2;
1.299     rillig   2384:        for (cp2 = pattern, st->cp = mod + 1;
1.236     rillig   2385:             st->cp < endpat;
                   2386:             st->cp++, cp2++) {
                   2387:            if ((*st->cp == '\\') && (st->cp+1 < endpat) &&
                   2388:                (st->cp[1] == ':' || st->cp[1] == st->endc))
                   2389:                st->cp++;
                   2390:            *cp2 = *st->cp;
                   2391:        }
                   2392:        *cp2 = '\0';
                   2393:        endpat = cp2;
                   2394:     } else {
                   2395:        /*
1.292     rillig   2396:         * Either Var_Subst or ModifyWords will need a
1.236     rillig   2397:         * nul-terminated string soon, so construct one now.
                   2398:         */
1.299     rillig   2399:        pattern = bmake_strndup(mod + 1, endpat - (mod + 1));
1.236     rillig   2400:     }
                   2401:     if (needSubst) {
                   2402:        /* pattern contains embedded '$', so use Var_Subst to expand it. */
1.288     rillig   2403:        char *old_pattern = pattern;
                   2404:        pattern = Var_Subst(NULL, pattern, st->ctxt, st->eflags);
                   2405:        free(old_pattern);
1.236     rillig   2406:     }
                   2407:     if (DEBUG(VAR))
                   2408:        fprintf(debug_file, "Pattern[%s] for [%s] is [%s]\n",
                   2409:            st->v->name, st->nstr, pattern);
1.299     rillig   2410:     ModifyWordsCallback callback = mod[0] == 'M'
1.291     rillig   2411:        ? ModifyWord_Match : ModifyWord_NoMatch;
                   2412:     st->newStr = ModifyWords(st->ctxt, &st->parsestate, st->nstr,
                   2413:                             callback, pattern);
1.236     rillig   2414:     free(pattern);
                   2415: }
                   2416:
                   2417: /* :S,from,to, */
                   2418: static Boolean
1.299     rillig   2419: ApplyModifier_Subst(const char * const mod, ApplyModifiersState *st)
1.236     rillig   2420: {
1.291     rillig   2421:     ModifyWord_SubstArgs args;
1.281     rillig   2422:     Var_Parse_State tmpparsestate = st->parsestate;
1.299     rillig   2423:     char delim = mod[1];
                   2424:
                   2425:     st->cp = mod + 2;
1.236     rillig   2426:
                   2427:     /*
                   2428:      * If pattern begins with '^', it is anchored to the
                   2429:      * start of the word -- skip over it and flag pattern.
                   2430:      */
1.281     rillig   2431:     args.pflags = 0;
1.299     rillig   2432:     if (*st->cp == '^') {
1.288     rillig   2433:        args.pflags |= VARP_ANCHOR_START;
1.299     rillig   2434:        st->cp++;
1.236     rillig   2435:     }
                   2436:
1.298     rillig   2437:     char *lhs = ParseModifierPart(st->ctxt, &st->cp, delim, st->eflags,
1.281     rillig   2438:                                  &args.pflags, &args.lhsLen, NULL);
1.298     rillig   2439:     if (lhs == NULL) {
                   2440:        st->missing_delim = delim;
1.236     rillig   2441:        return FALSE;
1.298     rillig   2442:     }
1.281     rillig   2443:     args.lhs = lhs;
1.236     rillig   2444:
1.298     rillig   2445:     char *rhs = ParseModifierPart(st->ctxt, &st->cp, delim, st->eflags,
1.281     rillig   2446:                                  NULL, &args.rhsLen, &args);
1.298     rillig   2447:     if (rhs == NULL) {
                   2448:        st->missing_delim = delim;
1.236     rillig   2449:        return FALSE;
1.298     rillig   2450:     }
1.281     rillig   2451:     args.rhs = rhs;
1.236     rillig   2452:
                   2453:     /*
                   2454:      * Check for global substitution. If 'g' after the final
                   2455:      * delimiter, substitution is global and is marked that
                   2456:      * way.
                   2457:      */
                   2458:     for (;; st->cp++) {
                   2459:        switch (*st->cp) {
                   2460:        case 'g':
1.281     rillig   2461:            args.pflags |= VARP_SUB_GLOBAL;
1.236     rillig   2462:            continue;
                   2463:        case '1':
1.281     rillig   2464:            args.pflags |= VARP_SUB_ONE;
1.236     rillig   2465:            continue;
                   2466:        case 'W':
                   2467:            tmpparsestate.oneBigWord = TRUE;
                   2468:            continue;
                   2469:        }
                   2470:        break;
                   2471:     }
                   2472:
                   2473:     st->termc = *st->cp;
1.291     rillig   2474:     st->newStr = ModifyWords(st->ctxt, &tmpparsestate, st->nstr,
                   2475:                             ModifyWord_Subst, &args);
1.236     rillig   2476:
1.281     rillig   2477:     free(lhs);
                   2478:     free(rhs);
1.236     rillig   2479:     return TRUE;
                   2480: }
                   2481:
                   2482: #ifndef NO_REGEX
1.291     rillig   2483:
1.236     rillig   2484: /* :C,from,to, */
                   2485: static Boolean
1.299     rillig   2486: ApplyModifier_Regex(const char *mod, ApplyModifiersState *st)
1.236     rillig   2487: {
1.291     rillig   2488:     ModifyWord_SubstRegexArgs args;
1.236     rillig   2489:
1.291     rillig   2490:     args.pflags = 0;
1.288     rillig   2491:     Var_Parse_State tmpparsestate = st->parsestate;
1.299     rillig   2492:     char delim = mod[1];
1.236     rillig   2493:
1.299     rillig   2494:     st->cp = mod + 2;
1.236     rillig   2495:
1.297     rillig   2496:     char *re = ParseModifierPart(st->ctxt, &st->cp, delim,
1.291     rillig   2497:                                 st->eflags, NULL, NULL, NULL);
1.297     rillig   2498:     if (re == NULL) {
1.298     rillig   2499:        st->missing_delim = delim;
1.236     rillig   2500:        return FALSE;
1.297     rillig   2501:     }
1.236     rillig   2502:
1.297     rillig   2503:     args.replace = ParseModifierPart(st->ctxt, &st->cp, delim,
1.291     rillig   2504:                                     st->eflags, NULL, NULL, NULL);
                   2505:     if (args.replace == NULL) {
1.236     rillig   2506:        free(re);
1.298     rillig   2507:        st->missing_delim = delim;
1.236     rillig   2508:        return FALSE;
                   2509:     }
                   2510:
                   2511:     for (;; st->cp++) {
                   2512:        switch (*st->cp) {
                   2513:        case 'g':
1.291     rillig   2514:            args.pflags |= VARP_SUB_GLOBAL;
1.236     rillig   2515:            continue;
                   2516:        case '1':
1.291     rillig   2517:            args.pflags |= VARP_SUB_ONE;
1.236     rillig   2518:            continue;
                   2519:        case 'W':
                   2520:            tmpparsestate.oneBigWord = TRUE;
                   2521:            continue;
                   2522:        }
                   2523:        break;
                   2524:     }
                   2525:
                   2526:     st->termc = *st->cp;
                   2527:
1.291     rillig   2528:     int error = regcomp(&args.re, re, REG_EXTENDED);
1.236     rillig   2529:     free(re);
1.242     rillig   2530:     if (error) {
1.236     rillig   2531:        *st->lengthPtr = st->cp - st->start + 1;
1.291     rillig   2532:        VarREError(error, &args.re, "RE substitution error");
                   2533:        free(args.replace);
1.236     rillig   2534:        return FALSE;
                   2535:     }
                   2536:
1.291     rillig   2537:     args.nsub = args.re.re_nsub + 1;
                   2538:     if (args.nsub < 1)
                   2539:        args.nsub = 1;
                   2540:     if (args.nsub > 10)
                   2541:        args.nsub = 10;
                   2542:     args.matches = bmake_malloc(args.nsub * sizeof(regmatch_t));
                   2543:     st->newStr = ModifyWords(st->ctxt, &tmpparsestate, st->nstr,
                   2544:                             ModifyWord_SubstRegex, &args);
                   2545:     regfree(&args.re);
                   2546:     free(args.replace);
                   2547:     free(args.matches);
1.236     rillig   2548:     return TRUE;
                   2549: }
                   2550: #endif
                   2551:
1.278     rillig   2552: static void
1.295     rillig   2553: ModifyWord_Copy(const char *word, SepBuf *buf, void *data MAKE_ATTR_UNUSED)
1.278     rillig   2554: {
                   2555:     SepBuf_AddBytes(buf, word, strlen(word));
1.275     rillig   2556: }
                   2557:
1.289     rillig   2558: /* :ts<separator> */
                   2559: static Boolean
1.299     rillig   2560: ApplyModifier_ToSep(const char *sep, ApplyModifiersState *st)
1.289     rillig   2561: {
                   2562:     if (sep[0] != st->endc && (sep[1] == st->endc || sep[1] == ':')) {
                   2563:        /* ":ts<unrecognised><endc>" or ":ts<unrecognised>:" */
                   2564:        st->parsestate.varSpace = sep[0];
                   2565:        st->cp = sep + 1;
                   2566:     } else if (sep[0] == st->endc || sep[0] == ':') {
                   2567:        /* ":ts<endc>" or ":ts:" */
                   2568:        st->parsestate.varSpace = 0;    /* no separator */
                   2569:        st->cp = sep;
                   2570:     } else if (sep[0] == '\\') {
                   2571:        const char *xp = sep + 1;
                   2572:        int base = 8;           /* assume octal */
                   2573:
                   2574:        switch (sep[1]) {
                   2575:        case 'n':
                   2576:            st->parsestate.varSpace = '\n';
                   2577:            st->cp = sep + 2;
                   2578:            break;
                   2579:        case 't':
                   2580:            st->parsestate.varSpace = '\t';
                   2581:            st->cp = sep + 2;
                   2582:            break;
                   2583:        case 'x':
                   2584:            base = 16;
                   2585:            xp++;
                   2586:            goto get_numeric;
                   2587:        case '0':
                   2588:            base = 0;
                   2589:            goto get_numeric;
                   2590:        default:
                   2591:            if (!isdigit((unsigned char)sep[1]))
                   2592:                return FALSE;   /* ":ts<backslash><unrecognised>". */
                   2593:
                   2594:            char *end;
                   2595:        get_numeric:
1.295     rillig   2596:            st->parsestate.varSpace = strtoul(sep + 1 + (sep[1] == 'x'),
                   2597:                                              &end, base);
1.289     rillig   2598:            if (*end != ':' && *end != st->endc)
                   2599:                return FALSE;
                   2600:            st->cp = end;
                   2601:            break;
                   2602:        }
                   2603:     } else {
                   2604:        return FALSE;           /* Found ":ts<unrecognised><unrecognised>". */
                   2605:     }
                   2606:
                   2607:     st->termc = *st->cp;
1.291     rillig   2608:     st->newStr = ModifyWords(st->ctxt, &st->parsestate, st->nstr,
1.292     rillig   2609:                             ModifyWord_Copy, NULL);
1.289     rillig   2610:     return TRUE;
                   2611: }
                   2612:
                   2613: /* :tA, :tu, :tl, :ts<separator>, etc. */
1.236     rillig   2614: static Boolean
1.299     rillig   2615: ApplyModifier_To(const char *mod, ApplyModifiersState *st)
1.236     rillig   2616: {
1.299     rillig   2617:     st->cp = mod + 1;  /* make sure it is set */
                   2618:     if (mod[1] == st->endc || mod[1] == ':')
1.289     rillig   2619:        return FALSE;           /* Found ":t<endc>" or ":t:". */
                   2620:
1.299     rillig   2621:     if (mod[1] == 's')
                   2622:        return ApplyModifier_ToSep(mod + 2, st);
1.289     rillig   2623:
1.299     rillig   2624:     if (mod[2] != st->endc && mod[2] != ':')
1.289     rillig   2625:        return FALSE;           /* Found ":t<unrecognised><unrecognised>". */
1.236     rillig   2626:
1.289     rillig   2627:     /* Check for two-character options: ":tu", ":tl" */
1.299     rillig   2628:     if (mod[1] == 'A') {       /* absolute path */
1.291     rillig   2629:        st->newStr = ModifyWords(st->ctxt, &st->parsestate, st->nstr,
                   2630:                                 ModifyWord_Realpath, NULL);
1.299     rillig   2631:        st->cp = mod + 2;
1.289     rillig   2632:        st->termc = *st->cp;
1.299     rillig   2633:     } else if (mod[1] == 'u') {
1.289     rillig   2634:        char *dp = bmake_strdup(st->nstr);
                   2635:        for (st->newStr = dp; *dp; dp++)
                   2636:            *dp = toupper((unsigned char)*dp);
1.299     rillig   2637:        st->cp = mod + 2;
1.289     rillig   2638:        st->termc = *st->cp;
1.299     rillig   2639:     } else if (mod[1] == 'l') {
1.289     rillig   2640:        char *dp = bmake_strdup(st->nstr);
                   2641:        for (st->newStr = dp; *dp; dp++)
                   2642:            *dp = tolower((unsigned char)*dp);
1.299     rillig   2643:        st->cp = mod + 2;
1.289     rillig   2644:        st->termc = *st->cp;
1.299     rillig   2645:     } else if (mod[1] == 'W' || mod[1] == 'w') {
                   2646:        st->parsestate.oneBigWord = (mod[1] == 'W');
1.289     rillig   2647:        st->newStr = st->nstr;
1.299     rillig   2648:        st->cp = mod + 2;
1.289     rillig   2649:        st->termc = *st->cp;
1.236     rillig   2650:     } else {
1.289     rillig   2651:        /* Found ":t<unrecognised>:" or ":t<unrecognised><endc>". */
1.236     rillig   2652:        return FALSE;
                   2653:     }
                   2654:     return TRUE;
                   2655: }
                   2656:
                   2657: /* :[#], :[1], etc. */
                   2658: static int
1.299     rillig   2659: ApplyModifier_Words(const char *mod, ApplyModifiersState *st)
1.236     rillig   2660: {
1.299     rillig   2661:     st->cp = mod + 1;  /* point to char after '[' */
1.298     rillig   2662:     char delim = ']';          /* look for closing ']' */
                   2663:     char *estr = ParseModifierPart(st->ctxt, &st->cp, delim, st->eflags,
1.266     rillig   2664:                                   NULL, NULL, NULL);
1.298     rillig   2665:     if (estr == NULL) {
                   2666:        st->missing_delim = delim;
                   2667:        return 'c';
                   2668:     }
1.288     rillig   2669:
1.236     rillig   2670:     /* now st->cp points just after the closing ']' */
1.288     rillig   2671:     if (st->cp[0] != ':' && st->cp[0] != st->endc)
                   2672:        goto bad_modifier;      /* Found junk after ']' */
                   2673:
                   2674:     if (estr[0] == '\0')
                   2675:        goto bad_modifier;      /* empty square brackets in ":[]". */
1.236     rillig   2676:
1.288     rillig   2677:     if (estr[0] == '#' && estr[1] == '\0') { /* Found ":[#]" */
1.236     rillig   2678:        /*
1.288     rillig   2679:         * We will need enough space for the decimal representation of an int.
                   2680:         * We calculate the space needed for the octal representation, and add
                   2681:         * enough slop to cope with a '-' sign (which should never be needed)
                   2682:         * and a '\0' string terminator.
1.236     rillig   2683:         */
                   2684:        int newStrSize = (sizeof(int) * CHAR_BIT + 2) / 3 + 2;
                   2685:
                   2686:        st->newStr = bmake_malloc(newStrSize);
                   2687:        if (st->parsestate.oneBigWord) {
                   2688:            strncpy(st->newStr, "1", newStrSize);
                   2689:        } else {
                   2690:            /* XXX: brk_string() is a rather expensive
                   2691:             * way of counting words. */
                   2692:            char **av;
                   2693:            char *as;
                   2694:            int ac;
                   2695:
                   2696:            av = brk_string(st->nstr, &ac, FALSE, &as);
1.242     rillig   2697:            snprintf(st->newStr, newStrSize, "%d", ac);
1.236     rillig   2698:            free(as);
                   2699:            free(av);
                   2700:        }
1.288     rillig   2701:        goto ok;
                   2702:     }
                   2703:
                   2704:     if (estr[0] == '*' && estr[1] == '\0') {
1.236     rillig   2705:        /* Found ":[*]" */
                   2706:        st->parsestate.oneBigWord = TRUE;
                   2707:        st->newStr = st->nstr;
1.288     rillig   2708:        goto ok;
                   2709:     }
                   2710:
                   2711:     if (estr[0] == '@' && estr[1] == '\0') {
1.236     rillig   2712:        /* Found ":[@]" */
                   2713:        st->parsestate.oneBigWord = FALSE;
                   2714:        st->newStr = st->nstr;
1.288     rillig   2715:        goto ok;
                   2716:     }
                   2717:
                   2718:     /*
                   2719:      * We expect estr to contain a single integer for :[N], or two integers
                   2720:      * separated by ".." for :[start..end].
                   2721:      */
                   2722:     char *ep;
1.290     rillig   2723:     int first = strtol(estr, &ep, 0);
                   2724:     int last;
1.288     rillig   2725:     if (ep == estr)            /* Found junk instead of a number */
                   2726:        goto bad_modifier;
                   2727:
                   2728:     if (ep[0] == '\0') {       /* Found only one integer in :[N] */
1.290     rillig   2729:        last = first;
1.288     rillig   2730:     } else if (ep[0] == '.' && ep[1] == '.' && ep[2] != '\0') {
                   2731:        /* Expecting another integer after ".." */
                   2732:        ep += 2;
1.290     rillig   2733:        last = strtol(ep, &ep, 0);
1.288     rillig   2734:        if (ep[0] != '\0')      /* Found junk after ".." */
                   2735:            goto bad_modifier;
                   2736:     } else
                   2737:        goto bad_modifier;      /* Found junk instead of ".." */
1.236     rillig   2738:
1.288     rillig   2739:     /*
                   2740:      * Now seldata is properly filled in, but we still have to check for 0 as
                   2741:      * a special case.
                   2742:      */
1.290     rillig   2743:     if (first == 0 && last == 0) {
1.288     rillig   2744:        /* ":[0]" or perhaps ":[0..0]" */
                   2745:        st->parsestate.oneBigWord = TRUE;
                   2746:        st->newStr = st->nstr;
                   2747:        goto ok;
1.236     rillig   2748:     }
1.288     rillig   2749:
                   2750:     /* ":[0..N]" or ":[N..0]" */
1.290     rillig   2751:     if (first == 0 || last == 0)
1.288     rillig   2752:        goto bad_modifier;
                   2753:
                   2754:     /* Normal case: select the words described by seldata. */
1.295     rillig   2755:     st->newStr = VarSelectWords(&st->parsestate, st->nstr, first, last);
1.288     rillig   2756:
                   2757: ok:
                   2758:     st->termc = *st->cp;
                   2759:     free(estr);
                   2760:     return 0;
                   2761:
                   2762: bad_modifier:
                   2763:     free(estr);
                   2764:     return 'b';
1.236     rillig   2765: }
                   2766:
                   2767: /* :O or :Ox */
                   2768: static Boolean
1.299     rillig   2769: ApplyModifier_Order(const char *mod, ApplyModifiersState *st)
1.236     rillig   2770: {
                   2771:     char otype;
                   2772:
1.299     rillig   2773:     st->cp = mod + 1;  /* skip to the rest in any case */
                   2774:     if (mod[1] == st->endc || mod[1] == ':') {
1.236     rillig   2775:        otype = 's';
                   2776:        st->termc = *st->cp;
1.299     rillig   2777:     } else if ((mod[1] == 'r' || mod[1] == 'x') &&
                   2778:               (mod[2] == st->endc || mod[2] == ':')) {
                   2779:        otype = mod[1];
                   2780:        st->cp = mod + 2;
1.236     rillig   2781:        st->termc = *st->cp;
                   2782:     } else {
                   2783:        return FALSE;
                   2784:     }
                   2785:     st->newStr = VarOrder(st->nstr, otype);
                   2786:     return TRUE;
                   2787: }
                   2788:
                   2789: /* :? then : else */
                   2790: static Boolean
1.299     rillig   2791: ApplyModifier_IfElse(const char *mod, ApplyModifiersState *st)
1.236     rillig   2792: {
1.285     rillig   2793:     Boolean value = FALSE;
                   2794:     int cond_rc = 0;
                   2795:     VarEvalFlags then_eflags = st->eflags & ~VARE_WANTRES;
                   2796:     VarEvalFlags else_eflags = st->eflags & ~VARE_WANTRES;
1.236     rillig   2797:
1.268     rillig   2798:     if (st->eflags & VARE_WANTRES) {
1.236     rillig   2799:        cond_rc = Cond_EvalExpression(NULL, st->v->name, &value, 0, FALSE);
1.285     rillig   2800:        if (cond_rc != COND_INVALID && value)
                   2801:            then_eflags |= VARE_WANTRES;
                   2802:        if (cond_rc != COND_INVALID && !value)
                   2803:            else_eflags |= VARE_WANTRES;
1.236     rillig   2804:     }
                   2805:
1.299     rillig   2806:     st->cp = mod + 1;
1.298     rillig   2807:     char delim = ':';
1.265     rillig   2808:     char *then_expr = ParseModifierPart(
1.298     rillig   2809:        st->ctxt, &st->cp, delim, then_eflags, NULL, NULL, NULL);
                   2810:     if (then_expr == NULL) {
                   2811:        st->missing_delim = delim;
1.236     rillig   2812:        return FALSE;
1.298     rillig   2813:     }
1.236     rillig   2814:
1.298     rillig   2815:     delim = st->endc;          /* BRCLOSE or PRCLOSE */
1.265     rillig   2816:     char *else_expr = ParseModifierPart(
1.298     rillig   2817:        st->ctxt, &st->cp, delim, else_eflags, NULL, NULL, NULL);
                   2818:     if (else_expr == NULL) {
                   2819:        st->missing_delim = delim;
1.236     rillig   2820:        return FALSE;
1.298     rillig   2821:     }
1.236     rillig   2822:
                   2823:     st->termc = *--st->cp;
                   2824:     if (cond_rc == COND_INVALID) {
                   2825:        Error("Bad conditional expression `%s' in %s?%s:%s",
1.258     rillig   2826:            st->v->name, st->v->name, then_expr, else_expr);
1.236     rillig   2827:        return FALSE;
                   2828:     }
                   2829:
                   2830:     if (value) {
1.258     rillig   2831:        st->newStr = then_expr;
                   2832:        free(else_expr);
1.236     rillig   2833:     } else {
1.258     rillig   2834:        st->newStr = else_expr;
1.270     rillig   2835:        free(then_expr);
1.236     rillig   2836:     }
                   2837:     if (st->v->flags & VAR_JUNK)
                   2838:        st->v->flags |= VAR_KEEP;
                   2839:     return TRUE;
                   2840: }
                   2841:
1.283     rillig   2842: /*
                   2843:  * The ::= modifiers actually assign a value to the variable.
                   2844:  * Their main purpose is in supporting modifiers of .for loop
                   2845:  * iterators and other obscure uses.  They always expand to
                   2846:  * nothing.  In a target rule that would otherwise expand to an
                   2847:  * empty line they can be preceded with @: to keep make happy.
                   2848:  * Eg.
                   2849:  *
                   2850:  * foo:        .USE
                   2851:  * .for i in ${.TARGET} ${.TARGET:R}.gz
                   2852:  *     @: ${t::=$i}
                   2853:  *     @echo blah ${t:T}
                   2854:  * .endfor
                   2855:  *
                   2856:  *       ::=<str>      Assigns <str> as the new value of variable.
                   2857:  *       ::?=<str>     Assigns <str> as value of variable if
                   2858:  *                     it was not already set.
                   2859:  *       ::+=<str>     Appends <str> to variable.
                   2860:  *       ::!=<cmd>     Assigns output of <cmd> as the new value of
                   2861:  *                     variable.
                   2862:  */
1.236     rillig   2863: static int
1.299     rillig   2864: ApplyModifier_Assign(const char *mod, ApplyModifiersState *st)
1.236     rillig   2865: {
1.299     rillig   2866:     const char *op = mod + 1;
1.272     rillig   2867:     if (!(op[0] == '=' ||
                   2868:        (op[1] == '=' &&
                   2869:         (op[0] == '!' || op[0] == '+' || op[0] == '?'))))
                   2870:        return 'd';             /* "::<unrecognised>" */
1.236     rillig   2871:
1.272     rillig   2872:     GNode *v_ctxt;             /* context where v belongs */
                   2873:
                   2874:     if (st->v->name[0] == 0)
                   2875:        return 'b';
                   2876:
                   2877:     v_ctxt = st->ctxt;
1.273     rillig   2878:     char *sv_name = NULL;
1.272     rillig   2879:     if (st->v->flags & VAR_JUNK) {
                   2880:        /*
                   2881:         * We need to bmake_strdup() it incase ParseModifierPart() recurses.
                   2882:         */
                   2883:        sv_name = st->v->name;
                   2884:        st->v->name = bmake_strdup(st->v->name);
                   2885:     } else if (st->ctxt != VAR_GLOBAL) {
                   2886:        Var *gv = VarFind(st->v->name, st->ctxt, 0);
                   2887:        if (gv == NULL)
                   2888:            v_ctxt = VAR_GLOBAL;
                   2889:        else
                   2890:            VarFreeEnv(gv, TRUE);
                   2891:     }
                   2892:
1.273     rillig   2893:     switch (op[0]) {
1.272     rillig   2894:     case '+':
                   2895:     case '?':
                   2896:     case '!':
1.299     rillig   2897:        st->cp = mod + 3;
1.272     rillig   2898:        break;
                   2899:     default:
1.299     rillig   2900:        st->cp = mod + 2;
1.272     rillig   2901:        break;
                   2902:     }
                   2903:
1.298     rillig   2904:     char delim = st->startc == PROPEN ? PRCLOSE : BRCLOSE;
1.287     rillig   2905:     VarEvalFlags eflags = (st->eflags & VARE_WANTRES) ? 0 : VARE_NOSUBST;
1.298     rillig   2906:     char *val = ParseModifierPart(st->ctxt, &st->cp, delim,
1.287     rillig   2907:                                  st->eflags | eflags, NULL, NULL, NULL);
1.272     rillig   2908:     if (st->v->flags & VAR_JUNK) {
                   2909:        /* restore original name */
                   2910:        free(st->v->name);
                   2911:        st->v->name = sv_name;
                   2912:     }
1.298     rillig   2913:     if (val == NULL) {
                   2914:        st->missing_delim = delim;
1.272     rillig   2915:        return 'c';
1.298     rillig   2916:     }
1.236     rillig   2917:
1.272     rillig   2918:     st->termc = *--st->cp;
1.236     rillig   2919:
1.272     rillig   2920:     if (st->eflags & VARE_WANTRES) {
1.273     rillig   2921:        switch (op[0]) {
1.236     rillig   2922:        case '+':
1.273     rillig   2923:            Var_Append(st->v->name, val, v_ctxt);
1.272     rillig   2924:            break;
1.273     rillig   2925:        case '!': {
                   2926:            const char *emsg;
                   2927:            st->newStr = Cmd_Exec(val, &emsg);
1.272     rillig   2928:            if (emsg)
                   2929:                Error(emsg, st->nstr);
                   2930:            else
                   2931:                Var_Set(st->v->name, st->newStr, v_ctxt);
                   2932:            free(st->newStr);
1.236     rillig   2933:            break;
1.273     rillig   2934:        }
1.272     rillig   2935:        case '?':
                   2936:            if ((st->v->flags & VAR_JUNK) == 0)
                   2937:                break;
                   2938:            /* FALLTHROUGH */
1.236     rillig   2939:        default:
1.273     rillig   2940:            Var_Set(st->v->name, val, v_ctxt);
1.236     rillig   2941:            break;
                   2942:        }
                   2943:     }
1.273     rillig   2944:     free(val);
1.272     rillig   2945:     st->newStr = varNoError;
                   2946:     return 0;
1.236     rillig   2947: }
                   2948:
                   2949: /* remember current value */
                   2950: static Boolean
1.299     rillig   2951: ApplyModifier_Remember(const char *mod, ApplyModifiersState *st)
1.236     rillig   2952: {
1.299     rillig   2953:     st->cp = mod + 1;  /* make sure it is set */
                   2954:     if (!STRMOD_MATCHX(mod, "_", 1))
1.236     rillig   2955:        return FALSE;
                   2956:
1.299     rillig   2957:     if (mod[1] == '=') {
1.236     rillig   2958:        char *np;
                   2959:        int n;
                   2960:
                   2961:        st->cp++;
                   2962:        n = strcspn(st->cp, ":)}");
1.249     rillig   2963:        np = bmake_strndup(st->cp, n + 1);
1.236     rillig   2964:        np[n] = '\0';
1.299     rillig   2965:        st->cp = mod + 2 + n;
1.236     rillig   2966:        Var_Set(np, st->nstr, st->ctxt);
                   2967:        free(np);
                   2968:     } else {
                   2969:        Var_Set("_", st->nstr, st->ctxt);
                   2970:     }
                   2971:     st->newStr = st->nstr;
                   2972:     st->termc = *st->cp;
                   2973:     return TRUE;
                   2974: }
                   2975:
                   2976: #ifdef SYSVVARSUB
                   2977: /* :from=to */
                   2978: static int
1.299     rillig   2979: ApplyModifier_SysV(const char *mod, ApplyModifiersState *st)
1.236     rillig   2980: {
1.276     rillig   2981:     Boolean eqFound = FALSE;
1.245     rillig   2982:
1.236     rillig   2983:     /*
                   2984:      * First we make a pass through the string trying
                   2985:      * to verify it is a SYSV-make-style translation:
                   2986:      * it must be: <string1>=<string2>)
                   2987:      */
1.299     rillig   2988:     st->cp = mod;
1.262     rillig   2989:     int nest = 1;
                   2990:     while (*st->cp != '\0' && nest > 0) {
1.236     rillig   2991:        if (*st->cp == '=') {
                   2992:            eqFound = TRUE;
                   2993:            /* continue looking for st->endc */
1.242     rillig   2994:        } else if (*st->cp == st->endc)
1.262     rillig   2995:            nest--;
1.236     rillig   2996:        else if (*st->cp == st->startc)
1.262     rillig   2997:            nest++;
                   2998:        if (nest > 0)
1.236     rillig   2999:            st->cp++;
                   3000:     }
1.245     rillig   3001:     if (*st->cp != st->endc || !eqFound)
                   3002:        return 0;
1.236     rillig   3003:
1.298     rillig   3004:     char delim = '=';
1.299     rillig   3005:     st->cp = mod;
1.298     rillig   3006:     char *lhs = ParseModifierPart(st->ctxt, &st->cp, delim, st->eflags,
1.284     rillig   3007:                                  NULL, NULL, NULL);
1.298     rillig   3008:     if (lhs == NULL) {
                   3009:        st->missing_delim = delim;
1.245     rillig   3010:        return 'c';
1.298     rillig   3011:     }
1.245     rillig   3012:
1.298     rillig   3013:     delim = st->endc;
                   3014:     char *rhs = ParseModifierPart(st->ctxt, &st->cp, delim, st->eflags,
1.276     rillig   3015:                                  NULL, NULL, NULL);
1.298     rillig   3016:     if (rhs == NULL) {
                   3017:        st->missing_delim = delim;
1.245     rillig   3018:        return 'c';
1.298     rillig   3019:     }
1.236     rillig   3020:
1.245     rillig   3021:     /*
                   3022:      * SYSV modifications happen through the whole
                   3023:      * string. Note the pattern is anchored at the end.
                   3024:      */
                   3025:     st->termc = *--st->cp;
1.276     rillig   3026:     if (lhs[0] == '\0' && *st->nstr == '\0') {
1.245     rillig   3027:        st->newStr = st->nstr;  /* special case */
                   3028:     } else {
1.295     rillig   3029:        ModifyWord_SYSVSubstArgs args = { st->ctxt, lhs, rhs };
1.291     rillig   3030:        st->newStr = ModifyWords(st->ctxt, &st->parsestate, st->nstr,
                   3031:                                 ModifyWord_SYSVSubst, &args);
1.245     rillig   3032:     }
1.276     rillig   3033:     free(lhs);
                   3034:     free(rhs);
1.245     rillig   3035:     return '=';
1.236     rillig   3036: }
                   3037: #endif
                   3038:
1.108     sjg      3039: /*
                   3040:  * Now we need to apply any modifiers the user wants applied.
                   3041:  * These are:
                   3042:  *       :M<pattern>   words which match the given <pattern>.
1.138     dsl      3043:  *                     <pattern> is of the standard file
                   3044:  *                     wildcarding form.
1.108     sjg      3045:  *       :N<pattern>   words which do not match the given <pattern>.
                   3046:  *       :S<d><pat1><d><pat2><d>[1gW]
1.138     dsl      3047:  *                     Substitute <pat2> for <pat1> in the value
1.108     sjg      3048:  *       :C<d><pat1><d><pat2><d>[1gW]
1.138     dsl      3049:  *                     Substitute <pat2> for regex <pat1> in the value
                   3050:  *       :H            Substitute the head of each word
                   3051:  *       :T            Substitute the tail of each word
                   3052:  *       :E            Substitute the extension (minus '.') of
                   3053:  *                     each word
                   3054:  *       :R            Substitute the root of each word
                   3055:  *                     (pathname minus the suffix).
                   3056:  *       :O            ("Order") Alphabeticaly sort words in variable.
                   3057:  *       :Ox           ("intermiX") Randomize words in variable.
                   3058:  *       :u            ("uniq") Remove adjacent duplicate words.
                   3059:  *       :tu           Converts the variable contents to uppercase.
                   3060:  *       :tl           Converts the variable contents to lowercase.
                   3061:  *       :ts[c]        Sets varSpace - the char used to
                   3062:  *                     separate words to 'c'. If 'c' is
                   3063:  *                     omitted then no separation is used.
                   3064:  *       :tW           Treat the variable contents as a single
                   3065:  *                     word, even if it contains spaces.
                   3066:  *                     (Mnemonic: one big 'W'ord.)
                   3067:  *       :tw           Treat the variable contents as multiple
                   3068:  *                     space-separated words.
                   3069:  *                     (Mnemonic: many small 'w'ords.)
                   3070:  *       :[index]      Select a single word from the value.
                   3071:  *       :[start..end] Select multiple words from the value.
                   3072:  *       :[*] or :[0]  Select the entire value, as a single
                   3073:  *                     word.  Equivalent to :tW.
                   3074:  *       :[@]          Select the entire value, as multiple
                   3075:  *                     words.  Undoes the effect of :[*].
                   3076:  *                     Equivalent to :tw.
                   3077:  *       :[#]          Returns the number of words in the value.
                   3078:  *
                   3079:  *       :?<true-value>:<false-value>
                   3080:  *                     If the variable evaluates to true, return
                   3081:  *                     true value, else return the second value.
                   3082:  *       :lhs=rhs      Like :S, but the rhs goes to the end of
                   3083:  *                     the invocation.
                   3084:  *       :sh           Treat the current value as a command
                   3085:  *                     to be run, new value is its output.
1.108     sjg      3086:  * The following added so we can handle ODE makefiles.
1.138     dsl      3087:  *       :@<tmpvar>@<newval>@
                   3088:  *                     Assign a temporary local variable <tmpvar>
                   3089:  *                     to the current value of each word in turn
                   3090:  *                     and replace each word with the result of
                   3091:  *                     evaluating <newval>
                   3092:  *       :D<newval>    Use <newval> as value if variable defined
                   3093:  *       :U<newval>    Use <newval> as value if variable undefined
                   3094:  *       :L            Use the name of the variable as the value.
                   3095:  *       :P            Use the path of the node that has the same
                   3096:  *                     name as the variable as the value.  This
                   3097:  *                     basically includes an implied :L so that
                   3098:  *                     the common method of refering to the path
                   3099:  *                     of your dependent 'x' in a rule is to use
                   3100:  *                     the form '${x:P}'.
                   3101:  *       :!<cmd>!      Run cmd much the same as :sh run's the
                   3102:  *                     current value of the variable.
1.283     rillig   3103:  * Assignment operators (see ApplyModifier_Assign).
1.1       cgd      3104:  */
1.108     sjg      3105: static char *
                   3106: ApplyModifiers(char *nstr, const char *tstr,
1.236     rillig   3107:               int const startc, int const endc,
1.268     rillig   3108:               Var * const v, GNode * const ctxt, VarEvalFlags const eflags,
1.236     rillig   3109:               int * const lengthPtr, void ** const freePtr)
                   3110: {
                   3111:     ApplyModifiersState st = {
1.268     rillig   3112:        startc, endc, v, ctxt, eflags, lengthPtr, freePtr,
1.299     rillig   3113:        nstr, tstr, tstr,
1.262     rillig   3114:        '\0', '\0', 0, {' ', FALSE}, NULL
1.236     rillig   3115:     };
1.15      christos 3116:
1.299     rillig   3117:     const char *p = tstr;
                   3118:     while (*p != '\0' && *p != endc) {
1.142     dsl      3119:
1.299     rillig   3120:        if (*p == '$') {
1.142     dsl      3121:            /*
1.167     sjg      3122:             * We may have some complex modifiers in a variable.
1.1       cgd      3123:             */
1.108     sjg      3124:            void *freeIt;
                   3125:            char *rval;
1.127     christos 3126:            int rlen;
1.167     sjg      3127:            int c;
1.22      christos 3128:
1.299     rillig   3129:            rval = Var_Parse(p, st.ctxt, st.eflags, &rlen, &freeIt);
1.1       cgd      3130:
1.167     sjg      3131:            /*
1.236     rillig   3132:             * If we have not parsed up to st.endc or ':',
1.167     sjg      3133:             * we are not interested.
                   3134:             */
                   3135:            if (rval != NULL && *rval &&
1.299     rillig   3136:                (c = p[rlen]) != '\0' &&
1.167     sjg      3137:                c != ':' &&
1.236     rillig   3138:                c != st.endc) {
1.196     christos 3139:                free(freeIt);
1.167     sjg      3140:                goto apply_mods;
                   3141:            }
                   3142:
1.108     sjg      3143:            if (DEBUG(VAR)) {
1.114     dsl      3144:                fprintf(debug_file, "Got '%s' from '%.*s'%.*s\n",
1.299     rillig   3145:                       rval, rlen, p, rlen, p + rlen);
1.22      christos 3146:            }
1.1       cgd      3147:
1.299     rillig   3148:            p += rlen;
1.15      christos 3149:
1.108     sjg      3150:            if (rval != NULL && *rval) {
1.127     christos 3151:                int used;
1.15      christos 3152:
1.236     rillig   3153:                st.nstr = ApplyModifiers(st.nstr, rval, 0, 0, st.v,
1.268     rillig   3154:                                      st.ctxt, st.eflags, &used, st.freePtr);
1.236     rillig   3155:                if (st.nstr == var_Error
1.268     rillig   3156:                    || (st.nstr == varNoError && (st.eflags & VARE_UNDEFERR) == 0)
1.111     rillig   3157:                    || strlen(rval) != (size_t) used) {
1.196     christos 3158:                    free(freeIt);
1.240     rillig   3159:                    goto out;   /* error already reported */
1.1       cgd      3160:                }
                   3161:            }
1.196     christos 3162:            free(freeIt);
1.299     rillig   3163:            if (*p == ':')
                   3164:                p++;
                   3165:            else if (*p == '\0' && endc != '\0') {
1.246     rillig   3166:                Error("Unclosed variable specification after complex "
                   3167:                    "modifier (expecting '%c') for %s", st.endc, st.v->name);
1.119     sjg      3168:                goto out;
                   3169:            }
1.108     sjg      3170:            continue;
                   3171:        }
1.167     sjg      3172:     apply_mods:
1.108     sjg      3173:        if (DEBUG(VAR)) {
1.236     rillig   3174:            fprintf(debug_file, "Applying[%s] :%c to \"%s\"\n", st.v->name,
1.299     rillig   3175:                *p, st.nstr);
1.1       cgd      3176:        }
1.236     rillig   3177:        st.newStr = var_Error;
1.299     rillig   3178:        switch ((st.modifier = *p)) {
1.108     sjg      3179:        case ':':
1.1       cgd      3180:            {
1.299     rillig   3181:                int res = ApplyModifier_Assign(p, &st);
1.236     rillig   3182:                if (res == 'b')
                   3183:                    goto bad_modifier;
                   3184:                if (res == 'c')
1.108     sjg      3185:                    goto cleanup;
1.236     rillig   3186:                if (res == 'd')
                   3187:                    goto default_case;
1.108     sjg      3188:                break;
                   3189:            }
1.236     rillig   3190:        case '@':
1.299     rillig   3191:            ApplyModifier_Loop(p, &st);
1.236     rillig   3192:            break;
                   3193:        case '_':
1.299     rillig   3194:            if (!ApplyModifier_Remember(p, &st))
1.236     rillig   3195:                goto default_case;
                   3196:            break;
1.108     sjg      3197:        case 'D':
                   3198:        case 'U':
1.299     rillig   3199:            ApplyModifier_Defined(p, &st);
1.236     rillig   3200:            break;
1.108     sjg      3201:        case 'L':
                   3202:            {
1.236     rillig   3203:                if ((st.v->flags & VAR_JUNK) != 0)
                   3204:                    st.v->flags |= VAR_KEEP;
                   3205:                st.newStr = bmake_strdup(st.v->name);
1.299     rillig   3206:                st.cp = p + 1;
                   3207:                st.termc = *st.cp;
1.108     sjg      3208:                break;
                   3209:            }
                   3210:        case 'P':
1.299     rillig   3211:            ApplyModifier_Path(p, &st);
1.236     rillig   3212:            break;
1.108     sjg      3213:        case '!':
1.299     rillig   3214:            if (!ApplyModifier_Exclam(p, &st))
1.236     rillig   3215:                goto cleanup;
                   3216:            break;
                   3217:        case '[':
1.108     sjg      3218:            {
1.299     rillig   3219:                int res = ApplyModifier_Words(p, &st);
1.236     rillig   3220:                if (res == 'b')
                   3221:                    goto bad_modifier;
                   3222:                if (res == 'c')
1.108     sjg      3223:                    goto cleanup;
                   3224:                break;
                   3225:            }
1.164     sjg      3226:        case 'g':
1.299     rillig   3227:            if (!ApplyModifier_Gmtime(p, &st))
1.165     sjg      3228:                goto default_case;
1.164     sjg      3229:            break;
1.163     joerg    3230:        case 'h':
1.299     rillig   3231:            if (!ApplyModifier_Hash(p, &st))
1.165     sjg      3232:                goto default_case;
1.163     joerg    3233:            break;
1.164     sjg      3234:        case 'l':
1.299     rillig   3235:            if (!ApplyModifier_Localtime(p, &st))
1.165     sjg      3236:                goto default_case;
1.164     sjg      3237:            break;
1.108     sjg      3238:        case 't':
1.299     rillig   3239:            if (!ApplyModifier_To(p, &st))
1.236     rillig   3240:                goto bad_modifier;
                   3241:            break;
1.108     sjg      3242:        case 'N':
                   3243:        case 'M':
1.299     rillig   3244:            ApplyModifier_Match(p, &st);
1.236     rillig   3245:            break;
1.108     sjg      3246:        case 'S':
1.299     rillig   3247:            if (!ApplyModifier_Subst(p, &st))
1.236     rillig   3248:                goto cleanup;
                   3249:            break;
1.108     sjg      3250:        case '?':
1.299     rillig   3251:            if (!ApplyModifier_IfElse(p, &st))
1.236     rillig   3252:                goto cleanup;
                   3253:            break;
1.108     sjg      3254: #ifndef NO_REGEX
                   3255:        case 'C':
1.299     rillig   3256:            if (!ApplyModifier_Regex(p, &st))
1.236     rillig   3257:                goto cleanup;
                   3258:            break;
1.108     sjg      3259: #endif
1.220     christos 3260:        case 'q':
1.108     sjg      3261:        case 'Q':
1.299     rillig   3262:            if (p[1] == st.endc || p[1] == ':') {
1.236     rillig   3263:                st.newStr = VarQuote(st.nstr, st.modifier == 'q');
1.299     rillig   3264:                st.cp = p + 1;
1.236     rillig   3265:                st.termc = *st.cp;
1.108     sjg      3266:                break;
                   3267:            }
                   3268:            goto default_case;
                   3269:        case 'T':
1.299     rillig   3270:            if (p[1] == st.endc || p[1] == ':') {
1.291     rillig   3271:                st.newStr = ModifyWords(st.ctxt, &st.parsestate, st.nstr,
                   3272:                                        ModifyWord_Tail, NULL);
1.299     rillig   3273:                st.cp = p + 1;
1.236     rillig   3274:                st.termc = *st.cp;
1.108     sjg      3275:                break;
                   3276:            }
                   3277:            goto default_case;
                   3278:        case 'H':
1.299     rillig   3279:            if (p[1] == st.endc || p[1] == ':') {
1.291     rillig   3280:                st.newStr = ModifyWords(st.ctxt, &st.parsestate, st.nstr,
                   3281:                                        ModifyWord_Head, NULL);
1.299     rillig   3282:                st.cp = p + 1;
1.236     rillig   3283:                st.termc = *st.cp;
1.108     sjg      3284:                break;
                   3285:            }
                   3286:            goto default_case;
                   3287:        case 'E':
1.299     rillig   3288:            if (p[1] == st.endc || p[1] == ':') {
1.291     rillig   3289:                st.newStr = ModifyWords(st.ctxt, &st.parsestate, st.nstr,
                   3290:                                        ModifyWord_Suffix, NULL);
1.299     rillig   3291:                st.cp = p + 1;
1.236     rillig   3292:                st.termc = *st.cp;
1.108     sjg      3293:                break;
                   3294:            }
                   3295:            goto default_case;
                   3296:        case 'R':
1.299     rillig   3297:            if (p[1] == st.endc || p[1] == ':') {
1.291     rillig   3298:                st.newStr = ModifyWords(st.ctxt, &st.parsestate, st.nstr,
                   3299:                                        ModifyWord_Root, NULL);
1.299     rillig   3300:                st.cp = p + 1;
1.236     rillig   3301:                st.termc = *st.cp;
1.108     sjg      3302:                break;
                   3303:            }
                   3304:            goto default_case;
1.210     sjg      3305:        case 'r':
1.299     rillig   3306:            if (!ApplyModifier_Range(p, &st))
1.236     rillig   3307:                goto default_case;
                   3308:            break;
1.108     sjg      3309:        case 'O':
1.299     rillig   3310:            if (!ApplyModifier_Order(p, &st))
1.236     rillig   3311:                goto bad_modifier;
                   3312:            break;
1.108     sjg      3313:        case 'u':
1.299     rillig   3314:            if (p[1] == st.endc || p[1] == ':') {
1.236     rillig   3315:                st.newStr = VarUniq(st.nstr);
1.299     rillig   3316:                st.cp = p + 1;
1.236     rillig   3317:                st.termc = *st.cp;
1.108     sjg      3318:                break;
                   3319:            }
                   3320:            goto default_case;
                   3321: #ifdef SUNSHCMD
                   3322:        case 's':
1.299     rillig   3323:            if (p[1] == 'h' && (p[2] == st.endc || p[2] == ':')) {
1.108     sjg      3324:                const char *emsg;
1.268     rillig   3325:                if (st.eflags & VARE_WANTRES) {
1.236     rillig   3326:                    st.newStr = Cmd_Exec(st.nstr, &emsg);
1.197     sjg      3327:                    if (emsg)
1.236     rillig   3328:                        Error(emsg, st.nstr);
1.197     sjg      3329:                } else
1.236     rillig   3330:                    st.newStr = varNoError;
1.299     rillig   3331:                st.cp = p + 2;
1.236     rillig   3332:                st.termc = *st.cp;
1.108     sjg      3333:                break;
                   3334:            }
                   3335:            goto default_case;
                   3336: #endif
                   3337:        default:
1.142     dsl      3338:        default_case:
1.236     rillig   3339:            {
1.108     sjg      3340: #ifdef SYSVVARSUB
1.299     rillig   3341:                int res = ApplyModifier_SysV(p, &st);
1.236     rillig   3342:                if (res == 'c')
1.108     sjg      3343:                    goto cleanup;
1.236     rillig   3344:                if (res != '=')
1.108     sjg      3345: #endif
                   3346:                {
1.299     rillig   3347:                    Error("Unknown modifier '%c'", *p);
                   3348:                    for (st.cp = p + 1;
1.236     rillig   3349:                         *st.cp != ':' && *st.cp != st.endc && *st.cp != '\0';
                   3350:                         st.cp++)
1.108     sjg      3351:                        continue;
1.236     rillig   3352:                    st.termc = *st.cp;
                   3353:                    st.newStr = var_Error;
1.108     sjg      3354:                }
                   3355:            }
                   3356:        }
                   3357:        if (DEBUG(VAR)) {
1.172     christos 3358:            fprintf(debug_file, "Result[%s] of :%c is \"%s\"\n",
1.236     rillig   3359:                st.v->name, st.modifier, st.newStr);
1.108     sjg      3360:        }
1.25      christos 3361:
1.236     rillig   3362:        if (st.newStr != st.nstr) {
                   3363:            if (*st.freePtr) {
                   3364:                free(st.nstr);
                   3365:                *st.freePtr = NULL;
1.108     sjg      3366:            }
1.236     rillig   3367:            st.nstr = st.newStr;
                   3368:            if (st.nstr != var_Error && st.nstr != varNoError) {
                   3369:                *st.freePtr = st.nstr;
1.108     sjg      3370:            }
                   3371:        }
1.236     rillig   3372:        if (st.termc == '\0' && st.endc != '\0') {
1.246     rillig   3373:            Error("Unclosed variable specification (expecting '%c') "
                   3374:                "for \"%s\" (value \"%s\") modifier %c",
                   3375:                st.endc, st.v->name, st.nstr, st.modifier);
1.236     rillig   3376:        } else if (st.termc == ':') {
                   3377:            st.cp++;
1.108     sjg      3378:        }
1.299     rillig   3379:        p = st.cp;
1.108     sjg      3380:     }
1.240     rillig   3381: out:
1.299     rillig   3382:     *st.lengthPtr = p - st.start;
1.236     rillig   3383:     return st.nstr;
1.25      christos 3384:
1.240     rillig   3385: bad_modifier:
1.299     rillig   3386:     Error("Bad modifier `:%.*s' for %s",
                   3387:          (int)strcspn(p, ":)}"), p, st.v->name);
1.25      christos 3388:
1.240     rillig   3389: cleanup:
1.236     rillig   3390:     *st.lengthPtr = st.cp - st.start;
1.298     rillig   3391:     if (st.missing_delim != '\0')
1.108     sjg      3392:        Error("Unclosed substitution for %s (%c missing)",
1.298     rillig   3393:              st.v->name, st.missing_delim);
1.236     rillig   3394:     free(*st.freePtr);
                   3395:     *st.freePtr = NULL;
1.231     rillig   3396:     return var_Error;
1.108     sjg      3397: }
1.25      christos 3398:
1.108     sjg      3399: /*-
                   3400:  *-----------------------------------------------------------------------
                   3401:  * Var_Parse --
                   3402:  *     Given the start of a variable invocation, extract the variable
                   3403:  *     name and find its value, then modify it according to the
                   3404:  *     specification.
                   3405:  *
                   3406:  * Input:
                   3407:  *     str             The string to parse
                   3408:  *     ctxt            The context for the variable
1.259     rillig   3409:  *     flags           VARE_UNDEFERR   if undefineds are an error
                   3410:  *                     VARE_WANTRES    if we actually want the result
                   3411:  *                     VARE_ASSIGN     if we are in a := assignment
1.108     sjg      3412:  *     lengthPtr       OUT: The length of the specification
1.121     apb      3413:  *     freePtr         OUT: Non-NULL if caller should free *freePtr
1.108     sjg      3414:  *
                   3415:  * Results:
                   3416:  *     The (possibly-modified) value of the variable or var_Error if the
                   3417:  *     specification is invalid. The length of the specification is
                   3418:  *     placed in *lengthPtr (for invalid specifications, this is just
                   3419:  *     2...?).
1.121     apb      3420:  *     If *freePtr is non-NULL then it's a pointer that the caller
                   3421:  *     should pass to free() to free memory used by the result.
1.108     sjg      3422:  *
                   3423:  * Side Effects:
                   3424:  *     None.
                   3425:  *
                   3426:  *-----------------------------------------------------------------------
                   3427:  */
                   3428: /* coverity[+alloc : arg-*4] */
                   3429: char *
1.259     rillig   3430: Var_Parse(const char *str, GNode *ctxt, VarEvalFlags flags,
1.202     christos 3431:          int *lengthPtr, void **freePtr)
1.108     sjg      3432: {
1.240     rillig   3433:     const char *tstr;          /* Pointer into str */
                   3434:     Var                *v;             /* Variable in invocation */
                   3435:     Boolean     haveModifier;  /* TRUE if have modifiers for the variable */
                   3436:     char        endc;          /* Ending character when variable in parens
1.108     sjg      3437:                                 * or braces */
1.240     rillig   3438:     char        startc;        /* Starting character when variable in parens
1.108     sjg      3439:                                 * or braces */
1.240     rillig   3440:     int                 vlen;          /* Length of variable name */
                   3441:     const char         *start;         /* Points to original start of str */
                   3442:     char       *nstr;          /* New string, used during expansion */
                   3443:     Boolean     dynamic;       /* TRUE if the variable is local and we're
1.108     sjg      3444:                                 * expanding it in a non-local context. This
                   3445:                                 * is done to support dynamic sources. The
                   3446:                                 * result is just the invocation, unaltered */
1.240     rillig   3447:     const char *extramodifiers; /* extra modifiers to apply first */
                   3448:     char        name[2];
1.1       cgd      3449:
1.108     sjg      3450:     *freePtr = NULL;
1.191     dholland 3451:     extramodifiers = NULL;
1.108     sjg      3452:     dynamic = FALSE;
                   3453:     start = str;
1.1       cgd      3454:
1.141     dsl      3455:     startc = str[1];
                   3456:     if (startc != PROPEN && startc != BROPEN) {
1.108     sjg      3457:        /*
                   3458:         * If it's not bounded by braces of some sort, life is much simpler.
                   3459:         * We just need to check for the first character and return the
                   3460:         * value if it exists.
                   3461:         */
1.15      christos 3462:
1.141     dsl      3463:        /* Error out some really stupid names */
                   3464:        if (startc == '\0' || strchr(")}:$", startc)) {
                   3465:            *lengthPtr = 1;
                   3466:            return var_Error;
                   3467:        }
                   3468:        name[0] = startc;
1.108     sjg      3469:        name[1] = '\0';
1.16      christos 3470:
1.108     sjg      3471:        v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
1.136     dsl      3472:        if (v == NULL) {
1.108     sjg      3473:            *lengthPtr = 2;
1.1       cgd      3474:
1.108     sjg      3475:            if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
                   3476:                /*
                   3477:                 * If substituting a local variable in a non-local context,
                   3478:                 * assume it's for dynamic source stuff. We have to handle
                   3479:                 * this specially and return the longhand for the variable
                   3480:                 * with the dollar sign escaped so it makes it back to the
                   3481:                 * caller. Only four of the local variables are treated
                   3482:                 * specially as they are the only four that will be set
                   3483:                 * when dynamic sources are expanded.
                   3484:                 */
                   3485:                switch (str[1]) {
1.242     rillig   3486:                case '@':
                   3487:                    return UNCONST("$(.TARGET)");
                   3488:                case '%':
                   3489:                    return UNCONST("$(.MEMBER)");
                   3490:                case '*':
                   3491:                    return UNCONST("$(.PREFIX)");
                   3492:                case '!':
                   3493:                    return UNCONST("$(.ARCHIVE)");
1.108     sjg      3494:                }
                   3495:            }
1.259     rillig   3496:            return (flags & VARE_UNDEFERR) ? var_Error : varNoError;
1.108     sjg      3497:        } else {
                   3498:            haveModifier = FALSE;
                   3499:            tstr = &str[1];
                   3500:            endc = str[1];
                   3501:        }
1.123     apb      3502:     } else {
1.240     rillig   3503:        Buffer buf;             /* Holds the variable name */
1.185     sjg      3504:        int depth = 1;
1.1       cgd      3505:
1.108     sjg      3506:        endc = startc == PROPEN ? PRCLOSE : BRCLOSE;
1.146     dsl      3507:        Buf_Init(&buf, 0);
1.1       cgd      3508:
1.108     sjg      3509:        /*
                   3510:         * Skip to the end character or a colon, whichever comes first.
                   3511:         */
1.249     rillig   3512:        for (tstr = str + 2; *tstr != '\0'; tstr++) {
1.240     rillig   3513:            /* Track depth so we can spot parse errors. */
                   3514:            if (*tstr == startc)
1.185     sjg      3515:                depth++;
                   3516:            if (*tstr == endc) {
                   3517:                if (--depth == 0)
                   3518:                    break;
                   3519:            }
1.240     rillig   3520:            if (depth == 1 && *tstr == ':')
1.185     sjg      3521:                break;
1.240     rillig   3522:            /* A variable inside a variable, expand. */
1.108     sjg      3523:            if (*tstr == '$') {
1.127     christos 3524:                int rlen;
1.108     sjg      3525:                void *freeIt;
1.226     rillig   3526:                char *rval = Var_Parse(tstr, ctxt, flags, &rlen, &freeIt);
1.240     rillig   3527:                if (rval != NULL)
1.146     dsl      3528:                    Buf_AddBytes(&buf, strlen(rval), rval);
1.196     christos 3529:                free(freeIt);
1.108     sjg      3530:                tstr += rlen - 1;
1.242     rillig   3531:            } else
1.146     dsl      3532:                Buf_AddByte(&buf, *tstr);
1.108     sjg      3533:        }
                   3534:        if (*tstr == ':') {
                   3535:            haveModifier = TRUE;
1.185     sjg      3536:        } else if (*tstr == endc) {
1.108     sjg      3537:            haveModifier = FALSE;
                   3538:        } else {
                   3539:            /*
                   3540:             * If we never did find the end character, return NULL
                   3541:             * right now, setting the length to be the distance to
                   3542:             * the end of the string, since that's what make does.
                   3543:             */
                   3544:            *lengthPtr = tstr - str;
1.146     dsl      3545:            Buf_Destroy(&buf, TRUE);
1.231     rillig   3546:            return var_Error;
1.108     sjg      3547:        }
1.146     dsl      3548:        str = Buf_GetAll(&buf, &vlen);
1.93      sjg      3549:
1.123     apb      3550:        /*
                   3551:         * At this point, str points into newly allocated memory from
                   3552:         * buf, containing only the name of the variable.
                   3553:         *
                   3554:         * start and tstr point into the const string that was pointed
                   3555:         * to by the original value of the str parameter.  start points
                   3556:         * to the '$' at the beginning of the string, while tstr points
                   3557:         * to the char just after the end of the variable name -- this
                   3558:         * will be '\0', ':', PRCLOSE, or BRCLOSE.
                   3559:         */
                   3560:
1.108     sjg      3561:        v = VarFind(str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
1.141     dsl      3562:        /*
                   3563:         * Check also for bogus D and F forms of local variables since we're
                   3564:         * in a local context and the name is the right length.
                   3565:         */
1.136     dsl      3566:        if ((v == NULL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
1.141     dsl      3567:                (vlen == 2) && (str[1] == 'F' || str[1] == 'D') &&
1.190     dholland 3568:                strchr("@%?*!<>", str[0]) != NULL) {
1.108     sjg      3569:            /*
1.141     dsl      3570:             * Well, it's local -- go look for it.
1.108     sjg      3571:             */
1.141     dsl      3572:            name[0] = *str;
                   3573:            name[1] = '\0';
                   3574:            v = VarFind(name, ctxt, 0);
1.15      christos 3575:
1.141     dsl      3576:            if (v != NULL) {
                   3577:                if (str[1] == 'D') {
1.240     rillig   3578:                    extramodifiers = "H:";
1.242     rillig   3579:                } else { /* F */
1.240     rillig   3580:                    extramodifiers = "T:";
1.1       cgd      3581:                }
                   3582:            }
1.108     sjg      3583:        }
                   3584:
1.136     dsl      3585:        if (v == NULL) {
1.108     sjg      3586:            if (((vlen == 1) ||
1.141     dsl      3587:                 (((vlen == 2) && (str[1] == 'F' || str[1] == 'D')))) &&
1.108     sjg      3588:                ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
                   3589:            {
                   3590:                /*
                   3591:                 * If substituting a local variable in a non-local context,
                   3592:                 * assume it's for dynamic source stuff. We have to handle
                   3593:                 * this specially and return the longhand for the variable
                   3594:                 * with the dollar sign escaped so it makes it back to the
                   3595:                 * caller. Only four of the local variables are treated
                   3596:                 * specially as they are the only four that will be set
                   3597:                 * when dynamic sources are expanded.
                   3598:                 */
                   3599:                switch (*str) {
1.242     rillig   3600:                case '@':
                   3601:                case '%':
                   3602:                case '*':
                   3603:                case '!':
                   3604:                    dynamic = TRUE;
                   3605:                    break;
1.108     sjg      3606:                }
1.240     rillig   3607:            } else if (vlen > 2 && *str == '.' &&
1.108     sjg      3608:                       isupper((unsigned char) str[1]) &&
1.240     rillig   3609:                       (ctxt == VAR_CMD || ctxt == VAR_GLOBAL))
1.108     sjg      3610:            {
1.240     rillig   3611:                int len = vlen - 1;
1.108     sjg      3612:                if ((strncmp(str, ".TARGET", len) == 0) ||
                   3613:                    (strncmp(str, ".ARCHIVE", len) == 0) ||
                   3614:                    (strncmp(str, ".PREFIX", len) == 0) ||
                   3615:                    (strncmp(str, ".MEMBER", len) == 0))
                   3616:                {
                   3617:                    dynamic = TRUE;
                   3618:                }
1.1       cgd      3619:            }
1.15      christos 3620:
1.108     sjg      3621:            if (!haveModifier) {
                   3622:                /*
                   3623:                 * No modifiers -- have specification length so we can return
                   3624:                 * now.
                   3625:                 */
                   3626:                *lengthPtr = tstr - start + 1;
                   3627:                if (dynamic) {
1.134     joerg    3628:                    char *pstr = bmake_strndup(start, *lengthPtr);
1.108     sjg      3629:                    *freePtr = pstr;
1.146     dsl      3630:                    Buf_Destroy(&buf, TRUE);
1.231     rillig   3631:                    return pstr;
1.40      sjg      3632:                } else {
1.146     dsl      3633:                    Buf_Destroy(&buf, TRUE);
1.259     rillig   3634:                    return (flags & VARE_UNDEFERR) ? var_Error : varNoError;
1.40      sjg      3635:                }
1.1       cgd      3636:            } else {
1.108     sjg      3637:                /*
                   3638:                 * Still need to get to the end of the variable specification,
                   3639:                 * so kludge up a Var structure for the modifications
                   3640:                 */
1.134     joerg    3641:                v = bmake_malloc(sizeof(Var));
1.108     sjg      3642:                v->name = UNCONST(str);
1.146     dsl      3643:                Buf_Init(&v->val, 1);
1.108     sjg      3644:                v->flags = VAR_JUNK;
1.146     dsl      3645:                Buf_Destroy(&buf, FALSE);
1.1       cgd      3646:            }
1.108     sjg      3647:        } else
1.146     dsl      3648:            Buf_Destroy(&buf, TRUE);
1.108     sjg      3649:     }
                   3650:
1.188     joerg    3651:     if (v->flags & VAR_IN_USE) {
                   3652:        Fatal("Variable %s is recursive.", v->name);
                   3653:        /*NOTREACHED*/
                   3654:     } else {
                   3655:        v->flags |= VAR_IN_USE;
                   3656:     }
                   3657:     /*
                   3658:      * Before doing any modification, we have to make sure the value
                   3659:      * has been fully expanded. If it looks like recursion might be
                   3660:      * necessary (there's a dollar sign somewhere in the variable's value)
                   3661:      * we just call Var_Subst to do any other substitutions that are
                   3662:      * necessary. Note that the value returned by Var_Subst will have
                   3663:      * been dynamically-allocated, so it will need freeing when we
                   3664:      * return.
                   3665:      */
                   3666:     nstr = Buf_GetAll(&v->val, NULL);
1.259     rillig   3667:     if (strchr(nstr, '$') != NULL && (flags & VARE_WANTRES) != 0) {
1.202     christos 3668:        nstr = Var_Subst(NULL, nstr, ctxt, flags);
1.188     joerg    3669:        *freePtr = nstr;
                   3670:     }
1.187     christos 3671:
1.188     joerg    3672:     v->flags &= ~VAR_IN_USE;
1.108     sjg      3673:
1.240     rillig   3674:     if (nstr != NULL && (haveModifier || extramodifiers != NULL)) {
1.191     dholland 3675:        void *extraFree;
1.127     christos 3676:        int used;
1.108     sjg      3677:
1.191     dholland 3678:        extraFree = NULL;
                   3679:        if (extramodifiers != NULL) {
1.240     rillig   3680:            nstr = ApplyModifiers(nstr, extramodifiers, '(', ')',
                   3681:                                  v, ctxt, flags, &used, &extraFree);
1.191     dholland 3682:        }
                   3683:
                   3684:        if (haveModifier) {
1.240     rillig   3685:            /* Skip initial colon. */
                   3686:            tstr++;
1.191     dholland 3687:
1.240     rillig   3688:            nstr = ApplyModifiers(nstr, tstr, startc, endc,
                   3689:                                  v, ctxt, flags, &used, freePtr);
                   3690:            tstr += used;
                   3691:            free(extraFree);
1.191     dholland 3692:        } else {
1.240     rillig   3693:            *freePtr = extraFree;
1.191     dholland 3694:        }
1.119     sjg      3695:     }
1.240     rillig   3696:     *lengthPtr = tstr - start + (*tstr ? 1 : 0);
1.15      christos 3697:
1.1       cgd      3698:     if (v->flags & VAR_FROM_ENV) {
1.249     rillig   3699:        Boolean destroy = FALSE;
1.15      christos 3700:
1.146     dsl      3701:        if (nstr != Buf_GetAll(&v->val, NULL)) {
1.1       cgd      3702:            destroy = TRUE;
                   3703:        } else {
                   3704:            /*
                   3705:             * Returning the value unmodified, so tell the caller to free
                   3706:             * the thing.
                   3707:             */
1.104     christos 3708:            *freePtr = nstr;
1.1       cgd      3709:        }
1.105     christos 3710:        VarFreeEnv(v, destroy);
1.1       cgd      3711:     } else if (v->flags & VAR_JUNK) {
                   3712:        /*
1.121     apb      3713:         * Perform any free'ing needed and set *freePtr to NULL so the caller
1.1       cgd      3714:         * doesn't try to free a static pointer.
1.40      sjg      3715:         * If VAR_KEEP is also set then we want to keep str as is.
1.1       cgd      3716:         */
1.58      itojun   3717:        if (!(v->flags & VAR_KEEP)) {
1.40      sjg      3718:            if (*freePtr) {
1.73      christos 3719:                free(nstr);
1.108     sjg      3720:                *freePtr = NULL;
1.40      sjg      3721:            }
                   3722:            if (dynamic) {
1.134     joerg    3723:                nstr = bmake_strndup(start, *lengthPtr);
1.104     christos 3724:                *freePtr = nstr;
1.40      sjg      3725:            } else {
1.259     rillig   3726:                nstr = (flags & VARE_UNDEFERR) ? var_Error : varNoError;
1.40      sjg      3727:            }
1.34      christos 3728:        }
1.146     dsl      3729:        if (nstr != Buf_GetAll(&v->val, NULL))
                   3730:            Buf_Destroy(&v->val, TRUE);
1.98      christos 3731:        free(v->name);
                   3732:        free(v);
1.1       cgd      3733:     }
1.231     rillig   3734:     return nstr;
1.1       cgd      3735: }
                   3736:
                   3737: /*-
                   3738:  *-----------------------------------------------------------------------
                   3739:  * Var_Subst  --
1.250     rillig   3740:  *     Substitute for all variables in the given string in the given context.
1.259     rillig   3741:  *     If flags & VARE_UNDEFERR, Parse_Error will be called when an undefined
1.1       cgd      3742:  *     variable is encountered.
                   3743:  *
1.70      wiz      3744:  * Input:
                   3745:  *     var             Named variable || NULL for all
                   3746:  *     str             the string which to substitute
                   3747:  *     ctxt            the context wherein to find variables
1.259     rillig   3748:  *     flags           VARE_UNDEFERR   if undefineds are an error
                   3749:  *                     VARE_WANTRES    if we actually want the result
                   3750:  *                     VARE_ASSIGN     if we are in a := assignment
1.70      wiz      3751:  *
1.1       cgd      3752:  * Results:
                   3753:  *     The resulting string.
                   3754:  *
                   3755:  * Side Effects:
1.250     rillig   3756:  *     None.
1.1       cgd      3757:  *-----------------------------------------------------------------------
                   3758:  */
                   3759: char *
1.259     rillig   3760: Var_Subst(const char *var, const char *str, GNode *ctxt, VarEvalFlags flags)
1.1       cgd      3761: {
1.240     rillig   3762:     Buffer     buf;            /* Buffer for forming things */
                   3763:     char       *val;           /* Value to substitute for a variable */
                   3764:     int                length;         /* Length of the variable invocation */
                   3765:     Boolean    trailingBslash; /* variable ends in \ */
                   3766:     void       *freeIt = NULL; /* Set if it should be freed */
                   3767:     static Boolean errorReported; /* Set true if an error has already
                   3768:                                 * been reported to prevent a plethora
                   3769:                                 * of messages when recursing */
1.1       cgd      3770:
1.146     dsl      3771:     Buf_Init(&buf, 0);
1.1       cgd      3772:     errorReported = FALSE;
1.96      christos 3773:     trailingBslash = FALSE;
1.1       cgd      3774:
                   3775:     while (*str) {
1.96      christos 3776:        if (*str == '\n' && trailingBslash)
1.146     dsl      3777:            Buf_AddByte(&buf, ' ');
1.48      mycroft  3778:        if (var == NULL && (*str == '$') && (str[1] == '$')) {
1.1       cgd      3779:            /*
                   3780:             * A dollar sign may be escaped either with another dollar sign.
                   3781:             * In such a case, we skip over the escape character and store the
                   3782:             * dollar sign into the buffer directly.
                   3783:             */
1.259     rillig   3784:            if (save_dollars && (flags & VARE_ASSIGN))
1.201     christos 3785:                Buf_AddByte(&buf, *str);
1.1       cgd      3786:            str++;
1.146     dsl      3787:            Buf_AddByte(&buf, *str);
1.1       cgd      3788:            str++;
                   3789:        } else if (*str != '$') {
                   3790:            /*
                   3791:             * Skip as many characters as possible -- either to the end of
                   3792:             * the string or to the next dollar sign (variable invocation).
                   3793:             */
1.249     rillig   3794:            const char *cp;
1.1       cgd      3795:
1.5       cgd      3796:            for (cp = str++; *str != '$' && *str != '\0'; str++)
                   3797:                continue;
1.146     dsl      3798:            Buf_AddBytes(&buf, str - cp, cp);
1.1       cgd      3799:        } else {
1.48      mycroft  3800:            if (var != NULL) {
                   3801:                int expand;
                   3802:                for (;;) {
1.100     christos 3803:                    if (str[1] == '\0') {
                   3804:                        /* A trailing $ is kind of a special case */
1.146     dsl      3805:                        Buf_AddByte(&buf, str[0]);
1.100     christos 3806:                        str++;
                   3807:                        expand = FALSE;
                   3808:                    } else if (str[1] != PROPEN && str[1] != BROPEN) {
1.48      mycroft  3809:                        if (str[1] != *var || strlen(var) > 1) {
1.146     dsl      3810:                            Buf_AddBytes(&buf, 2, str);
1.48      mycroft  3811:                            str += 2;
                   3812:                            expand = FALSE;
1.242     rillig   3813:                        } else
1.48      mycroft  3814:                            expand = TRUE;
                   3815:                        break;
1.240     rillig   3816:                    } else {
1.73      christos 3817:                        const char *p;
1.48      mycroft  3818:
1.242     rillig   3819:                        /* Scan up to the end of the variable name. */
1.48      mycroft  3820:                        for (p = &str[2]; *p &&
1.100     christos 3821:                             *p != ':' && *p != PRCLOSE && *p != BRCLOSE; p++)
1.48      mycroft  3822:                            if (*p == '$')
                   3823:                                break;
                   3824:                        /*
                   3825:                         * A variable inside the variable. We cannot expand
                   3826:                         * the external variable yet, so we try again with
                   3827:                         * the nested one
                   3828:                         */
                   3829:                        if (*p == '$') {
1.146     dsl      3830:                            Buf_AddBytes(&buf, p - str, str);
1.48      mycroft  3831:                            str = p;
                   3832:                            continue;
                   3833:                        }
                   3834:
1.127     christos 3835:                        if (strncmp(var, str + 2, p - str - 2) != 0 ||
1.48      mycroft  3836:                            var[p - str - 2] != '\0') {
                   3837:                            /*
                   3838:                             * Not the variable we want to expand, scan
                   3839:                             * until the next variable
                   3840:                             */
1.249     rillig   3841:                            for (; *p != '$' && *p != '\0'; p++)
1.48      mycroft  3842:                                continue;
1.146     dsl      3843:                            Buf_AddBytes(&buf, p - str, str);
1.48      mycroft  3844:                            str = p;
                   3845:                            expand = FALSE;
1.240     rillig   3846:                        } else
1.48      mycroft  3847:                            expand = TRUE;
                   3848:                        break;
                   3849:                    }
                   3850:                }
                   3851:                if (!expand)
                   3852:                    continue;
                   3853:            }
                   3854:
1.202     christos 3855:            val = Var_Parse(str, ctxt, flags, &length, &freeIt);
1.1       cgd      3856:
                   3857:            /*
                   3858:             * When we come down here, val should either point to the
                   3859:             * value of this variable, suitably modified, or be NULL.
                   3860:             * Length should be the total length of the potential
                   3861:             * variable invocation (from $ to end character...)
                   3862:             */
                   3863:            if (val == var_Error || val == varNoError) {
                   3864:                /*
                   3865:                 * If performing old-time variable substitution, skip over
                   3866:                 * the variable and continue with the substitution. Otherwise,
                   3867:                 * store the dollar sign and advance str so we continue with
                   3868:                 * the string...
                   3869:                 */
                   3870:                if (oldVars) {
                   3871:                    str += length;
1.259     rillig   3872:                } else if ((flags & VARE_UNDEFERR) || val == var_Error) {
1.1       cgd      3873:                    /*
                   3874:                     * If variable is undefined, complain and skip the
                   3875:                     * variable. The complaint will stop us from doing anything
                   3876:                     * when the file is parsed.
                   3877:                     */
                   3878:                    if (!errorReported) {
1.231     rillig   3879:                        Parse_Error(PARSE_FATAL, "Undefined variable \"%.*s\"",
                   3880:                                    length, str);
1.1       cgd      3881:                    }
                   3882:                    str += length;
                   3883:                    errorReported = TRUE;
                   3884:                } else {
1.146     dsl      3885:                    Buf_AddByte(&buf, *str);
1.1       cgd      3886:                    str += 1;
                   3887:                }
                   3888:            } else {
                   3889:                /*
                   3890:                 * We've now got a variable structure to store in. But first,
                   3891:                 * advance the string pointer.
                   3892:                 */
                   3893:                str += length;
1.15      christos 3894:
1.1       cgd      3895:                /*
                   3896:                 * Copy all the characters from the variable value straight
                   3897:                 * into the new string.
                   3898:                 */
1.96      christos 3899:                length = strlen(val);
1.146     dsl      3900:                Buf_AddBytes(&buf, length, val);
1.96      christos 3901:                trailingBslash = length > 0 && val[length - 1] == '\\';
1.104     christos 3902:            }
1.196     christos 3903:            free(freeIt);
                   3904:            freeIt = NULL;
1.1       cgd      3905:        }
                   3906:     }
1.15      christos 3907:
1.168     sjg      3908:     return Buf_DestroyCompact(&buf);
1.1       cgd      3909: }
                   3910:
1.250     rillig   3911: /* Initialize the module. */
1.1       cgd      3912: void
1.70      wiz      3913: Var_Init(void)
1.1       cgd      3914: {
1.184     sjg      3915:     VAR_INTERNAL = Targ_NewGN("Internal");
1.92      christos 3916:     VAR_GLOBAL = Targ_NewGN("Global");
                   3917:     VAR_CMD = Targ_NewGN("Command");
1.6       jtc      3918: }
                   3919:
1.1       cgd      3920:
1.6       jtc      3921: void
1.70      wiz      3922: Var_End(void)
1.6       jtc      3923: {
1.286     sjg      3924:     Var_Stats();
                   3925: }
                   3926:
                   3927: void
                   3928: Var_Stats(void)
                   3929: {
                   3930:     Hash_DebugStats(&VAR_GLOBAL->context, "VAR_GLOBAL");
1.1       cgd      3931: }
1.15      christos 3932:
1.1       cgd      3933:
                   3934: /****************** PRINT DEBUGGING INFO *****************/
1.36      mycroft  3935: static void
1.241     rillig   3936: VarPrintVar(void *vp, void *data MAKE_ATTR_UNUSED)
1.1       cgd      3937: {
1.242     rillig   3938:     Var *v = (Var *)vp;
1.146     dsl      3939:     fprintf(debug_file, "%-16s = %s\n", v->name, Buf_GetAll(&v->val, NULL));
1.1       cgd      3940: }
                   3941:
                   3942: /*-
                   3943:  *-----------------------------------------------------------------------
                   3944:  * Var_Dump --
                   3945:  *     print all variables in a context
                   3946:  *-----------------------------------------------------------------------
                   3947:  */
1.5       cgd      3948: void
1.70      wiz      3949: Var_Dump(GNode *ctxt)
1.1       cgd      3950: {
1.241     rillig   3951:     Hash_ForEach(&ctxt->context, VarPrintVar, NULL);
1.1       cgd      3952: }

CVSweb <webmaster@jp.NetBSD.org>