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