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