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