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