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