Annotation of src/usr.bin/make/var.c, Revision 1.100
1.100 ! natano 1: /* $OpenBSD: var.c,v 1.99 2015/09/27 16:58:16 guenther 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.62 espie 5: * Copyright (c) 1999,2000,2007 Marc Espie.
1.17 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: /*
1.5 millert 31: * Copyright (c) 1988, 1989, 1990, 1993
32: * The Regents of the University of California. All rights reserved.
1.1 deraadt 33: * Copyright (c) 1989 by Berkeley Softworks
34: * All rights reserved.
35: *
36: * This code is derived from software contributed to Berkeley by
37: * Adam de Boor.
38: *
39: * Redistribution and use in source and binary forms, with or without
40: * modification, are permitted provided that the following conditions
41: * are met:
42: * 1. Redistributions of source code must retain the above copyright
43: * notice, this list of conditions and the following disclaimer.
44: * 2. Redistributions in binary form must reproduce the above copyright
45: * notice, this list of conditions and the following disclaimer in the
46: * documentation and/or other materials provided with the distribution.
1.57 millert 47: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 48: * may be used to endorse or promote products derived from this software
49: * without specific prior written permission.
50: *
51: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
52: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
55: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61: * SUCH DAMAGE.
62: */
63:
1.55 espie 64: #include <assert.h>
65: #include <stddef.h>
1.94 espie 66: #include <stdint.h>
1.55 espie 67: #include <stdio.h>
68: #include <stdlib.h>
69: #include <string.h>
1.94 espie 70: #include <ohash.h>
1.55 espie 71:
72: #include "config.h"
73: #include "defines.h"
74: #include "buf.h"
75: #include "stats.h"
1.62 espie 76: #include "pathnames.h"
1.55 espie 77: #include "varmodifiers.h"
78: #include "var.h"
79: #include "varname.h"
80: #include "error.h"
81: #include "str.h"
82: #include "var_int.h"
83: #include "memory.h"
84: #include "symtable.h"
85: #include "gnode.h"
1.91 espie 86: #include "dump.h"
87: #include "lowparse.h"
1.55 espie 88:
1.1 deraadt 89: /*
90: * This is a harmless return value for Var_Parse that can be used by Var_Subst
91: * to determine if there was an error in parsing -- easier than returning
92: * a flag, as things outside this module don't give a hoot.
93: */
1.53 espie 94: char var_Error[] = "";
1.1 deraadt 95:
1.95 espie 96: GNode *current_node = NULL;
1.1 deraadt 97: /*
98: * Similar to var_Error, but returned when the 'err' flag for Var_Parse is
99: * set false. Why not just use a constant? Well, gcc likes to condense
100: * identical string instances...
101: */
102: static char varNoError[] = "";
1.78 espie 103: bool errorIsOkay;
1.66 espie 104: static bool checkEnvFirst; /* true if environment should be searched for
105: * variables before the global context */
1.62 espie 106:
107: void
108: Var_setCheckEnvFirst(bool yes)
109: {
110: checkEnvFirst = yes;
111: }
1.1 deraadt 112:
113: /*
1.66 espie 114: * The rules for variable look-up are complicated.
115: *
116: * - Dynamic variables like $@ and $* are special. They always pertain to
117: * a given variable. In this implementation of make, it is an error to
118: * try to affect them manually. They are stored in a local symtable directly
119: * inside the gnode.
120: *
121: * Global variables can be obtained:
122: * - from the command line
123: * - from the environment
124: * - from the Makefile proper.
125: * All of these are stored in a hash global_variables.
126: *
127: * Variables set on the command line override Makefile contents, are
128: * passed to submakes (see Var_AddCmdLine), and are also exported to the
129: * environment.
130: *
131: * Without -e (!checkEnvFirst), make will see variables set in the
132: * Makefile, and default to the environment otherwise.
133: *
134: * With -e (checkEnvFirst), make will see the environment first, and that
135: * will override anything that's set in the Makefile (but not set on
136: * the command line).
137: *
138: * The SHELL variable is very special: it is never obtained from the
139: * environment, and never passed to the environment.
1.1 deraadt 140: */
1.53 espie 141:
1.66 espie 142: /* definitions pertaining to dynamic variables */
143:
144: /* full names of dynamic variables */
1.53 espie 145: static char *varnames[] = {
1.66 espie 146: TARGET,
147: PREFIX,
148: ARCHIVE,
149: MEMBER,
1.100 ! natano 150: IMPSRC,
1.66 espie 151: OODATE,
152: ALLSRC,
153: FTARGET,
154: DTARGET,
155: FPREFIX,
156: DPREFIX,
157: FARCHIVE,
158: DARCHIVE,
159: FMEMBER,
1.100 ! natano 160: DMEMBER,
! 161: FIMPSRC,
! 162: DIMPSRC
1.66 espie 163: };
1.53 espie 164:
1.92 espie 165: static bool xtlist[] = {
166: false, /* GLOBAL_INDEX */
167: true, /* $@ */
168: false, /* $* */
169: false, /* $! */
170: true, /* $% */
1.100 ! natano 171: true, /* $< */
1.92 espie 172: false, /* $? */
173: false, /* $> */
174: true, /* ${@F} */
175: true, /* ${@D} */
176: false, /* ${*F} */
177: false, /* ${*D} */
178: false, /* ${!F} */
179: false, /* ${!D} */
180: true, /* ${%F} */
181: true, /* ${%D} */
1.100 ! natano 182: true, /* ${<F} */
! 183: true, /* ${<D} */
1.92 espie 184: };
185:
186: /* so that we can access tlist[-1] */
187: static bool *tlist = xtlist+1;
188:
1.66 espie 189: /* hashed names of dynamic variables */
1.65 espie 190: #include "varhashconsts.h"
191:
192: /* extended indices for System V stuff */
193: #define FTARGET_INDEX 7
194: #define DTARGET_INDEX 8
195: #define FPREFIX_INDEX 9
196: #define DPREFIX_INDEX 10
197: #define FARCHIVE_INDEX 11
198: #define DARCHIVE_INDEX 12
199: #define FMEMBER_INDEX 13
200: #define DMEMBER_INDEX 14
1.100 ! natano 201: #define FIMPSRC_INDEX 15
! 202: #define DIMPSRC_INDEX 16
1.65 espie 203:
1.66 espie 204: #define GLOBAL_INDEX -1
205:
1.65 espie 206: #define EXTENDED2SIMPLE(i) (((i)-LOCAL_SIZE)/2)
207: #define IS_EXTENDED_F(i) ((i)%2 == 1)
208:
1.66 espie 209:
1.65 espie 210: static struct ohash global_variables;
1.1 deraadt 211:
1.66 espie 212:
1.37 espie 213: typedef struct Var_ {
1.66 espie 214: BUFFER val; /* the variable value */
215: unsigned int flags; /* miscellaneous status flags */
1.62 espie 216: #define VAR_IN_USE 1 /* Variable's value currently being used. */
1.66 espie 217: /* (Used to avoid recursion) */
218: #define VAR_DUMMY 2 /* Variable is currently just a name */
219: /* In particular: BUFFER is invalid */
220: #define VAR_FROM_CMD 4 /* Special source: command line */
221: #define VAR_FROM_ENV 8 /* Special source: environment */
222: #define VAR_SEEN_ENV 16 /* No need to go look up environment again */
223: #define VAR_SHELL 32 /* Magic behavior */
1.79 espie 224:
1.62 espie 225: #define POISONS (POISON_NORMAL | POISON_EMPTY | POISON_NOT_DEFINED)
1.66 espie 226: /* Defined in var.h */
227: char name[1]; /* the variable's name */
1.1 deraadt 228: } Var;
229:
1.53 espie 230:
231: static struct ohash_info var_info = {
232: offsetof(Var, name),
1.66 espie 233: NULL,
1.98 espie 234: hash_calloc, hash_free, element_alloc
1.66 espie 235: };
236:
237: static int classify_var(const char *, const char **, uint32_t *);
1.62 espie 238: static Var *find_global_var(const char *, const char *, uint32_t);
1.66 espie 239: static Var *find_global_var_without_env(const char *, const char *, uint32_t);
1.62 espie 240: static void fill_from_env(Var *);
1.53 espie 241: static Var *create_var(const char *, const char *);
1.66 espie 242: static void var_set_initial_value(Var *, const char *);
243: static void var_set_value(Var *, const char *);
244: #define var_get_value(v) Buf_Retrieve(&((v)->val))
245: static void var_append_value(Var *, const char *);
246: static void poison_check(Var *);
1.62 espie 247: static void var_set_append(const char *, const char *, const char *, int, bool);
248: static void set_magic_shell_variable(void);
1.66 espie 249:
250: static void delete_var(Var *);
251: static void print_var(Var *);
252:
253:
1.53 espie 254: static const char *find_rparen(const char *);
255: static const char *find_ket(const char *);
256: typedef const char * (*find_t)(const char *);
257: static find_t find_pos(int);
1.69 espie 258: static void push_used(Var *);
259: static void pop_used(Var *);
1.83 espie 260: static char *get_expanded_value(const char *, const char *, int, uint32_t,
261: SymTable *, bool, bool *);
1.72 espie 262: static bool parse_base_variable_name(const char **, struct Name *, SymTable *);
1.53 espie 263:
1.66 espie 264:
265:
266: /* Variable lookup function: return idx for dynamic variable, or
267: * GLOBAL_INDEX if name is not dynamic. Set up *pk for further use.
268: */
1.38 espie 269: static int
1.66 espie 270: classify_var(const char *name, const char **enamePtr, uint32_t *pk)
1.38 espie 271: {
1.66 espie 272: size_t len;
1.38 espie 273:
1.66 espie 274: *pk = ohash_interval(name, enamePtr);
275: len = *enamePtr - name;
276: /* substitute short version for long local name */
277: switch (*pk % MAGICSLOTS1) { /* MAGICSLOTS should be the */
278: case K_LONGALLSRC % MAGICSLOTS1:/* smallest constant yielding */
279: /* distinct case values */
280: if (*pk == K_LONGALLSRC && len == strlen(LONGALLSRC) &&
281: strncmp(name, LONGALLSRC, len) == 0)
282: return ALLSRC_INDEX;
283: break;
284: case K_LONGARCHIVE % MAGICSLOTS1:
285: if (*pk == K_LONGARCHIVE && len == strlen(LONGARCHIVE) &&
286: strncmp(name, LONGARCHIVE, len) == 0)
287: return ARCHIVE_INDEX;
288: break;
289: case K_LONGIMPSRC % MAGICSLOTS1:
290: if (*pk == K_LONGIMPSRC && len == strlen(LONGIMPSRC) &&
291: strncmp(name, LONGIMPSRC, len) == 0)
292: return IMPSRC_INDEX;
293: break;
294: case K_LONGMEMBER % MAGICSLOTS1:
295: if (*pk == K_LONGMEMBER && len == strlen(LONGMEMBER) &&
296: strncmp(name, LONGMEMBER, len) == 0)
297: return MEMBER_INDEX;
298: break;
299: case K_LONGOODATE % MAGICSLOTS1:
300: if (*pk == K_LONGOODATE && len == strlen(LONGOODATE) &&
301: strncmp(name, LONGOODATE, len) == 0)
302: return OODATE_INDEX;
303: break;
304: case K_LONGPREFIX % MAGICSLOTS1:
305: if (*pk == K_LONGPREFIX && len == strlen(LONGPREFIX) &&
306: strncmp(name, LONGPREFIX, len) == 0)
307: return PREFIX_INDEX;
308: break;
309: case K_LONGTARGET % MAGICSLOTS1:
310: if (*pk == K_LONGTARGET && len == strlen(LONGTARGET) &&
311: strncmp(name, LONGTARGET, len) == 0)
312: return TARGET_INDEX;
313: break;
314: case K_TARGET % MAGICSLOTS1:
315: if (name[0] == TARGET[0] && len == 1)
316: return TARGET_INDEX;
317: break;
318: case K_OODATE % MAGICSLOTS1:
319: if (name[0] == OODATE[0] && len == 1)
320: return OODATE_INDEX;
321: break;
322: case K_ALLSRC % MAGICSLOTS1:
323: if (name[0] == ALLSRC[0] && len == 1)
324: return ALLSRC_INDEX;
325: break;
326: case K_IMPSRC % MAGICSLOTS1:
327: if (name[0] == IMPSRC[0] && len == 1)
328: return IMPSRC_INDEX;
329: break;
330: case K_PREFIX % MAGICSLOTS1:
331: if (name[0] == PREFIX[0] && len == 1)
332: return PREFIX_INDEX;
333: break;
334: case K_ARCHIVE % MAGICSLOTS1:
335: if (name[0] == ARCHIVE[0] && len == 1)
336: return ARCHIVE_INDEX;
337: break;
338: case K_MEMBER % MAGICSLOTS1:
339: if (name[0] == MEMBER[0] && len == 1)
340: return MEMBER_INDEX;
341: break;
342: case K_FTARGET % MAGICSLOTS1:
343: if (name[0] == FTARGET[0] && name[1] == FTARGET[1] && len == 2)
344: return FTARGET_INDEX;
345: break;
346: case K_DTARGET % MAGICSLOTS1:
347: if (name[0] == DTARGET[0] && name[1] == DTARGET[1] && len == 2)
348: return DTARGET_INDEX;
349: break;
350: case K_FPREFIX % MAGICSLOTS1:
351: if (name[0] == FPREFIX[0] && name[1] == FPREFIX[1] && len == 2)
352: return FPREFIX_INDEX;
353: break;
354: case K_DPREFIX % MAGICSLOTS1:
355: if (name[0] == DPREFIX[0] && name[1] == DPREFIX[1] && len == 2)
356: return DPREFIX_INDEX;
357: break;
358: case K_FARCHIVE % MAGICSLOTS1:
359: if (name[0] == FARCHIVE[0] && name[1] == FARCHIVE[1] &&
360: len == 2)
361: return FARCHIVE_INDEX;
362: break;
363: case K_DARCHIVE % MAGICSLOTS1:
364: if (name[0] == DARCHIVE[0] && name[1] == DARCHIVE[1] &&
365: len == 2)
366: return DARCHIVE_INDEX;
367: break;
368: case K_FMEMBER % MAGICSLOTS1:
369: if (name[0] == FMEMBER[0] && name[1] == FMEMBER[1] && len == 2)
370: return FMEMBER_INDEX;
371: break;
372: case K_DMEMBER % MAGICSLOTS1:
373: if (name[0] == DMEMBER[0] && name[1] == DMEMBER[1] && len == 2)
1.100 ! natano 374: return DMEMBER_INDEX;
! 375: break;
! 376: case K_FIMPSRC % MAGICSLOTS1:
! 377: if (name[0] == FIMPSRC[0] && name[1] == FIMPSRC[1] && len == 2)
! 378: return FIMPSRC_INDEX;
! 379: break;
! 380: case K_DIMPSRC % MAGICSLOTS1:
! 381: if (name[0] == DIMPSRC[0] && name[1] == DIMPSRC[1] && len == 2)
! 382: return DIMPSRC_INDEX;
1.66 espie 383: break;
384: default:
385: break;
386: }
387: return GLOBAL_INDEX;
1.38 espie 388: }
1.37 espie 389:
1.66 espie 390:
391: /***
392: *** Internal handling of variables.
393: ***/
394:
395:
396: /* Create a new variable, does not initialize anything except the name.
397: * in particular, buffer is invalid, and flag value is invalid. Accordingly,
398: * must either:
399: * - set flags to VAR_DUMMY
400: * - set flags to !VAR_DUMMY, and initialize buffer, for instance with
401: * var_set_initial_value().
402: */
1.65 espie 403: static Var *
404: create_var(const char *name, const char *ename)
405: {
1.66 espie 406: return ohash_create_entry(&var_info, name, &ename);
1.65 espie 407: }
408:
1.66 espie 409: /* Initial version of var_set_value(), to be called after create_var().
410: */
1.65 espie 411: static void
1.66 espie 412: var_set_initial_value(Var *v, const char *val)
1.65 espie 413: {
1.66 espie 414: size_t len;
1.65 espie 415:
1.66 espie 416: len = strlen(val);
417: Buf_Init(&(v->val), len+1);
418: Buf_AddChars(&(v->val), len, val);
1.65 espie 419: }
420:
1.66 espie 421: /* Normal version of var_set_value(), to be called after variable is fully
422: * initialized.
423: */
1.65 espie 424: static void
1.66 espie 425: var_set_value(Var *v, const char *val)
1.65 espie 426: {
1.66 espie 427: if ((v->flags & VAR_DUMMY) == 0) {
428: Buf_Reset(&(v->val));
429: Buf_AddString(&(v->val), val);
430: } else {
431: var_set_initial_value(v, val);
432: v->flags &= ~VAR_DUMMY;
433: }
1.65 espie 434: }
435:
1.66 espie 436: /* Add to a variable, insert a separating space if the variable was already
437: * defined.
438: */
1.65 espie 439: static void
1.66 espie 440: var_append_value(Var *v, const char *val)
1.65 espie 441: {
1.66 espie 442: if ((v->flags & VAR_DUMMY) == 0) {
443: Buf_AddSpace(&(v->val));
444: Buf_AddString(&(v->val), val);
445: } else {
446: var_set_initial_value(v, val);
447: v->flags &= ~VAR_DUMMY;
448: }
449: }
450:
451:
452: /* Delete a variable and all the space associated with it.
1.65 espie 453: */
454: static void
1.66 espie 455: delete_var(Var *v)
1.65 espie 456: {
1.66 espie 457: if ((v->flags & VAR_DUMMY) == 0)
458: Buf_Destroy(&(v->val));
459: free(v);
1.65 espie 460: }
461:
462:
463:
1.66 espie 464:
465: /***
466: *** Dynamic variable handling.
467: ***/
468:
469:
470:
471: /* create empty symtable.
472: * XXX: to save space, dynamic variables may be NULL pointers.
473: */
1.65 espie 474: void
475: SymTable_Init(SymTable *ctxt)
476: {
1.80 espie 477: static SymTable sym_template;
1.66 espie 478: memcpy(ctxt, &sym_template, sizeof(*ctxt));
1.65 espie 479: }
480:
1.66 espie 481: /***
482: *** Global variable handling.
483: ***/
484:
485: /* Create a new global var if necessary, and set it up correctly.
486: * Do not take environment into account.
487: */
1.53 espie 488: static Var *
1.66 espie 489: find_global_var_without_env(const char *name, const char *ename, uint32_t k)
1.37 espie 490: {
1.65 espie 491: unsigned int slot;
492: Var *v;
1.1 deraadt 493:
1.65 espie 494: slot = ohash_lookup_interval(&global_variables, name, ename, k);
495: v = ohash_find(&global_variables, slot);
496: if (v == NULL) {
497: v = create_var(name, ename);
498: v->flags = VAR_DUMMY;
499: ohash_insert(&global_variables, slot, v);
500: }
501: return v;
1.35 espie 502: }
1.53 espie 503:
1.66 espie 504: /* Helper for find_global_var(): grab environment value if needed.
505: */
1.62 espie 506: static void
507: fill_from_env(Var *v)
1.37 espie 508: {
1.66 espie 509: char *env;
1.37 espie 510:
1.66 espie 511: env = getenv(v->name);
512: if (env == NULL)
513: v->flags |= VAR_SEEN_ENV;
514: else {
515: var_set_value(v, env);
516: v->flags |= VAR_FROM_ENV | VAR_SEEN_ENV;
517: }
1.37 espie 518:
1.53 espie 519: #ifdef STATS_VAR_LOOKUP
1.66 espie 520: STAT_VAR_FROM_ENV++;
1.53 espie 521: #endif
1.62 espie 522: }
1.37 espie 523:
1.66 espie 524: /* Find global var, and obtain its value from the environment if needed.
525: */
1.62 espie 526: static Var *
1.65 espie 527: find_global_var(const char *name, const char *ename, uint32_t k)
528: {
1.66 espie 529: Var *v;
1.65 espie 530:
1.66 espie 531: v = find_global_var_without_env(name, ename, k);
1.65 espie 532:
1.82 espie 533: if ((v->flags & VAR_SEEN_ENV) == 0)
534: if ((checkEnvFirst && (v->flags & VAR_FROM_CMD) == 0) ||
535: (v->flags & VAR_DUMMY) != 0)
536: fill_from_env(v);
1.65 espie 537:
1.66 espie 538: return v;
1.65 espie 539: }
540:
1.66 espie 541: /* mark variable as poisoned, in a given setup.
542: */
1.65 espie 543: void
544: Var_MarkPoisoned(const char *name, const char *ename, unsigned int type)
1.62 espie 545: {
1.65 espie 546: Var *v;
547: uint32_t k;
548: int idx;
1.66 espie 549: idx = classify_var(name, &ename, &k);
1.65 espie 550:
1.66 espie 551: if (idx != GLOBAL_INDEX) {
552: Parse_Error(PARSE_FATAL,
1.65 espie 553: "Trying to poison dynamic variable $%s",
554: varnames[idx]);
555: return;
556: }
1.62 espie 557:
1.65 espie 558: v = find_global_var(name, ename, k);
559: v->flags |= type;
1.66 espie 560: /* POISON_NORMAL is not lazy: if the variable already exists in
561: * the Makefile, then it's a mistake.
562: */
1.65 espie 563: if (v->flags & POISON_NORMAL) {
564: if (v->flags & VAR_DUMMY)
565: return;
566: if (v->flags & VAR_FROM_ENV)
567: return;
568: Parse_Error(PARSE_FATAL,
569: "Poisoned variable %s is already set\n", v->name);
1.62 espie 570: }
1.37 espie 571: }
572:
1.66 espie 573: /* Check if there's any reason not to use the variable in this context.
574: */
1.62 espie 575: static void
576: poison_check(Var *v)
1.1 deraadt 577: {
1.62 espie 578: if (v->flags & POISON_NORMAL) {
1.66 espie 579: Parse_Error(PARSE_FATAL,
1.62 espie 580: "Poisoned variable %s has been referenced\n", v->name);
581: return;
582: }
583: if (v->flags & VAR_DUMMY) {
584: Parse_Error(PARSE_FATAL,
585: "Poisoned variable %s is not defined\n", v->name);
586: return;
587: }
588: if (v->flags & POISON_EMPTY)
1.66 espie 589: if (strcmp(var_get_value(v), "") == 0)
590: Parse_Error(PARSE_FATAL,
1.62 espie 591: "Poisoned variable %s is empty\n", v->name);
1.37 espie 592: }
593:
1.66 espie 594: /* Delete global variable.
595: */
1.1 deraadt 596: void
1.66 espie 597: Var_Deletei(const char *name, const char *ename)
1.1 deraadt 598: {
1.66 espie 599: Var *v;
600: uint32_t k;
1.62 espie 601: unsigned int slot;
1.66 espie 602: int idx;
1.62 espie 603:
1.66 espie 604: idx = classify_var(name, &ename, &k);
605: if (idx != GLOBAL_INDEX) {
606: Parse_Error(PARSE_FATAL,
607: "Trying to delete dynamic variable $%s", varnames[idx]);
608: return;
609: }
1.62 espie 610: slot = ohash_lookup_interval(&global_variables, name, ename, k);
611: v = ohash_find(&global_variables, slot);
1.80 espie 612:
1.62 espie 613: if (v == NULL)
614: return;
1.66 espie 615:
1.62 espie 616: if (checkEnvFirst && (v->flags & VAR_FROM_ENV))
617: return;
1.1 deraadt 618:
1.62 espie 619: if (v->flags & VAR_FROM_CMD)
620: return;
1.37 espie 621:
1.62 espie 622: ohash_remove(&global_variables, slot);
1.66 espie 623: delete_var(v);
1.1 deraadt 624: }
625:
1.66 espie 626: /* Set or add a global variable, in VAR_CMD or VAR_GLOBAL context.
627: */
1.62 espie 628: static void
629: var_set_append(const char *name, const char *ename, const char *val, int ctxt,
630: bool append)
1.1 deraadt 631: {
1.66 espie 632: Var *v;
633: uint32_t k;
634: int idx;
1.53 espie 635:
1.66 espie 636: idx = classify_var(name, &ename, &k);
637: if (idx != GLOBAL_INDEX) {
1.62 espie 638: Parse_Error(PARSE_FATAL, "Trying to %s dynamic variable $%s",
639: append ? "append to" : "set", varnames[idx]);
640: return;
641: }
1.53 espie 642:
1.62 espie 643: v = find_global_var(name, ename, k);
644: if (v->flags & POISON_NORMAL)
645: Parse_Error(PARSE_FATAL, "Trying to %s poisoned variable %s\n",
646: append ? "append to" : "set", v->name);
647: /* so can we write to it ? */
1.66 espie 648: if (ctxt == VAR_CMD) { /* always for command line */
649: (append ? var_append_value : var_set_value)(v, val);
1.62 espie 650: v->flags |= VAR_FROM_CMD;
651: if ((v->flags & VAR_SHELL) == 0) {
1.66 espie 652: /* Any variables given on the command line are
1.62 espie 653: * automatically exported to the environment,
1.66 espie 654: * except for SHELL (as per POSIX standard).
1.62 espie 655: */
656: esetenv(v->name, val);
1.66 espie 657: }
1.62 espie 658: if (DEBUG(VAR))
1.66 espie 659: printf("command:%s = %s\n", v->name, var_get_value(v));
1.62 espie 660: } else if ((v->flags & VAR_FROM_CMD) == 0 &&
661: (!checkEnvFirst || (v->flags & VAR_FROM_ENV) == 0)) {
1.66 espie 662: (append ? var_append_value : var_set_value)(v, val);
1.62 espie 663: if (DEBUG(VAR))
1.66 espie 664: printf("global:%s = %s\n", v->name, var_get_value(v));
1.62 espie 665: } else if (DEBUG(VAR))
1.84 tobias 666: printf("overridden:%s = %s\n", v->name, var_get_value(v));
1.1 deraadt 667: }
668:
669: void
1.77 espie 670: Var_Seti_with_ctxt(const char *name, const char *ename, const char *val,
1.73 espie 671: int ctxt)
1.1 deraadt 672: {
1.62 espie 673: var_set_append(name, ename, val, ctxt, false);
674: }
1.53 espie 675:
1.62 espie 676: void
1.77 espie 677: Var_Appendi_with_ctxt(const char *name, const char *ename, const char *val,
1.73 espie 678: int ctxt)
1.62 espie 679: {
680: var_set_append(name, ename, val, ctxt, true);
681: }
1.53 espie 682:
1.66 espie 683: /* XXX different semantics for Var_Valuei() and Var_Definedi():
684: * references to poisoned value variables will error out in Var_Valuei(),
685: * but not in Var_Definedi(), so the following construct works:
686: * .poison BINDIR
687: * BINDIR ?= /usr/bin
688: */
1.53 espie 689: char *
1.59 espie 690: Var_Valuei(const char *name, const char *ename)
1.53 espie 691: {
1.66 espie 692: Var *v;
693: uint32_t k;
694: int idx;
1.62 espie 695:
1.66 espie 696: idx = classify_var(name, &ename, &k);
697: if (idx != GLOBAL_INDEX) {
698: Parse_Error(PARSE_FATAL,
699: "Trying to get value of dynamic variable $%s",
700: varnames[idx]);
701: return NULL;
1.62 espie 702: }
1.66 espie 703: v = find_global_var(name, ename, k);
704: if (v->flags & POISONS)
705: poison_check(v);
706: if ((v->flags & VAR_DUMMY) == 0)
707: return var_get_value(v);
708: else
709: return NULL;
1.53 espie 710: }
711:
1.62 espie 712: bool
713: Var_Definedi(const char *name, const char *ename)
714: {
1.66 espie 715: Var *v;
716: uint32_t k;
717: int idx;
1.62 espie 718:
1.66 espie 719: idx = classify_var(name, &ename, &k);
720: /* We don't bother writing an error message for dynamic variables,
721: * these will be caught when getting set later, usually.
722: */
723: if (idx == GLOBAL_INDEX) {
1.62 espie 724: v = find_global_var(name, ename, k);
725: if (v->flags & POISON_NORMAL)
1.66 espie 726: poison_check(v);
1.62 espie 727: if ((v->flags & VAR_DUMMY) == 0)
728: return true;
729: }
730: return false;
1.65 espie 731: }
732:
1.66 espie 733:
734: /***
735: *** Substitution functions, handling both global and dynamic variables.
736: ***/
737:
738:
739: /* All the scanning functions needed to account for all the forms of
740: * variable names that exist:
741: * $A, ${AB}, $(ABC), ${A:mod}, $(A:mod)
742: */
1.53 espie 743:
744: static const char *
1.59 espie 745: find_rparen(const char *p)
1.53 espie 746: {
747: while (*p != '$' && *p != '\0' && *p != ')' && *p != ':')
748: p++;
749: return p;
750: }
1.1 deraadt 751:
1.53 espie 752: static const char *
1.59 espie 753: find_ket(const char *p)
1.53 espie 754: {
755: while (*p != '$' && *p != '\0' && *p != '}' && *p != ':')
756: p++;
757: return p;
758: }
1.1 deraadt 759:
1.66 espie 760: /* Figure out what kind of name we're looking for from a start character.
761: */
1.53 espie 762: static find_t
1.59 espie 763: find_pos(int c)
1.53 espie 764: {
765: switch(c) {
1.66 espie 766: case '(':
1.53 espie 767: return find_rparen;
1.66 espie 768: case '{':
1.53 espie 769: return find_ket;
770: default:
1.66 espie 771: Parse_Error(PARSE_FATAL,
1.99 guenther 772: "Wrong character in variable spec %c (can't happen)", c);
1.66 espie 773: return find_rparen;
1.53 espie 774: }
1.1 deraadt 775: }
776:
1.77 espie 777: static bool
1.72 espie 778: parse_base_variable_name(const char **pstr, struct Name *name, SymTable *ctxt)
1.1 deraadt 779: {
1.72 espie 780: const char *str = *pstr;
1.68 espie 781: const char *tstr;
1.70 espie 782: bool has_modifier = false;
1.66 espie 783:
1.70 espie 784: switch(str[1]) {
785: case '(':
786: case '{':
1.66 espie 787: /* Find eventual modifiers in the variable */
1.72 espie 788: tstr = VarName_Get(str+2, name, ctxt, false, find_pos(str[1]));
1.90 espie 789: if (*tstr == '\0')
790: Parse_Error(PARSE_FATAL, "Unterminated variable spec in %s", *pstr);
791: else if (*tstr == ':')
1.70 espie 792: has_modifier = true;
1.90 espie 793: else
1.70 espie 794: tstr++;
795: break;
796: default:
1.72 espie 797: name->s = str+1;
798: name->e = str+2;
799: name->tofree = false;
1.70 espie 800: tstr = str + 2;
801: break;
1.66 espie 802: }
1.72 espie 803: *pstr = tstr;
804: return has_modifier;
805: }
806:
807: bool
808: Var_ParseSkip(const char **pstr, SymTable *ctxt)
809: {
810: const char *str = *pstr;
811: struct Name name;
812: bool result;
813: bool has_modifier;
814: const char *tstr = str;
1.80 espie 815:
1.93 espie 816: if (str[1] == 0) {
817: *pstr = str+1;
818: return false;
819: }
1.72 espie 820: has_modifier = parse_base_variable_name(&tstr, &name, ctxt);
821: VarName_Free(&name);
1.68 espie 822: result = true;
1.88 espie 823: if (has_modifier) {
824: bool freePtr = false;
825: char *s = VarModifiers_Apply(NULL, NULL, ctxt, true, &freePtr,
826: &tstr, str[1]);
827: if (s == var_Error)
1.68 espie 828: result = false;
1.88 espie 829: if (freePtr)
830: free(s);
831: }
1.70 espie 832: *pstr = tstr;
1.68 espie 833: return result;
1.1 deraadt 834: }
835:
1.55 espie 836: /* As of now, Var_ParseBuffer is just a wrapper around Var_Parse. For
837: * speed, it may be better to revisit the implementation to do things
838: * directly. */
839: bool
1.66 espie 840: Var_ParseBuffer(Buffer buf, const char *str, SymTable *ctxt, bool err,
1.59 espie 841: size_t *lengthPtr)
1.53 espie 842: {
1.66 espie 843: char *result;
844: bool freeIt;
1.45 espie 845:
1.66 espie 846: result = Var_Parse(str, ctxt, err, lengthPtr, &freeIt);
847: if (result == var_Error)
848: return false;
849:
850: Buf_AddString(buf, result);
851: if (freeIt)
852: free(result);
853: return true;
1.45 espie 854: }
855:
1.69 espie 856: /* Helper function for Var_Parse: still recursive, but we tag what variables
857: * we expand for better error messages.
858: */
859: #define MAX_DEPTH 350
860: static Var *call_trace[MAX_DEPTH];
861: static int current_depth = 0;
862:
1.77 espie 863: static void
1.69 espie 864: push_used(Var *v)
865: {
866: if (v->flags & VAR_IN_USE) {
867: int i;
868: fprintf(stderr, "Problem with variable expansion chain: ");
1.77 espie 869: for (i = 0;
870: i < (current_depth > MAX_DEPTH ? MAX_DEPTH : current_depth);
1.69 espie 871: i++)
872: fprintf(stderr, "%s -> ", call_trace[i]->name);
873: fprintf(stderr, "%s\n", v->name);
874: Fatal("\tVariable %s is recursive.", v->name);
875: /*NOTREACHED*/
876: }
877:
878: v->flags |= VAR_IN_USE;
879: if (current_depth < MAX_DEPTH)
880: call_trace[current_depth] = v;
881: current_depth++;
882: }
883:
884: static void
885: pop_used(Var *v)
886: {
887: v->flags &= ~VAR_IN_USE;
888: current_depth--;
889: }
890:
891: static char *
1.86 espie 892: get_expanded_value(const char *name, const char *ename, int idx, uint32_t k,
1.83 espie 893: SymTable *ctxt, bool err, bool *freePtr)
1.69 espie 894: {
895: char *val;
896:
897: /* Before doing any modification, we have to make sure the
898: * value has been fully expanded. If it looks like recursion
899: * might be necessary (there's a dollar sign somewhere in
900: * the variable's value) we just call Var_Subst to do any
901: * other substitutions that are necessary. Note that the
902: * value returned by Var_Subst will have been dynamically
903: * allocated, so it will need freeing when we return.
904: */
905: if (idx == GLOBAL_INDEX) {
1.83 espie 906: Var *v = find_global_var(name, ename, k);
907:
908: if (v == NULL)
909: return NULL;
910:
911: if ((v->flags & POISONS) != 0)
912: poison_check(v);
913: if ((v->flags & VAR_DUMMY) != 0)
914: return NULL;
915:
916: val = var_get_value(v);
1.69 espie 917: if (strchr(val, '$') != NULL) {
918: push_used(v);
919: val = Var_Subst(val, ctxt, err);
920: pop_used(v);
921: *freePtr = true;
922: }
1.83 espie 923: } else {
924: if (ctxt != NULL) {
925: if (idx < LOCAL_SIZE)
926: val = ctxt->locals[idx];
927: else
928: val = ctxt->locals[EXTENDED2SIMPLE(idx)];
929: } else
930: val = NULL;
931: if (val == NULL)
932: return NULL;
933:
934: if (idx >= LOCAL_SIZE) {
935: if (IS_EXTENDED_F(idx))
936: val = Var_GetTail(val);
937: else
938: val = Var_GetHead(val);
939: *freePtr = true;
940: }
1.69 espie 941: }
942: return val;
943: }
944:
1.95 espie 945: #define ERRMSG1 "Using $< in a non-suffix rule context is a GNUmake idiom "
946: #define ERRMSG2 "Using undefined dynamic variable $%s "
947: static void
948: bad_dynamic_variable(int idx)
949: {
950: Location origin;
951:
952: Parse_FillLocation(&origin);
953: if (idx >= LOCAL_SIZE)
954: idx = EXTENDED2SIMPLE(idx);
955: switch(idx) {
956: case IMPSRC_INDEX:
957: if (origin.fname)
958: Fatal(ERRMSG1 "(%s:%lu)",
1.97 espie 959: origin.fname, origin.lineno);
1.95 espie 960: else if (current_node)
961: Fatal(ERRMSG1 "(prereq of %s)", current_node->name);
962: else
963: Fatal(ERRMSG1 "(?)");
964: break;
965: default:
966: if (origin.fname)
967: Error(ERRMSG2 "(%s:%lu)", varnames[idx],
1.97 espie 968: origin.fname, origin.lineno);
1.95 espie 969: else if (current_node)
970: Error(ERRMSG2 "(prereq of %s)", varnames[idx],
971: current_node->name);
972: else
973: Error(ERRMSG2 "(?)", varnames[idx]);
974: break;
975: }
976: }
977:
1.1 deraadt 978: char *
1.66 espie 979: Var_Parse(const char *str, /* The string to parse */
980: SymTable *ctxt, /* The context for the variable */
981: bool err, /* true if undefined variables are an error */
982: size_t *lengthPtr, /* OUT: The length of the specification */
1.59 espie 983: bool *freePtr) /* OUT: true if caller should free result */
1.44 espie 984: {
1.70 espie 985: const char *tstr;
1.66 espie 986: struct Name name;
1.70 espie 987: char *val;
1.66 espie 988: uint32_t k;
989: int idx;
1.72 espie 990: bool has_modifier;
1.66 espie 991:
992: *freePtr = false;
993:
1.72 espie 994: tstr = str;
1.93 espie 995:
996: if (str[1] == 0) {
997: *lengthPtr = 1;
998: *freePtr = false;
999: return err ? var_Error : varNoError;
1000: }
1.72 espie 1001:
1002: has_modifier = parse_base_variable_name(&tstr, &name, ctxt);
1.5 millert 1003:
1.66 espie 1004: idx = classify_var(name.s, &name.e, &k);
1.83 espie 1005: val = get_expanded_value(name.s, name.e, idx, k, ctxt, err, freePtr);
1.70 espie 1006: if (has_modifier) {
1.66 espie 1007: val = VarModifiers_Apply(val, &name, ctxt, err, freePtr,
1.70 espie 1008: &tstr, str[1]);
1009: }
1.66 espie 1010: if (val == NULL) {
1011: val = err ? var_Error : varNoError;
1.96 espie 1012: /* If it comes from a dynamic source, and it doesn't have
1013: * a context, copy the spec instead.
1014: * Specifically, this make allows constructs like:
1015: * target.o: $*.c
1016: * Absence of a context means "parsing". But these can't
1017: * be expanded during parsing, to be consistent with the
1018: * way .SUFFIXES work.
1019: * .SUFFIXES may be added/reset/removed during parsing,
1020: * but in the end, the final list is what's considered for
1021: * handling targets. So those dynamic variables must be
1022: * handled lazily too.
1023: */
1.66 espie 1024: if (idx != GLOBAL_INDEX) {
1025: if (ctxt == NULL) {
1026: *freePtr = true;
1.70 espie 1027: val = Str_dupi(str, tstr);
1.66 espie 1028: } else {
1.95 espie 1029: bad_dynamic_variable(idx);
1.66 espie 1030: }
1.53 espie 1031: }
1032: }
1.66 espie 1033: VarName_Free(&name);
1.70 espie 1034: *lengthPtr = tstr - str;
1.66 espie 1035: return val;
1.42 espie 1036: }
1037:
1.66 espie 1038:
1.1 deraadt 1039: char *
1.66 espie 1040: Var_Subst(const char *str, /* the string in which to substitute */
1041: SymTable *ctxt, /* the context wherein to find variables */
1.59 espie 1042: bool undefErr) /* true if undefineds are an error */
1043: {
1.66 espie 1044: BUFFER buf; /* Buffer for forming things */
1045: static bool errorReported;
1046:
1047: Buf_Init(&buf, MAKE_BSIZE);
1048: errorReported = false;
1049:
1050: for (;;) {
1051: char *val; /* Value to substitute for a variable */
1052: size_t length; /* Length of the variable invocation */
1053: bool doFree; /* Set true if val should be freed */
1054: const char *cp;
1055:
1056: /* copy uninteresting stuff */
1057: for (cp = str; *str != '\0' && *str != '$'; str++)
1058: ;
1059: Buf_Addi(&buf, cp, str);
1060: if (*str == '\0')
1061: break;
1062: if (str[1] == '$') {
1063: /* A $ may be escaped with another $. */
1064: Buf_AddChar(&buf, '$');
1065: str += 2;
1066: continue;
1067: }
1068: val = Var_Parse(str, ctxt, undefErr, &length, &doFree);
1069: /* When we come down here, val should either point to the
1070: * value of this variable, suitably modified, or be NULL.
1071: * Length should be the total length of the potential
1072: * variable invocation (from $ to end character...) */
1073: if (val == var_Error || val == varNoError) {
1074: /* If errors are not an issue, skip over the variable
1075: * and continue with the substitution. Otherwise, store
1076: * the dollar sign and advance str so we continue with
1077: * the string... */
1078: if (errorIsOkay)
1079: str += length;
1080: else if (undefErr) {
1081: /* If variable is undefined, complain and
1082: * skip the variable name. The complaint
1083: * will stop us from doing anything when
1084: * the file is parsed. */
1085: if (!errorReported)
1086: Parse_Error(PARSE_FATAL,
1087: "Undefined variable \"%.*s\"",
1.99 guenther 1088: (int)length, str);
1.66 espie 1089: str += length;
1090: errorReported = true;
1091: } else {
1092: Buf_AddChar(&buf, *str);
1093: str++;
1094: }
1095: } else {
1096: /* We've now got a variable structure to store in.
1097: * But first, advance the string pointer. */
1098: str += length;
1099:
1100: /* Copy all the characters from the variable value
1101: * straight into the new string. */
1102: Buf_AddString(&buf, val);
1103: if (doFree)
1104: free(val);
1105: }
1.24 espie 1106: }
1.66 espie 1107: return Buf_Retrieve(&buf);
1.92 espie 1108: }
1109:
1110: /* Very quick version of the variable scanner that just looks for target
1111: * variables, and never ever errors out
1112: */
1113: bool
1114: Var_Check_for_target(const char *str)
1115: {
1116: bool seen_target = false;
1117:
1118: for (;;) {
1119: const char *tstr;
1120: uint32_t k;
1121: int idx;
1122: bool has_modifier;
1123: struct Name name;
1124:
1125: /* skip over uninteresting stuff */
1126: for (; *str != '\0' && *str != '$'; str++)
1127: ;
1128: if (*str == '\0')
1129: break;
1130: if (str[1] == '$') {
1131: /* A $ may be escaped with another $. */
1132: str += 2;
1133: continue;
1134: }
1135:
1136: tstr = str;
1137:
1138: has_modifier = parse_base_variable_name(&tstr, &name, NULL);
1139: idx = classify_var(name.s, &name.e, &k);
1140: if (has_modifier) {
1141: bool doFree = false;
1142: char *val = VarModifiers_Apply(NULL, NULL, NULL, false,
1143: &doFree, &tstr, str[1]);
1144: if (doFree)
1145: free(val);
1146: }
1147: if (tlist[idx])
1148: seen_target = true;
1149: VarName_Free(&name);
1150: str = tstr;
1151: }
1152: return seen_target;
1.66 espie 1153: }
1154:
1.74 espie 1155: static BUFFER subst_buffer;
1156:
1.77 espie 1157: /* we would like to subst on intervals, but it's complicated, so we cheat
1158: * by storing the interval in a static buffer.
1.74 espie 1159: */
1160: char *
1161: Var_Substi(const char *str, const char *estr, SymTable *ctxt, bool undefErr)
1162: {
1163: /* delimited string: no need to copy */
1164: if (estr == NULL || *estr == '\0')
1165: return Var_Subst(str, ctxt, undefErr);
1166:
1167: Buf_Reset(&subst_buffer);
1168: Buf_Addi(&subst_buffer, str, estr);
1169: return Var_Subst(Buf_Retrieve(&subst_buffer), ctxt, undefErr);
1170: }
1.66 espie 1171:
1172: /***
1173: *** Supplementary support for .for loops.
1174: ***/
1175:
1176:
1177:
1178: struct LoopVar
1179: {
1180: Var old; /* keep old variable value (before the loop) */
1181: Var *me; /* the variable we're dealing with */
1182: };
1183:
1184:
1185: struct LoopVar *
1186: Var_NewLoopVar(const char *name, const char *ename)
1187: {
1188: struct LoopVar *l;
1189: uint32_t k;
1190:
1191: l = emalloc(sizeof(struct LoopVar));
1192:
1193: /* we obtain a new variable quickly, make a snapshot of its old
1194: * value, and make sure the environment cannot touch us.
1195: */
1196: /* XXX: should we avoid dynamic variables ? */
1197: k = ohash_interval(name, &ename);
1198:
1199: l->me = find_global_var_without_env(name, ename, k);
1.80 espie 1200: l->old = *(l->me);
1.67 espie 1201: l->me->flags = VAR_SEEN_ENV | VAR_DUMMY;
1.66 espie 1202: return l;
1.85 espie 1203: }
1204:
1205: char *
1206: Var_LoopVarName(struct LoopVar *v)
1207: {
1208: return v->me->name;
1.66 espie 1209: }
1210:
1211: void
1212: Var_DeleteLoopVar(struct LoopVar *l)
1213: {
1.67 espie 1214: if ((l->me->flags & VAR_DUMMY) == 0)
1215: Buf_Destroy(&(l->me->val));
1.66 espie 1216: *(l->me) = l->old;
1217: free(l);
1.24 espie 1218: }
1.1 deraadt 1219:
1.53 espie 1220: void
1.66 espie 1221: Var_SubstVar(Buffer buf, /* To store result */
1222: const char *str, /* The string in which to substitute */
1223: struct LoopVar *l, /* Handle */
1.59 espie 1224: const char *val) /* Its value */
1.24 espie 1225: {
1.66 espie 1226: const char *var = l->me->name;
1.24 espie 1227:
1.66 espie 1228: var_set_value(l->me, val);
1.53 espie 1229:
1.66 espie 1230: for (;;) {
1231: const char *start;
1232: /* Copy uninteresting stuff */
1233: for (start = str; *str != '\0' && *str != '$'; str++)
1234: ;
1235: Buf_Addi(buf, start, str);
1236:
1237: start = str;
1238: if (*str++ == '\0')
1239: break;
1240: str++;
1241: /* and escaped dollars */
1242: if (start[1] == '$') {
1243: Buf_Addi(buf, start, start+2);
1244: continue;
1245: }
1246: /* Simple variable, if it's not us, copy. */
1247: if (start[1] != '(' && start[1] != '{') {
1248: if (start[1] != *var || var[1] != '\0') {
1249: Buf_AddChars(buf, 2, start);
1250: continue;
1251: }
1252: } else {
1253: const char *p;
1254: char paren = start[1];
1255:
1256:
1257: /* Find the end of the variable specification. */
1258: p = find_pos(paren)(str);
1259: /* A variable inside the variable. We don't know how to
1260: * expand the external variable at this point, so we
1261: * try again with the nested variable. */
1262: if (*p == '$') {
1263: Buf_Addi(buf, start, p);
1264: str = p;
1265: continue;
1266: }
1267:
1268: if (strncmp(var, str, p - str) != 0 ||
1269: var[p - str] != '\0') {
1270: /* Not the variable we want to expand. */
1271: Buf_Addi(buf, start, p);
1272: str = p;
1273: continue;
1274: }
1275: if (*p == ':') {
1276: bool doFree; /* should val be freed ? */
1.80 espie 1277: char *newval;
1.66 espie 1278: struct Name name;
1279:
1280: doFree = false;
1281: name.s = var;
1282: name.e = var + (p-str);
1283:
1284: /* val won't be freed since !doFree, but
1285: * VarModifiers_Apply doesn't know that,
1286: * hence the cast. */
1.77 espie 1287: newval = VarModifiers_Apply((char *)val,
1.70 espie 1288: &name, NULL, false, &doFree, &p, paren);
1.66 espie 1289: Buf_AddString(buf, newval);
1290: if (doFree)
1291: free(newval);
1.70 espie 1292: str = p;
1.66 espie 1293: continue;
1294: } else
1295: str = p+1;
1296: }
1297: Buf_AddString(buf, val);
1298: }
1299: }
1.1 deraadt 1300:
1.66 espie 1301: /***
1302: *** Odds and ends
1303: ***/
1.1 deraadt 1304:
1.62 espie 1305: static void
1306: set_magic_shell_variable()
1307: {
1.66 espie 1308: const char *name = "SHELL";
1309: const char *ename = NULL;
1310: uint32_t k;
1311: Var *v;
1312:
1313: k = ohash_interval(name, &ename);
1314: v = find_global_var_without_env(name, ename, k);
1315: var_set_value(v, _PATH_BSHELL);
1316: /* XXX the environment shall never affect it */
1317: v->flags = VAR_SHELL | VAR_SEEN_ENV;
1318: }
1319:
1320: /*
1321: * Var_Init
1.1 deraadt 1322: * Initialize the module
1323: */
1324: void
1.59 espie 1325: Var_Init(void)
1.1 deraadt 1326: {
1.66 espie 1327: ohash_init(&global_variables, 10, &var_info);
1328: set_magic_shell_variable();
1.35 espie 1329:
1.62 espie 1330:
1.66 espie 1331: errorIsOkay = true;
1332: Var_setCheckEnvFirst(false);
1.53 espie 1333:
1.66 espie 1334: VarModifiers_Init();
1.74 espie 1335: Buf_Init(&subst_buffer, MAKE_BSIZE);
1.1 deraadt 1336: }
1337:
1338:
1.53 espie 1339: static const char *interpret(int);
1340:
1341: static const char *
1.59 espie 1342: interpret(int f)
1.53 espie 1343: {
1.66 espie 1344: if (f & VAR_DUMMY)
1345: return "(D)";
1346: return "";
1.53 espie 1347: }
1348:
1.1 deraadt 1349:
1.31 espie 1350: static void
1.66 espie 1351: print_var(Var *v)
1.1 deraadt 1352: {
1.66 espie 1353: printf("%-16s%s = %s\n", v->name, interpret(v->flags),
1354: (v->flags & VAR_DUMMY) == 0 ? var_get_value(v) : "(none)");
1.1 deraadt 1355: }
1356:
1.91 espie 1357:
1.1 deraadt 1358: void
1.59 espie 1359: Var_Dump(void)
1.1 deraadt 1360: {
1.91 espie 1361: Var **t;
1362:
1.66 espie 1363: unsigned int i;
1.91 espie 1364: const char *banner;
1365: bool first = true;
1366:
1367: t = sort_ohash_by_name(&global_variables);
1368: /* somewhat dirty, but does the trick */
1369:
1370: #define LOOP(mask, value, do_stuff) \
1371: for (i = 0; t[i] != NULL; i++) \
1372: if ((t[i]->flags & (mask)) == (value)) { \
1373: if (banner) { \
1374: if (first) \
1375: first = false; \
1376: else \
1377: putchar('\n'); \
1378: fputs(banner, stdout); \
1379: banner = NULL; \
1380: } \
1381: do_stuff; \
1382: }
1383:
1384: banner = "#variables from command line:\n";
1385: LOOP(VAR_FROM_CMD | VAR_DUMMY, VAR_FROM_CMD, print_var(t[i]));
1386:
1387: banner = "#global variables:\n";
1388: LOOP(VAR_FROM_ENV| VAR_FROM_CMD | VAR_DUMMY, 0, print_var(t[i]));
1389:
1390: banner = "#variables from env:\n";
1391: LOOP(VAR_FROM_ENV|VAR_DUMMY, VAR_FROM_ENV, print_var(t[i]));
1.53 espie 1392:
1.91 espie 1393: banner = "#variable name seen, but not defined:";
1394: LOOP(VAR_DUMMY|POISONS, VAR_DUMMY, printf(" %s", t[i]->name));
1.37 espie 1395:
1.91 espie 1396: #undef LOOP
1397:
1398: printf("\n\n");
1399:
1400: for (i = 0; t[i] != NULL; i++)
1401: switch(t[i]->flags & POISONS) {
1402: case POISON_NORMAL:
1403: printf(".poison %s\n", t[i]->name);
1404: break;
1405: case POISON_EMPTY:
1406: printf(".poison empty(%s)\n", t[i]->name);
1407: break;
1408: case POISON_NOT_DEFINED:
1409: printf(".poison !defined(%s)\n", t[i]->name);
1410: break;
1411: default:
1412: break;
1413: }
1414: free(t);
1415: printf("\n");
1.53 espie 1416: }
1.46 espie 1417:
1418: static const char *quotable = " \t\n\\'\"";
1419:
1.66 espie 1420: /* POSIX says that variable assignments passed on the command line should be
1.46 espie 1421: * propagated to sub makes through MAKEFLAGS.
1422: */
1423: void
1.59 espie 1424: Var_AddCmdline(const char *name)
1.46 espie 1425: {
1.66 espie 1426: Var *v;
1427: unsigned int i;
1428: BUFFER buf;
1429: char *s;
1430:
1431: Buf_Init(&buf, MAKE_BSIZE);
1432:
1433: for (v = ohash_first(&global_variables, &i); v != NULL;
1434: v = ohash_next(&global_variables, &i)) {
1435: /* This is not as expensive as it looks: this function is
1436: * called before parsing Makefiles, so there are just a
1437: * few non cmdling variables in there.
1438: */
1.62 espie 1439: if (!(v->flags & VAR_FROM_CMD)) {
1440: continue;
1441: }
1.46 espie 1442: /* We assume variable names don't need quoting */
1443: Buf_AddString(&buf, v->name);
1444: Buf_AddChar(&buf, '=');
1.66 espie 1445: for (s = var_get_value(v); *s != '\0'; s++) {
1.46 espie 1446: if (strchr(quotable, *s))
1447: Buf_AddChar(&buf, '\\');
1448: Buf_AddChar(&buf, *s);
1449: }
1450: Buf_AddSpace(&buf);
1.66 espie 1451: }
1.73 espie 1452: Var_Append(name, Buf_Retrieve(&buf));
1.66 espie 1453: Buf_Destroy(&buf);
1.46 espie 1454: }