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

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

1.48    ! espie       1: /*     $OpenBSD: var.c,v 1.47 2000/08/21 10:44:21 espie Exp $  */
1.6       millert     2: /*     $NetBSD: var.c,v 1.18 1997/03/18 19:24:46 christos Exp $        */
1.1       deraadt     3:
                      4: /*
1.17      espie       5:  * Copyright (c) 1999 Marc Espie.
                      6:  *
                      7:  * Extensive code modifications for the OpenBSD project.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  *
                     18:  * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
                     19:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
                     20:  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
                     21:  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OPENBSD
                     22:  * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
                     23:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
                     24:  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     25:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     26:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     27:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
                     28:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     29:  */
                     30:
                     31: /*
1.5       millert    32:  * Copyright (c) 1988, 1989, 1990, 1993
                     33:  *     The Regents of the University of California.  All rights reserved.
1.1       deraadt    34:  * Copyright (c) 1989 by Berkeley Softworks
                     35:  * All rights reserved.
                     36:  *
                     37:  * This code is derived from software contributed to Berkeley by
                     38:  * Adam de Boor.
                     39:  *
                     40:  * Redistribution and use in source and binary forms, with or without
                     41:  * modification, are permitted provided that the following conditions
                     42:  * are met:
                     43:  * 1. Redistributions of source code must retain the above copyright
                     44:  *    notice, this list of conditions and the following disclaimer.
                     45:  * 2. Redistributions in binary form must reproduce the above copyright
                     46:  *    notice, this list of conditions and the following disclaimer in the
                     47:  *    documentation and/or other materials provided with the distribution.
                     48:  * 3. All advertising materials mentioning features or use of this software
                     49:  *    must display the following acknowledgement:
                     50:  *     This product includes software developed by the University of
                     51:  *     California, Berkeley and its contributors.
                     52:  * 4. Neither the name of the University nor the names of its contributors
                     53:  *    may be used to endorse or promote products derived from this software
                     54:  *    without specific prior written permission.
                     55:  *
                     56:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     57:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     58:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     59:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     60:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     61:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     62:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     63:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     64:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     65:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     66:  * SUCH DAMAGE.
                     67:  */
                     68:
                     69: /*-
                     70:  * var.c --
                     71:  *     Variable-handling functions
                     72:  *
                     73:  * Interface:
                     74:  *     Var_Set             Set the value of a variable in the given
                     75:  *                         context. The variable is created if it doesn't
                     76:  *                         yet exist. The value and variable name need not
                     77:  *                         be preserved.
                     78:  *
                     79:  *     Var_Append          Append more characters to an existing variable
                     80:  *                         in the given context. The variable needn't
                     81:  *                         exist already -- it will be created if it doesn't.
                     82:  *                         A space is placed between the old value and the
                     83:  *                         new one.
                     84:  *
                     85:  *     Var_Exists          See if a variable exists.
                     86:  *
                     87:  *     Var_Value           Return the value of a variable in a context or
                     88:  *                         NULL if the variable is undefined.
                     89:  *
                     90:  *     Var_Subst           Substitute named variable, or all variables if
                     91:  *                         NULL in a string using
                     92:  *                         the given context as the top-most one. If the
                     93:  *                         third argument is non-zero, Parse_Error is
                     94:  *                         called if any variables are undefined.
                     95:  *
                     96:  *     Var_Parse           Parse a variable expansion from a string and
                     97:  *                         return the result and the number of characters
                     98:  *                         consumed.
                     99:  *
                    100:  *     Var_Delete          Delete a variable in a context.
                    101:  *
                    102:  *     Var_Init            Initialize this module.
                    103:  *
                    104:  * Debugging:
                    105:  *     Var_Dump            Print out all variables defined in the given
                    106:  *                         context.
                    107:  *
                    108:  * XXX: There's a lot of duplication in these functions.
                    109:  */
                    110:
                    111: #include    <ctype.h>
1.6       millert   112: #ifndef MAKE_BOOTSTRAP
1.9       deraadt   113: #include    <sys/types.h>
1.6       millert   114: #include    <regex.h>
                    115: #endif
                    116: #include    <stdlib.h>
1.35      espie     117: #include    <stddef.h>
1.1       deraadt   118: #include    "make.h"
                    119: #include    "buf.h"
1.38      espie     120: #include    "ohash.h"
                    121: #include    "hashconsts.h"
1.43      espie     122: #include    "varmodifiers.h"
1.34      espie     123:
1.48    ! espie     124: #ifndef lint
        !           125: #if 0
        !           126: static char sccsid[] = "@(#)var.c      8.3 (Berkeley) 3/19/94";
        !           127: #else
        !           128: UNUSED
        !           129: static char rcsid[] = "$OpenBSD: var.c,v 1.45 2000/07/17 23:29:35 espie Exp $";
        !           130: #endif
        !           131: #endif /* not lint */
        !           132:
1.37      espie     133: static SymTable *CTXT_GLOBAL, *CTXT_CMD, *CTXT_ENV;
                    134:
1.34      espie     135: static char *varnames[] = {
                    136:     TARGET,
                    137:     OODATE,
                    138:     ALLSRC,
                    139:     IMPSRC,
                    140:     PREFIX,
                    141:     ARCHIVE,
                    142:     MEMBER };
                    143:
1.1       deraadt   144: /*
                    145:  * This is a harmless return value for Var_Parse that can be used by Var_Subst
                    146:  * to determine if there was an error in parsing -- easier than returning
                    147:  * a flag, as things outside this module don't give a hoot.
                    148:  */
                    149: char   var_Error[] = "";
                    150:
                    151: /*
                    152:  * Similar to var_Error, but returned when the 'err' flag for Var_Parse is
                    153:  * set false. Why not just use a constant? Well, gcc likes to condense
                    154:  * identical string instances...
                    155:  */
                    156: static char    varNoError[] = "";
                    157:
                    158: /*
                    159:  * Internally, variables are contained in four different contexts.
                    160:  *     1) the environment. They may not be changed. If an environment
                    161:  *         variable is appended-to, the result is placed in the global
                    162:  *         context.
                    163:  *     2) the global context. Variables set in the Makefile are located in
                    164:  *         the global context. It is the penultimate context searched when
                    165:  *         substituting.
                    166:  *     3) the command-line context. All variables set on the command line
                    167:  *        are placed in this context. They are UNALTERABLE once placed here.
                    168:  *     4) the local context. Each target has associated with it a context
                    169:  *        list. On this list are located the structures describing such
                    170:  *        local variables as $(@) and $(*)
                    171:  * The four contexts are searched in the reverse order from which they are
                    172:  * listed.
                    173:  */
1.37      espie     174: GSymT          *VAR_GLOBAL;    /* variables from the makefile */
                    175: GSymT          *VAR_CMD;       /* variables defined on the command-line */
                    176: static GSymT   *VAR_ENV;       /* variables read from env */
1.1       deraadt   177:
1.39      espie     178: #define FIND_MINE      0x1   /* look in CTXT_CMD and CTXT_GLOBAL */
                    179: #define FIND_ENV       0x2   /* look in the environment */
1.1       deraadt   180:
1.37      espie     181: typedef struct Var_ {
1.23      espie     182:     BUFFER       val;          /* its value */
1.1       deraadt   183:     int                  flags;        /* miscellaneous status flags */
                    184: #define VAR_IN_USE     1           /* Variable's value currently being used.
                    185:                                     * Used to avoid recursion */
                    186: #define VAR_JUNK       4           /* Variable is a junk variable that
                    187:                                     * should be destroyed when done with
                    188:                                     * it. Used by Var_Parse for undefined,
                    189:                                     * modified variables */
1.38      espie     190:     char          name[1];     /* the variable's name */
1.1       deraadt   191: }  Var;
                    192:
1.38      espie     193: static struct hash_info var_info = {
                    194:        offsetof(Var, name),
                    195:     NULL, hash_alloc, hash_free, element_alloc };
                    196: static int quick_lookup __P((const char *, const char **, u_int32_t *));
1.23      espie     197: #define VarValue(v)    Buf_Retrieve(&((v)->val))
1.39      espie     198: static Var *varfind __P((const char *, const char *, SymTable *, int, int, u_int32_t));
                    199: static Var *VarFind_interval __P((const char *, const char *, SymTable *, int));
                    200: #define VarFind(n, ctxt, flags)        VarFind_interval(n, NULL, ctxt, flags)
                    201: static Var *VarAdd __P((const char *, const char *, GSymT *));
1.32      espie     202: static void VarDelete __P((void *));
                    203: static void VarPrintVar __P((void *));
1.38      espie     204: static const char *context_name __P((GSymT *));
1.39      espie     205: static Var *new_var __P((const char *, const char *));
                    206: static Var *getvar __P((GSymT *, const char *, const char *, u_int32_t));
1.45      espie     207: static Var *var_name_with_dollar __P((char *, char **, SymTable *, Boolean, char));
1.37      espie     208:
                    209: void
                    210: SymTable_Init(ctxt)
                    211:     SymTable   *ctxt;
                    212: {
                    213:     static SymTable sym_template;
                    214:     memcpy(ctxt, &sym_template, sizeof(*ctxt));
                    215: }
                    216:
                    217: void
                    218: SymTable_Destroy(ctxt)
                    219:     SymTable   *ctxt;
                    220: {
                    221:     int i;
                    222:
                    223:     for (i = 0; i < LOCAL_SIZE; i++)
                    224:        if (ctxt->locals[i] != NULL)
                    225:            VarDelete(ctxt->locals[i]);
                    226: }
                    227:
1.38      espie     228: static int
                    229: quick_lookup(name, end, pk)
                    230:     const char *name;
                    231:     const char **end;
                    232:     u_int32_t *pk;
                    233: {
                    234:     size_t len;
                    235:
                    236:     *pk = hash_interval(name, end);
                    237:     len = *end - name;
                    238:        /* substitute short version for long local name */
                    239:     switch (*pk % MAGICSLOTS) {                    /* MAGICSLOTS should be the    */
                    240:     case K_LONGALLSRC % MAGICSLOTS:        /* smallest constant yielding  */
                    241:                                            /* distinct case values        */
                    242:        if (*pk == K_LONGALLSRC && strncmp(name, LONGALLSRC, len) == 0 &&
                    243:            len == strlen(LONGALLSRC))
                    244:            return ALLSRC_INDEX;
                    245:        break;
                    246:     case K_LONGARCHIVE % MAGICSLOTS:
                    247:        if (*pk == K_LONGARCHIVE && strncmp(name, LONGARCHIVE, len) == 0 &&
                    248:            len == strlen(LONGARCHIVE))
                    249:            return ARCHIVE_INDEX;
                    250:        break;
                    251:     case K_LONGIMPSRC % MAGICSLOTS:
                    252:        if (*pk == K_LONGIMPSRC && strncmp(name, LONGIMPSRC, len) == 0 &&
                    253:            len == strlen(LONGIMPSRC))
                    254:            return IMPSRC_INDEX;
                    255:        break;
                    256:     case K_LONGMEMBER % MAGICSLOTS:
                    257:        if (*pk == K_LONGMEMBER && strncmp(name, LONGMEMBER, len) == 0 &&
                    258:            len == strlen(LONGMEMBER))
                    259:            return MEMBER_INDEX;
                    260:        break;
                    261:     case K_LONGOODATE % MAGICSLOTS:
                    262:        if (*pk == K_LONGOODATE && strncmp(name, LONGOODATE, len) == 0 &&
                    263:            len == strlen(LONGOODATE))
                    264:            return OODATE_INDEX;
                    265:        break;
                    266:     case K_LONGPREFIX % MAGICSLOTS:
                    267:        if (*pk == K_LONGPREFIX && strncmp(name, LONGPREFIX, len) == 0 &&
                    268:            len == strlen(LONGPREFIX))
                    269:            return PREFIX_INDEX;
                    270:        break;
                    271:     case K_LONGTARGET % MAGICSLOTS:
                    272:        if (*pk == K_LONGTARGET && strncmp(name, LONGTARGET, len) == 0 &&
                    273:            len == strlen(LONGTARGET))
                    274:            return TARGET_INDEX;
                    275:        break;
                    276:     case K_TARGET % MAGICSLOTS:
                    277:        if (name[0] == TARGET[0] && len == 1)
                    278:            return TARGET_INDEX;
                    279:        break;
                    280:     case K_OODATE % MAGICSLOTS:
                    281:        if (name[0] == OODATE[0] && len == 1)
                    282:            return OODATE_INDEX;
                    283:        break;
                    284:     case K_ALLSRC % MAGICSLOTS:
                    285:        if (name[0] == ALLSRC[0] && len == 1)
                    286:            return ALLSRC_INDEX;
                    287:        break;
                    288:     case K_IMPSRC % MAGICSLOTS:
                    289:        if (name[0] == IMPSRC[0] && len == 1)
                    290:            return IMPSRC_INDEX;
                    291:        break;
                    292:     case K_PREFIX % MAGICSLOTS:
                    293:        if (name[0] == PREFIX[0] && len == 1)
                    294:            return PREFIX_INDEX;
                    295:        break;
                    296:     case K_ARCHIVE % MAGICSLOTS:
                    297:        if (name[0] == ARCHIVE[0] && len == 1)
                    298:            return ARCHIVE_INDEX;
                    299:        break;
                    300:     case K_MEMBER % MAGICSLOTS:
                    301:        if (name[0] == MEMBER[0] && len == 1)
                    302:            return MEMBER_INDEX;
                    303:        break;
                    304:     default:
                    305:        break;
                    306:     }
                    307:     return -1;
                    308: }
1.37      espie     309:
                    310: void
                    311: Varq_Set(idx, val, gn)
                    312:     int        idx;
1.48    ! espie     313:     const char         *val;
1.37      espie     314:     GNode      *gn;
                    315: {
1.38      espie     316:     /* We only look for a variable in the given context since anything set
                    317:      * here will override anything in a lower context, so there's not much
                    318:      * point in searching them all just to save a bit of memory...  */
1.37      espie     319:     Var *v = gn->context.locals[idx];
                    320:
                    321:     if (v == NULL) {
                    322:        v = new_var(varnames[idx], val);
                    323:        v->flags = 0;
                    324:        gn->context.locals[idx] = v;
                    325:     } else {
                    326:        Buf_Reset(&(v->val));
                    327:        Buf_AddString(&(v->val), val);
                    328:     }
                    329:     if (DEBUG(VAR))
                    330:        printf("%s:%s = %s\n", gn->name, varnames[idx], val);
                    331: }
                    332:
                    333: void
                    334: Varq_Append(idx, val, gn)
                    335:     int                idx;
1.48    ! espie     336:     const char *val;
1.37      espie     337:     GNode      *gn;
                    338: {
1.48    ! espie     339:     Var        *v = gn->context.locals[idx];
1.37      espie     340:
                    341:     if (v == NULL) {
                    342:        v = new_var(varnames[idx], val);
                    343:        v->flags = 0;
                    344:        gn->context.locals[idx] = v;
                    345:     } else {
                    346:        Buf_AddSpace(&(v->val));
                    347:        Buf_AddString(&(v->val), val);
                    348:     }
                    349:     if (DEBUG(VAR))
                    350:        printf("%s:%s = %s\n", gn->name, varnames[idx], VarValue(v));
                    351: }
                    352:
                    353: char *
                    354: Varq_Value(idx, gn)
                    355:     int                idx;
                    356:     GNode      *gn;
                    357: {
                    358:     Var *v = gn->context.locals[idx];
                    359:
                    360:     if (v != NULL)
                    361:        return VarValue(v);
                    362:     else
                    363:        return NULL;
                    364: }
                    365:
                    366: Boolean
                    367: Varq_Exists(idx, gn)
                    368:     int                idx;
                    369:     GNode      *gn;
                    370: {
                    371:     return gn->context.locals[idx] != NULL;
                    372: }
1.1       deraadt   373:
1.35      espie     374:
1.38      espie     375: static const char *
1.35      espie     376: context_name(ctxt)
1.37      espie     377:     GSymT *ctxt;
1.35      espie     378: {
                    379:     if (ctxt == VAR_GLOBAL)
                    380:        return "Global";
1.37      espie     381:     else if (ctxt == VAR_CMD)
1.35      espie     382:        return "Command";
1.37      espie     383:     else
1.35      espie     384:        return "Environment";
                    385: }
                    386:
1.37      espie     387: /* Create a variable, to pass to VarAdd.  */
                    388: static Var *
                    389: new_var(name, val)
1.39      espie     390:     const char *name;
                    391:     const char *val;
1.37      espie     392: {
                    393:     Var *v;
1.38      espie     394:     const char *end = NULL;
1.37      espie     395:
1.38      espie     396:     v = hash_create_entry(&var_info, name, &end);
1.37      espie     397:
                    398:     if (val != NULL) {
                    399:        size_t len = strlen(val);
                    400:        Buf_Init(&(v->val), len+1);
                    401:        Buf_AddChars(&(v->val), len, val);
                    402:     } else
                    403:        Buf_Init(&(v->val), 1);
                    404:
                    405:     return v;
                    406: }
                    407:
1.38      espie     408: static Var *
                    409: getvar(ctxt, name, end, k)
                    410:     GSymT      *ctxt;
1.39      espie     411:     const char         *name;
1.38      espie     412:     const char *end;
                    413:     u_int32_t  k;
1.1       deraadt   414: {
1.38      espie     415:     return hash_find(ctxt, hash_lookup_interval(ctxt, name, end, k));
1.37      espie     416: }
                    417:
1.1       deraadt   418: /*-
                    419:  *-----------------------------------------------------------------------
1.39      espie     420:  * VarFind_interval --
1.1       deraadt   421:  *     Find the given variable in the given context and any other contexts
1.39      espie     422:  *     indicated.  if end is NULL, name is a string, otherwise, only
                    423:  *      the interval name - end  is concerned.
1.1       deraadt   424:  *
                    425:  * Results:
                    426:  *     A pointer to the structure describing the desired variable or
1.26      espie     427:  *     NULL if the variable does not exist.
1.1       deraadt   428:  *
                    429:  * Side Effects:
1.17      espie     430:  *     Caches env variables in the VAR_ENV context.
1.1       deraadt   431:  *-----------------------------------------------------------------------
                    432:  */
                    433: static Var *
1.39      espie     434: VarFind_interval(name, end, ctxt, flags)
                    435:     const char          *name; /* name to find */
                    436:     const char         *end;   /* end of name */
1.35      espie     437:     SymTable           *ctxt;  /* context in which to find it */
1.39      espie     438:     int                flags;  /* FIND_MINE set means to look in the
                    439:                                 * CTXT_GLOBAL and CTXT_CMD contexts also.
1.1       deraadt   440:                                 * FIND_ENV set means to look in the
1.39      espie     441:                                 * environment */
1.1       deraadt   442: {
1.38      espie     443:     int                idx;
                    444:     u_int32_t          k;
                    445:
                    446:     idx = quick_lookup(name, &end, &k);
1.39      espie     447:     return varfind(name, end, ctxt, flags, idx, k);
                    448: }
                    449:
                    450: static Var *
                    451: varfind(name, end, ctxt, flags, idx, k)
                    452:     const char         *name;
                    453:     const char         *end;
                    454:     SymTable           *ctxt;
                    455:     int                        flags;
                    456:     int                        idx;
                    457:     u_int32_t          k;
                    458: {
                    459:     Var                        *v;
1.1       deraadt   460:
                    461:     /*
                    462:      * First look for the variable in the given context. If it's not there,
                    463:      * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order,
                    464:      * depending on the FIND_* flags in 'flags'
                    465:      */
1.37      espie     466:     if (ctxt == NULL)
                    467:        v = NULL;
                    468:     else if (ctxt == CTXT_GLOBAL || ctxt == CTXT_CMD || ctxt == CTXT_ENV)
1.38      espie     469:        v = getvar((GSymT *)ctxt, name, end, k);
1.37      espie     470:     else {
1.38      espie     471:        if (idx == -1)
                    472:            v = NULL;
                    473:        else
                    474:            v = ctxt->locals[idx];
1.37      espie     475:     }
                    476:     if (v != NULL)
                    477:        return v;
                    478:
1.39      espie     479:     if ((flags & FIND_MINE) && ctxt != CTXT_CMD)
1.38      espie     480:        v = getvar(VAR_CMD, name, end, k);
1.37      espie     481:     if (v != NULL)
                    482:        return v;
                    483:
1.39      espie     484:     if (!checkEnvFirst && (flags & FIND_MINE) && ctxt != CTXT_GLOBAL)
1.38      espie     485:        v = getvar(VAR_GLOBAL, name, end, k);
1.37      espie     486:     if (v != NULL)
                    487:        return v;
                    488:
                    489:     if ((flags & FIND_ENV)) {
                    490:        char *env;
1.42      espie     491:        char *n;
1.37      espie     492:
1.38      espie     493:        v = getvar(VAR_ENV, name, end, k);
1.37      espie     494:        if (v != NULL)
                    495:            return v;
1.1       deraadt   496:
1.42      espie     497:        /* getenv requires a null-terminated name */
                    498:        n = interval_dup(name, end);
                    499:        env = getenv(n);
                    500:        free(n);
                    501:        if (env != NULL)
1.37      espie     502:            return VarAdd(name, env, VAR_ENV);
                    503:     }
1.17      espie     504:
1.39      espie     505:     if (checkEnvFirst && (flags & FIND_MINE) && ctxt != CTXT_GLOBAL)
1.38      espie     506:        v = getvar(VAR_GLOBAL, name, end, k);
1.37      espie     507:     return v;
1.1       deraadt   508: }
                    509:
                    510: /*-
                    511:  *-----------------------------------------------------------------------
                    512:  * VarAdd  --
                    513:  *     Add a new variable of name name and value val to the given context
                    514:  *
                    515:  * Results:
1.17      espie     516:  *     The added variable
1.1       deraadt   517:  *
                    518:  * Side Effects:
1.48    ! espie     519:  *     The new variable is placed in the given context.
1.1       deraadt   520:  *     The name and val arguments are duplicated so they may
                    521:  *     safely be freed.
                    522:  *-----------------------------------------------------------------------
                    523:  */
1.17      espie     524: static Var *
                    525: VarAdd(name, val, ctxt)
1.39      espie     526:     const char *name;  /* name of variable to add */
                    527:     const char *val;   /* value to set it to */
1.37      espie     528:     GSymT      *ctxt;  /* context in which to set it */
1.1       deraadt   529: {
1.38      espie     530:     Var        *v;
                    531:     const char         *end = NULL;
                    532:     int        idx;
                    533:     u_int32_t  k;
1.1       deraadt   534:
1.37      espie     535:     v = new_var(name, val);
1.1       deraadt   536:
                    537:     v->flags = 0;
                    538:
1.38      espie     539:     idx = quick_lookup(name, &end, &k);
                    540:
1.48    ! espie     541:     if (idx != -1)
1.38      espie     542:        Parse_Error(PARSE_FATAL, "Trying to set dynamic variable %s",
                    543:            v->name);
1.48    ! espie     544:     else
1.38      espie     545:        hash_insert(ctxt, hash_lookup_interval(ctxt, name, end, k), v);
1.17      espie     546:     return v;
1.1       deraadt   547: }
                    548:
                    549:
                    550: /*-
                    551:  *-----------------------------------------------------------------------
                    552:  * VarDelete  --
                    553:  *     Delete a variable and all the space associated with it.
                    554:  *-----------------------------------------------------------------------
                    555:  */
                    556: static void
                    557: VarDelete(vp)
1.48    ! espie     558:     void       *vp;
1.1       deraadt   559: {
1.48    ! espie     560:     Var        *v = (Var *) vp;
        !           561:
1.23      espie     562:     Buf_Destroy(&(v->val));
                    563:     free(v);
1.1       deraadt   564: }
                    565:
                    566:
                    567:
                    568: /*-
                    569:  *-----------------------------------------------------------------------
                    570:  * Var_Delete --
                    571:  *     Remove a variable from a context.
                    572:  *
                    573:  * Side Effects:
                    574:  *     The Var structure is removed and freed.
                    575:  *-----------------------------------------------------------------------
                    576:  */
                    577: void
                    578: Var_Delete(name, ctxt)
1.48    ! espie     579:     const char *name;
        !           580:     GSymT      *ctxt;
1.1       deraadt   581: {
1.48    ! espie     582:     Var        *v;
        !           583:     u_int32_t  k;
        !           584:     const char         *end = NULL;
1.1       deraadt   585:
1.37      espie     586:     if (DEBUG(VAR))
1.35      espie     587:        printf("%s:delete %s\n", context_name(ctxt), name);
1.38      espie     588:     (void)quick_lookup(name, &end, &k);
                    589:     v = hash_remove(ctxt, hash_lookup_interval(ctxt, name, end, k));
1.37      espie     590:
1.38      espie     591:     if (v != NULL)
1.30      espie     592:        VarDelete(v);
1.1       deraadt   593: }
                    594:
                    595: /*-
                    596:  *-----------------------------------------------------------------------
                    597:  * Var_Set --
                    598:  *     Set the variable name to the value val in the given context.
                    599:  *
                    600:  * Side Effects:
                    601:  *     If the variable doesn't yet exist, a new record is created for it.
                    602:  *     Else the old value is freed and the new one stuck in its place
                    603:  *
                    604:  * Notes:
                    605:  *     The variable is searched for only in its context before being
                    606:  *     created in that context. I.e. if the context is VAR_GLOBAL,
                    607:  *     only VAR_GLOBAL->context is searched. Likewise if it is VAR_CMD, only
                    608:  *     VAR_CMD->context is searched. This is done to avoid the literally
                    609:  *     thousands of unnecessary strcmp's that used to be done to
                    610:  *     set, say, $(@) or $(<).
                    611:  *-----------------------------------------------------------------------
                    612:  */
                    613: void
1.35      espie     614: Var_Set(name, val, ctxt)
1.48    ! espie     615:     const char *name;  /* name of variable to set */
        !           616:     const char *val;   /* value to give to the variable */
1.37      espie     617:     GSymT       *ctxt; /* context in which to set it */
1.1       deraadt   618: {
1.48    ! espie     619:     Var   *v;
1.1       deraadt   620:
                    621:     /*
                    622:      * We only look for a variable in the given context since anything set
                    623:      * here will override anything in a lower context, so there's not much
                    624:      * point in searching them all just to save a bit of memory...
                    625:      */
1.37      espie     626:     v = VarFind(name, (SymTable *)ctxt, 0);
1.38      espie     627:     if (v == NULL)
1.17      espie     628:        (void)VarAdd(name, val, ctxt);
1.38      espie     629:     else {
1.23      espie     630:        Buf_Reset(&(v->val));
                    631:        Buf_AddString(&(v->val), val);
1.1       deraadt   632:     }
1.37      espie     633:     if (DEBUG(VAR))
                    634:        printf("%s:%s = %s\n", context_name(ctxt), name, val);
1.1       deraadt   635:     /*
                    636:      * Any variables given on the command line are automatically exported
1.17      espie     637:      * to the environment (as per POSIX standard).
                    638:      * We put them into the env cache directly.
                    639:      * (Note that additions to VAR_CMD occur very early, so VAR_ENV is
                    640:      * actually empty at this point).
1.1       deraadt   641:      */
                    642:     if (ctxt == VAR_CMD) {
                    643:        setenv(name, val, 1);
1.17      espie     644:        (void)VarAdd(name, val, VAR_ENV);
1.1       deraadt   645:     }
                    646: }
                    647:
                    648: /*-
                    649:  *-----------------------------------------------------------------------
                    650:  * Var_Append --
                    651:  *     The variable of the given name has the given value appended to it in
                    652:  *     the given context.
                    653:  *
                    654:  * Side Effects:
                    655:  *     If the variable doesn't exist, it is created. Else the strings
                    656:  *     are concatenated (with a space in between).
                    657:  *
                    658:  * Notes:
                    659:  *     Only if the variable is being sought in the global context is the
                    660:  *     environment searched.
                    661:  *     XXX: Knows its calling circumstances in that if called with ctxt
                    662:  *     an actual target, it will only search that context since only
                    663:  *     a local variable could be being appended to. This is actually
                    664:  *     a big win and must be tolerated.
                    665:  *-----------------------------------------------------------------------
                    666:  */
                    667: void
1.35      espie     668: Var_Append(name, val, ctxt)
1.48    ! espie     669:     const char *name;  /* Name of variable to modify */
        !           670:     const char *val;   /* String to append to it */
1.37      espie     671:     GSymT      *ctxt;  /* Context in which this should occur */
1.1       deraadt   672: {
1.48    ! espie     673:     Var        *v;
1.1       deraadt   674:
1.37      espie     675:     v = VarFind(name, (SymTable *)ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0);
1.1       deraadt   676:
1.26      espie     677:     if (v == NULL) {
1.47      espie     678:        v = VarAdd(name, val, ctxt);
1.1       deraadt   679:     } else {
1.23      espie     680:        Buf_AddSpace(&(v->val));
                    681:        Buf_AddString(&(v->val), val);
1.1       deraadt   682:     }
1.37      espie     683:     if (DEBUG(VAR))
                    684:        printf("%s:%s = %s\n", context_name(ctxt), name, VarValue(v));
1.1       deraadt   685: }
                    686:
                    687: /*-
                    688:  *-----------------------------------------------------------------------
                    689:  * Var_Exists --
                    690:  *     See if the given variable exists.
                    691:  *
                    692:  * Results:
                    693:  *     TRUE if it does, FALSE if it doesn't
                    694:  *-----------------------------------------------------------------------
                    695:  */
                    696: Boolean
                    697: Var_Exists(name, ctxt)
1.48    ! espie     698:     const char *name;          /* Variable to find */
1.37      espie     699:     GSymT      *ctxt;          /* Context in which to start search */
1.1       deraadt   700: {
1.48    ! espie     701:     Var                *v;
1.1       deraadt   702:
1.39      espie     703:     v = VarFind(name, (SymTable *)ctxt, FIND_MINE|FIND_ENV);
1.1       deraadt   704:
1.26      espie     705:     if (v == NULL)
1.17      espie     706:        return FALSE;
                    707:     else
                    708:        return TRUE;
1.1       deraadt   709: }
                    710:
                    711: /*-
                    712:  *-----------------------------------------------------------------------
                    713:  * Var_Value --
                    714:  *     Return the value of the named variable in the given context
                    715:  *
                    716:  * Results:
                    717:  *     The value if the variable exists, NULL if it doesn't
                    718:  *-----------------------------------------------------------------------
                    719:  */
                    720: char *
1.18      espie     721: Var_Value(name, ctxt)
1.48    ! espie     722:     const char *name;  /* name to find */
1.37      espie     723:     GSymT      *ctxt;  /* context in which to search for it */
1.1       deraadt   724: {
1.48    ! espie     725:     Var                *v;
1.1       deraadt   726:
1.39      espie     727:     v = VarFind(name, (SymTable *)ctxt, FIND_ENV | FIND_MINE);
1.26      espie     728:     if (v != NULL)
1.23      espie     729:        return VarValue(v);
1.21      espie     730:     else
1.17      espie     731:        return NULL;
1.1       deraadt   732: }
                    733:
1.45      espie     734: /*
                    735:  *-----------------------------------------------------------------------
                    736:  * v = var_name_with_dollar(str, &pos, ctxt, err, endc)
                    737:  *   handle variable name that contains a dollar
                    738:  *   str points to the first letter of the variable name,
                    739:  *   &pos to the current position in the name (first dollar at invocation,
                    740:  *   end of name specification at return).
                    741:  *   returns the corresponding variable.
                    742:  *-----------------------------------------------------------------------
                    743:  */
                    744: static Var *
                    745: var_name_with_dollar(str, pos, ctxt, err, endc)
1.48    ! espie     746:     char       *str;           /* First dollar in variable name */
        !           747:     char       **pos;          /* Current position in variable spec */
1.45      espie     748:     SymTable           *ctxt;          /* The context for the variable */
                    749:     Boolean    err;            /* TRUE if undefined variables are an error */
                    750:     char       endc;           /* End character for spec */
                    751: {
1.48    ! espie     752:     BUFFER     buf;            /* Store the variable name */
        !           753:     size_t     sublen;         /* Deal with recursive expansions */
        !           754:     Boolean    subfree;
        !           755:     char       *n;             /* Sub name */
        !           756:     Var        *v;
1.45      espie     757:
                    758:     Buf_Init(&buf, MAKE_BSIZE);
                    759:
1.48    ! espie     760:     for (;;) {
1.45      espie     761:        Buf_AddInterval(&buf, str, *pos);
                    762:        n = Var_Parse(*pos, ctxt, err, &sublen, &subfree);
                    763:        if (n != NULL)
                    764:            Buf_AddString(&buf, n);
                    765:        if (subfree)
                    766:            free(n);
                    767:        *pos += sublen;
                    768:        str = *pos;
                    769:        for (; **pos != '$'; (*pos)++) {
                    770:            if (**pos == '\0' || **pos == endc || **pos == ':') {
                    771:                v = VarFind(Buf_Retrieve(&buf), ctxt, FIND_ENV | FIND_MINE);
                    772:                Buf_Destroy(&buf);
                    773:                return v;
                    774:            }
                    775:        }
                    776:     }
                    777: }
                    778:
1.1       deraadt   779: /*-
                    780:  *-----------------------------------------------------------------------
                    781:  * Var_Parse --
                    782:  *     Given the start of a variable invocation, extract the variable
                    783:  *     name and find its value, then modify it according to the
                    784:  *     specification.
                    785:  *
                    786:  * Results:
                    787:  *     The (possibly-modified) value of the variable or var_Error if the
                    788:  *     specification is invalid. The length of the specification is
                    789:  *     placed in *lengthPtr (for invalid specifications, this is just
                    790:  *     2...?).
                    791:  *     A Boolean in *freePtr telling whether the returned string should
                    792:  *     be freed by the caller.
                    793:  *-----------------------------------------------------------------------
                    794:  */
                    795: char *
1.35      espie     796: Var_Parse(str, ctxt, err, lengthPtr, freePtr)
1.44      espie     797:     char       *str;           /* The string to parse */
                    798:     SymTable           *ctxt;          /* The context for the variable */
                    799:     Boolean    err;            /* TRUE if undefined variables are an error */
                    800:     size_t     *lengthPtr;     /* OUT: The length of the specification */
                    801:     Boolean    *freePtr;       /* OUT: TRUE if caller should free result */
                    802: {
                    803:     char       *tstr;          /* Pointer into str */
                    804:     Var                *v;             /* Variable in invocation */
                    805:     char       endc;           /* Ending character when variable in parens
1.1       deraadt   806:                                 * or braces */
1.44      espie     807:     char       *start;
                    808:     char       *val;           /* Variable value  */
                    809:     u_int32_t  k;
                    810:     int                idx;
1.5       millert   811:
1.1       deraadt   812:     *freePtr = FALSE;
1.44      espie     813:     start = str++;
1.5       millert   814:
1.44      espie     815:     val = NULL;
1.45      espie     816:     v = NULL;
                    817:     idx = 0;
1.44      espie     818:
                    819:     if (*str != '(' && *str != '{') {
                    820:        tstr = str + 1;
                    821:        *lengthPtr = 2;
                    822:        endc = '\0';
1.1       deraadt   823:     } else {
1.44      espie     824:        endc = *str == '(' ? ')' : '}';
                    825:        str++;
1.5       millert   826:
1.44      espie     827:        /* Find eventual modifiers in the variable */
1.45      espie     828:        for (tstr = str; *tstr != ':'; tstr++) {
                    829:            if (*tstr == '$') {
                    830:                v = var_name_with_dollar(str, &tstr, ctxt, err, endc);
                    831:                if (*tstr == '\0' || *tstr == endc)
                    832:                    endc = '\0';
                    833:                break;
                    834:            } else if (*tstr == '\0' || *tstr == endc) {
1.44      espie     835:                endc = '\0';
                    836:                break;
1.1       deraadt   837:            }
1.45      espie     838:        }
1.44      espie     839:        *lengthPtr = tstr+1 - start;
                    840:     }
1.5       millert   841:
1.45      espie     842:     if (v == NULL) {
                    843:        idx = quick_lookup(str, &tstr, &k);
                    844:        v = varfind(str, tstr, ctxt, FIND_ENV | FIND_MINE, idx, k);
                    845:     }
1.44      espie     846:     if (v == NULL) {
                    847:        /* Find out about D and F forms of local variables. */
                    848:        if (idx == -1 && tstr == str+2 && (str[1] == 'D' || str[1] == 'F')) {
                    849:            switch (*str) {
                    850:            case '@':
                    851:                idx = TARGET_INDEX;
                    852:                break;
                    853:            case '!':
                    854:                idx = ARCHIVE_INDEX;
                    855:                break;
                    856:            case '*':
                    857:                idx = PREFIX_INDEX;
                    858:                break;
                    859:            case '%':
                    860:                idx = MEMBER_INDEX;
                    861:                break;
                    862:            default:
                    863:                break;
1.1       deraadt   864:            }
1.44      espie     865:            /* This is a DF form, check if we can expand it now.  */
                    866:            if (idx != -1 && ctxt != NULL && ctxt != CTXT_GLOBAL) {
                    867:                v = varfind(str, str+1, ctxt, 0, idx, 0);
                    868:                /* No need for nested expansion or anything, as we're
                    869:                 * the only one who sets these things and we sure don't
                    870:                 * do nested invocations in them...  */
                    871:                if (v != NULL) {
                    872:                    val = VarValue(v);
                    873:                    if (str[1] == 'D')
                    874:                        val = Var_GetHead(val);
                    875:                    else
                    876:                        val = Var_GetTail(val);
1.1       deraadt   877:                    *freePtr = TRUE;
1.44      espie     878:                }
1.1       deraadt   879:            }
                    880:        }
1.44      espie     881:     } else {
                    882:        if (v->flags & VAR_IN_USE)
                    883:            Fatal("Variable %s is recursive.", v->name);
                    884:            /*NOTREACHED*/
                    885:        else
                    886:            v->flags |= VAR_IN_USE;
                    887:        /* Before doing any modification, we have to make sure the value
                    888:         * has been fully expanded. If it looks like recursion might be
                    889:         * necessary (there's a dollar sign somewhere in the variable's value)
                    890:         * we just call Var_Subst to do any other substitutions that are
                    891:         * necessary. Note that the value returned by Var_Subst will have
                    892:         * been dynamically-allocated, so it will need freeing when we
                    893:         * return.  */
                    894:        val = VarValue(v);
                    895:        if (strchr(val, '$') != NULL) {
                    896:            val = Var_Subst(val, ctxt, err);
                    897:            *freePtr = TRUE;
                    898:        }
                    899:
                    900:        v->flags &= ~VAR_IN_USE;
1.1       deraadt   901:     }
1.44      espie     902:     if (endc != '\0')
                    903:        val = VarModifiers_Apply(val, ctxt, err, freePtr, tstr+1, endc,
1.42      espie     904:            lengthPtr);
1.44      espie     905:     if (val == NULL) {
                    906:        /* Dynamic source that can't be expanded for now: copy the var
                    907:         * specification instead.  */
                    908:        if (idx != -1 && (ctxt == NULL || ctxt == CTXT_GLOBAL)) {
1.42      espie     909:            *freePtr = TRUE;
1.44      espie     910:            val = interval_dup(start, start+ *lengthPtr);
                    911:        } else
                    912:            val = err ? var_Error : varNoError;
1.42      espie     913:     }
1.44      espie     914:
                    915:     return val;
1.42      espie     916: }
                    917:
1.1       deraadt   918: /*-
                    919:  *-----------------------------------------------------------------------
                    920:  * Var_Subst  --
1.24      espie     921:  *     Substitute for all variables in a string in a context
1.1       deraadt   922:  *     If undefErr is TRUE, Parse_Error will be called when an undefined
                    923:  *     variable is encountered.
                    924:  *
                    925:  * Results:
                    926:  *     The resulting string.
                    927:  *
                    928:  * Side Effects:
                    929:  *     None. The old string must be freed by the caller
                    930:  *-----------------------------------------------------------------------
                    931:  */
                    932: char *
1.24      espie     933: Var_Subst(str, ctxt, undefErr)
1.1       deraadt   934:     char         *str;             /* the string in which to substitute */
1.35      espie     935:     SymTable      *ctxt;           /* the context wherein to find variables */
1.1       deraadt   936:     Boolean      undefErr;         /* TRUE if undefineds are an error */
                    937: {
1.24      espie     938:     BUFFER       buf;              /* Buffer for forming things */
1.1       deraadt   939:     static Boolean errorReported;   /* Set true if an error has already
                    940:                                     * been reported to prevent a plethora
                    941:                                     * of messages when recursing */
                    942:
1.23      espie     943:     Buf_Init(&buf, MAKE_BSIZE);
1.1       deraadt   944:     errorReported = FALSE;
                    945:
1.24      espie     946:     for (;;) {
                    947:        char            *val;           /* Value to substitute for a variable */
                    948:        size_t          length;         /* Length of the variable invocation */
                    949:        Boolean         doFree;         /* Set true if val should be freed */
                    950:        const char *cp;
                    951:
                    952:        /* copy uninteresting stuff */
                    953:        for (cp = str; *str != '\0' && *str != '$'; str++)
                    954:            ;
                    955:        Buf_AddInterval(&buf, cp, str);
                    956:        if (*str == '\0')
                    957:            break;
                    958:        if (str[1] == '$') {
                    959:            /* A dollar sign may be escaped with another dollar sign.  */
                    960:            Buf_AddChar(&buf, '$');
                    961:            str += 2;
                    962:            continue;
                    963:        }
                    964:        val = Var_Parse(str, ctxt, undefErr, &length, &doFree);
                    965:        /* When we come down here, val should either point to the
                    966:         * value of this variable, suitably modified, or be NULL.
                    967:         * Length should be the total length of the potential
                    968:         * variable invocation (from $ to end character...) */
                    969:        if (val == var_Error || val == varNoError) {
                    970:            /* If performing old-time variable substitution, skip over
                    971:             * the variable and continue with the substitution. Otherwise,
                    972:             * store the dollar sign and advance str so we continue with
                    973:             * the string...  */
                    974:            if (oldVars) {
                    975:                str += length;
                    976:            } else if (undefErr) {
                    977:                /* If variable is undefined, complain and skip the
                    978:                 * variable. The complaint will stop us from doing anything
                    979:                 * when the file is parsed.  */
                    980:                if (!errorReported) {
                    981:                    Parse_Error(PARSE_FATAL,
                    982:                                 "Undefined variable \"%.*s\"",length,str);
                    983:                }
                    984:                str += length;
                    985:                errorReported = TRUE;
                    986:            } else {
                    987:                Buf_AddChar(&buf, *str);
                    988:                str += 1;
                    989:            }
                    990:        } else {
                    991:            /* We've now got a variable structure to store in. But first,
                    992:             * advance the string pointer.  */
                    993:            str += length;
                    994:
                    995:            /* Copy all the characters from the variable value straight
                    996:             * into the new string.  */
                    997:            Buf_AddString(&buf, val);
                    998:            if (doFree)
                    999:                free(val);
                   1000:        }
                   1001:     }
                   1002:     return  Buf_Retrieve(&buf);
                   1003: }
1.1       deraadt  1004:
1.24      espie    1005: /*-
                   1006:  *-----------------------------------------------------------------------
                   1007:  * Var_SubstVar  --
                   1008:  *     Substitute for one variable in the given string in the given context
                   1009:  *     If undefErr is TRUE, Parse_Error will be called when an undefined
                   1010:  *     variable is encountered.
                   1011:  *
                   1012:  * Side Effects:
                   1013:  *     Append the result to the buffer
                   1014:  *-----------------------------------------------------------------------
                   1015:  */
                   1016: void
                   1017: Var_SubstVar(buf, str, var, ctxt)
                   1018:     Buffer     buf;            /* Where to store the result */
                   1019:     char       *str;           /* The string in which to substitute */
                   1020:     const char *var;           /* Named variable */
1.37      espie    1021:     GSymT      *ctxt;          /* The context wherein to find variables */
1.24      espie    1022: {
                   1023:     char       *val;           /* Value substituted for a variable */
                   1024:     size_t     length;         /* Length of the variable invocation */
                   1025:     Boolean    doFree;         /* Set true if val should be freed */
                   1026:
                   1027:     for (;;) {
                   1028:        const char *cp;
                   1029:        /* copy uninteresting stuff */
                   1030:        for (cp = str; *str != '\0' && *str != '$'; str++)
                   1031:            ;
                   1032:        Buf_AddInterval(buf, cp, str);
                   1033:        if (*str == '\0')
                   1034:            break;
                   1035:        if (str[1] == '$') {
                   1036:            Buf_AddString(buf, "$$");
                   1037:            str += 2;
                   1038:            continue;
                   1039:        }
                   1040:        if (str[1] != '(' && str[1] != '{') {
                   1041:            if (str[1] != *var || var[1] != '\0') {
                   1042:                Buf_AddChars(buf, 2, str);
                   1043:                str += 2;
1.1       deraadt  1044:                continue;
1.24      espie    1045:            }
1.1       deraadt  1046:        } else {
1.24      espie    1047:            char *p;
                   1048:            char endc;
1.1       deraadt  1049:
1.24      espie    1050:            if (str[1] == '(')
                   1051:                endc = ')';
                   1052:            else if (str[1] == '{')
                   1053:                endc = '}';
                   1054:
                   1055:            /* Find the end of the variable specification.  */
                   1056:            p = str+2;
                   1057:            while (*p != '\0' && *p != ':' && *p != endc && *p != '$')
                   1058:                p++;
                   1059:            /* A variable inside the variable.  We don't know how to
                   1060:             * expand the external variable at this point, so we try
                   1061:             * again with the nested variable.  */
                   1062:            if (*p == '$') {
                   1063:                Buf_AddInterval(buf, str, p);
                   1064:                str = p;
                   1065:                continue;
1.1       deraadt  1066:            }
1.5       millert  1067:
1.24      espie    1068:            if (strncmp(var, str + 2, p - str - 2) != 0 ||
                   1069:                var[p - str - 2] != '\0') {
                   1070:                /* Not the variable we want to expand.  */
                   1071:                Buf_AddInterval(buf, str, p);
                   1072:                str = p;
                   1073:                continue;
                   1074:            }
1.1       deraadt  1075:        }
1.24      espie    1076:        /* okay, so we've found the variable we want to expand.  */
1.37      espie    1077:        val = Var_Parse(str, (SymTable *)ctxt, FALSE, &length, &doFree);
1.24      espie    1078:        /* We've now got a variable structure to store in. But first,
                   1079:         * advance the string pointer.  */
                   1080:        str += length;
                   1081:
                   1082:        /* Copy all the characters from the variable value straight
                   1083:         * into the new string.  */
                   1084:        Buf_AddString(buf, val);
                   1085:        if (doFree)
                   1086:            free(val);
1.1       deraadt  1087:     }
                   1088: }
                   1089:
                   1090: /*-
                   1091:  *-----------------------------------------------------------------------
                   1092:  * Var_Init --
                   1093:  *     Initialize the module
                   1094:  *
                   1095:  * Side Effects:
1.5       millert  1096:  *     The VAR_CMD and VAR_GLOBAL contexts are created
1.1       deraadt  1097:  *-----------------------------------------------------------------------
                   1098:  */
                   1099: void
1.33      espie    1100: Var_Init()
1.1       deraadt  1101: {
1.37      espie    1102:     static GSymT global_vars, cmd_vars, env_vars;
1.35      espie    1103:
                   1104:     VAR_GLOBAL = &global_vars;
                   1105:     VAR_CMD = &cmd_vars;
                   1106:     VAR_ENV = &env_vars;
1.38      espie    1107:     hash_init(VAR_GLOBAL, 10, &var_info);
                   1108:     hash_init(VAR_CMD, 5, &var_info);
                   1109:     hash_init(VAR_ENV, 5, &var_info);
1.37      espie    1110:     CTXT_GLOBAL = (SymTable *)VAR_GLOBAL;
                   1111:     CTXT_CMD = (SymTable *)VAR_CMD;
                   1112:     CTXT_ENV = (SymTable *)VAR_ENV;
1.1       deraadt  1113: }
                   1114:
                   1115:
                   1116: void
1.33      espie    1117: Var_End()
1.1       deraadt  1118: {
1.37      espie    1119: #ifdef CLEANUP
1.38      espie    1120:     Var *v;
                   1121:     unsigned int i;
                   1122:
                   1123:     for (v = hash_first(VAR_GLOBAL, &i); v != NULL;
                   1124:        v = hash_next(VAR_GLOBAL, &i))
                   1125:            VarDelete(v);
                   1126:     for (v = hash_first(VAR_CMD, &i); v != NULL;
                   1127:        v = hash_next(VAR_CMD, &i))
                   1128:            VarDelete(v);
                   1129:     for (v = hash_first(VAR_ENV, &i); v != NULL;
                   1130:        v = hash_next(VAR_ENV, &i))
                   1131:            VarDelete(v);
1.37      espie    1132: #endif
1.1       deraadt  1133: }
1.5       millert  1134:
1.1       deraadt  1135:
                   1136: /****************** PRINT DEBUGGING INFO *****************/
1.31      espie    1137: static void
                   1138: VarPrintVar(vp)
1.32      espie    1139:     void *vp;
1.1       deraadt  1140: {
1.31      espie    1141:     Var    *v = (Var *)vp;
                   1142:
1.23      espie    1143:     printf("%-16s = %s\n", v->name, VarValue(v));
1.1       deraadt  1144: }
                   1145:
                   1146: /*-
                   1147:  *-----------------------------------------------------------------------
                   1148:  * Var_Dump --
                   1149:  *     print all variables in a context
                   1150:  *-----------------------------------------------------------------------
                   1151:  */
                   1152: void
1.35      espie    1153: Var_Dump(ctxt)
1.37      espie    1154:    GSymT       *ctxt;
1.1       deraadt  1155: {
1.38      espie    1156:        Var *v;
                   1157:        unsigned int i;
                   1158:
                   1159:        for (v = hash_first(ctxt, &i); v != NULL;
                   1160:            v = hash_next(ctxt, &i))
                   1161:                VarPrintVar(v);
1.1       deraadt  1162: }
1.37      espie    1163:
1.46      espie    1164:
                   1165: #ifdef POSIX
                   1166:
                   1167: static const char *quotable = " \t\n\\'\"";
                   1168:
                   1169: /* In POSIX mode, variable assignments passed on the command line are
                   1170:  * propagated to sub makes through MAKEFLAGS.
                   1171:  */
                   1172: void
                   1173: Var_AddCmdline(name)
                   1174:        const char *name;
                   1175: {
                   1176:     Var *v;
                   1177:     unsigned int i;
                   1178:     BUFFER buf;
                   1179:     char *s;
                   1180:
                   1181:     Buf_Init(&buf, MAKE_BSIZE);
                   1182:
                   1183:     for (v = hash_first(VAR_CMD, &i); v != NULL;
                   1184:        v = hash_next(VAR_CMD, &i)) {
                   1185:                /* We assume variable names don't need quoting */
                   1186:                Buf_AddString(&buf, v->name);
                   1187:                Buf_AddChar(&buf, '=');
                   1188:                for (s = VarValue(v); *s != '\0'; s++) {
                   1189:                        if (strchr(quotable, *s))
                   1190:                                Buf_AddChar(&buf, '\\');
                   1191:                        Buf_AddChar(&buf, *s);
                   1192:                }
                   1193:                Buf_AddSpace(&buf);
                   1194:     }
                   1195:     Var_Append(name, Buf_Retrieve(&buf), VAR_GLOBAL);
                   1196:     Buf_Destroy(&buf);
                   1197: }
                   1198: #endif