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