Annotation of src/usr.bin/make/var.c, Revision 1.51
1.51 ! espie 1: /* $OpenBSD: var.c,v 1.50 2000/11/24 14:29:56 espie Exp $ */
1.6 millert 2: /* $NetBSD: var.c,v 1.18 1997/03/18 19:24:46 christos Exp $ */
1.1 deraadt 3:
4: /*
1.17 espie 5: * Copyright (c) 1999 Marc 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:
31: /*
1.5 millert 32: * Copyright (c) 1988, 1989, 1990, 1993
33: * The Regents of the University of California. All rights reserved.
1.1 deraadt 34: * Copyright (c) 1989 by Berkeley Softworks
35: * All rights reserved.
36: *
37: * This code is derived from software contributed to Berkeley by
38: * Adam de Boor.
39: *
40: * Redistribution and use in source and binary forms, with or without
41: * modification, are permitted provided that the following conditions
42: * are met:
43: * 1. Redistributions of source code must retain the above copyright
44: * notice, this list of conditions and the following disclaimer.
45: * 2. Redistributions in binary form must reproduce the above copyright
46: * notice, this list of conditions and the following disclaimer in the
47: * documentation and/or other materials provided with the distribution.
48: * 3. All advertising materials mentioning features or use of this software
49: * must display the following acknowledgement:
50: * This product includes software developed by the University of
51: * California, Berkeley and its contributors.
52: * 4. Neither the name of the University nor the names of its contributors
53: * may be used to endorse or promote products derived from this software
54: * without specific prior written permission.
55: *
56: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
57: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
60: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66: * SUCH DAMAGE.
67: */
68:
69: /*-
70: * var.c --
71: * Variable-handling functions
72: *
73: * Interface:
74: * Var_Set Set the value of a variable in the given
75: * context. The variable is created if it doesn't
76: * yet exist. The value and variable name need not
77: * be preserved.
78: *
79: * Var_Append Append more characters to an existing variable
80: * in the given context. The variable needn't
81: * exist already -- it will be created if it doesn't.
82: * A space is placed between the old value and the
83: * new one.
84: *
85: * Var_Exists See if a variable exists.
86: *
87: * Var_Value Return the value of a variable in a context or
88: * NULL if the variable is undefined.
89: *
90: * Var_Subst Substitute named variable, or all variables if
91: * NULL in a string using
92: * the given context as the top-most one. If the
93: * third argument is non-zero, Parse_Error is
94: * called if any variables are undefined.
95: *
1.50 espie 96: * Var_SubstVar Substitute a named variable in a string using
97: * the given context as the top-most one,
98: * accumulating the result into a user-supplied
99: * buffer.
100: *
1.1 deraadt 101: * Var_Parse Parse a variable expansion from a string and
102: * return the result and the number of characters
103: * consumed.
104: *
105: * Var_Delete Delete a variable in a context.
106: *
107: * Var_Init Initialize this module.
108: *
109: * Debugging:
110: * Var_Dump Print out all variables defined in the given
111: * context.
112: *
113: * XXX: There's a lot of duplication in these functions.
114: */
115:
116: #include <ctype.h>
1.6 millert 117: #ifndef MAKE_BOOTSTRAP
1.9 deraadt 118: #include <sys/types.h>
1.6 millert 119: #include <regex.h>
120: #endif
121: #include <stdlib.h>
1.35 espie 122: #include <stddef.h>
1.1 deraadt 123: #include "make.h"
124: #include "buf.h"
1.38 espie 125: #include "ohash.h"
126: #include "hashconsts.h"
1.43 espie 127: #include "varmodifiers.h"
1.34 espie 128:
1.48 espie 129: #ifndef lint
130: #if 0
131: static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94";
132: #else
133: UNUSED
1.51 ! espie 134: static char rcsid[] = "$OpenBSD: var.c,v 1.50 2000/11/24 14:29:56 espie Exp $";
1.48 espie 135: #endif
136: #endif /* not lint */
137:
1.37 espie 138: static SymTable *CTXT_GLOBAL, *CTXT_CMD, *CTXT_ENV;
139:
1.34 espie 140: static char *varnames[] = {
141: TARGET,
142: OODATE,
143: ALLSRC,
144: IMPSRC,
145: PREFIX,
146: ARCHIVE,
147: MEMBER };
148:
1.1 deraadt 149: /*
150: * This is a harmless return value for Var_Parse that can be used by Var_Subst
151: * to determine if there was an error in parsing -- easier than returning
152: * a flag, as things outside this module don't give a hoot.
153: */
154: char var_Error[] = "";
155:
156: /*
157: * Similar to var_Error, but returned when the 'err' flag for Var_Parse is
158: * set false. Why not just use a constant? Well, gcc likes to condense
159: * identical string instances...
160: */
161: static char varNoError[] = "";
162:
163: /*
164: * Internally, variables are contained in four different contexts.
165: * 1) the environment. They may not be changed. If an environment
166: * variable is appended-to, the result is placed in the global
167: * context.
168: * 2) the global context. Variables set in the Makefile are located in
169: * the global context. It is the penultimate context searched when
170: * substituting.
171: * 3) the command-line context. All variables set on the command line
172: * are placed in this context. They are UNALTERABLE once placed here.
173: * 4) the local context. Each target has associated with it a context
174: * list. On this list are located the structures describing such
175: * local variables as $(@) and $(*)
176: * The four contexts are searched in the reverse order from which they are
177: * listed.
178: */
1.37 espie 179: GSymT *VAR_GLOBAL; /* variables from the makefile */
180: GSymT *VAR_CMD; /* variables defined on the command-line */
181: static GSymT *VAR_ENV; /* variables read from env */
1.1 deraadt 182:
1.39 espie 183: #define FIND_MINE 0x1 /* look in CTXT_CMD and CTXT_GLOBAL */
184: #define FIND_ENV 0x2 /* look in the environment */
1.1 deraadt 185:
1.37 espie 186: typedef struct Var_ {
1.23 espie 187: BUFFER val; /* its value */
1.1 deraadt 188: int flags; /* miscellaneous status flags */
189: #define VAR_IN_USE 1 /* Variable's value currently being used.
190: * Used to avoid recursion */
191: #define VAR_JUNK 4 /* Variable is a junk variable that
192: * should be destroyed when done with
193: * it. Used by Var_Parse for undefined,
194: * modified variables */
1.38 espie 195: char name[1]; /* the variable's name */
1.1 deraadt 196: } Var;
197:
1.38 espie 198: static struct hash_info var_info = {
199: offsetof(Var, name),
200: NULL, hash_alloc, hash_free, element_alloc };
201: static int quick_lookup __P((const char *, const char **, u_int32_t *));
1.23 espie 202: #define VarValue(v) Buf_Retrieve(&((v)->val))
1.39 espie 203: static Var *varfind __P((const char *, const char *, SymTable *, int, int, u_int32_t));
204: static Var *VarFind_interval __P((const char *, const char *, SymTable *, int));
205: #define VarFind(n, ctxt, flags) VarFind_interval(n, NULL, ctxt, flags)
206: static Var *VarAdd __P((const char *, const char *, GSymT *));
1.32 espie 207: static void VarDelete __P((void *));
208: static void VarPrintVar __P((void *));
1.38 espie 209: static const char *context_name __P((GSymT *));
1.39 espie 210: static Var *new_var __P((const char *, const char *));
211: static Var *getvar __P((GSymT *, const char *, const char *, u_int32_t));
1.45 espie 212: static Var *var_name_with_dollar __P((char *, char **, SymTable *, Boolean, char));
1.37 espie 213:
214: void
215: SymTable_Init(ctxt)
216: SymTable *ctxt;
217: {
218: static SymTable sym_template;
219: memcpy(ctxt, &sym_template, sizeof(*ctxt));
220: }
221:
222: void
223: SymTable_Destroy(ctxt)
224: SymTable *ctxt;
225: {
226: int i;
227:
228: for (i = 0; i < LOCAL_SIZE; i++)
229: if (ctxt->locals[i] != NULL)
230: VarDelete(ctxt->locals[i]);
231: }
232:
1.38 espie 233: static int
234: quick_lookup(name, end, pk)
235: const char *name;
236: const char **end;
237: u_int32_t *pk;
238: {
239: size_t len;
240:
241: *pk = hash_interval(name, end);
242: len = *end - name;
243: /* substitute short version for long local name */
244: switch (*pk % MAGICSLOTS) { /* MAGICSLOTS should be the */
245: case K_LONGALLSRC % MAGICSLOTS: /* smallest constant yielding */
246: /* distinct case values */
247: if (*pk == K_LONGALLSRC && strncmp(name, LONGALLSRC, len) == 0 &&
248: len == strlen(LONGALLSRC))
249: return ALLSRC_INDEX;
250: break;
251: case K_LONGARCHIVE % MAGICSLOTS:
252: if (*pk == K_LONGARCHIVE && strncmp(name, LONGARCHIVE, len) == 0 &&
253: len == strlen(LONGARCHIVE))
254: return ARCHIVE_INDEX;
255: break;
256: case K_LONGIMPSRC % MAGICSLOTS:
257: if (*pk == K_LONGIMPSRC && strncmp(name, LONGIMPSRC, len) == 0 &&
258: len == strlen(LONGIMPSRC))
259: return IMPSRC_INDEX;
260: break;
261: case K_LONGMEMBER % MAGICSLOTS:
262: if (*pk == K_LONGMEMBER && strncmp(name, LONGMEMBER, len) == 0 &&
263: len == strlen(LONGMEMBER))
264: return MEMBER_INDEX;
265: break;
266: case K_LONGOODATE % MAGICSLOTS:
267: if (*pk == K_LONGOODATE && strncmp(name, LONGOODATE, len) == 0 &&
268: len == strlen(LONGOODATE))
269: return OODATE_INDEX;
270: break;
271: case K_LONGPREFIX % MAGICSLOTS:
272: if (*pk == K_LONGPREFIX && strncmp(name, LONGPREFIX, len) == 0 &&
273: len == strlen(LONGPREFIX))
274: return PREFIX_INDEX;
275: break;
276: case K_LONGTARGET % MAGICSLOTS:
277: if (*pk == K_LONGTARGET && strncmp(name, LONGTARGET, len) == 0 &&
278: len == strlen(LONGTARGET))
279: return TARGET_INDEX;
280: break;
281: case K_TARGET % MAGICSLOTS:
282: if (name[0] == TARGET[0] && len == 1)
283: return TARGET_INDEX;
284: break;
285: case K_OODATE % MAGICSLOTS:
286: if (name[0] == OODATE[0] && len == 1)
287: return OODATE_INDEX;
288: break;
289: case K_ALLSRC % MAGICSLOTS:
290: if (name[0] == ALLSRC[0] && len == 1)
291: return ALLSRC_INDEX;
292: break;
293: case K_IMPSRC % MAGICSLOTS:
294: if (name[0] == IMPSRC[0] && len == 1)
295: return IMPSRC_INDEX;
296: break;
297: case K_PREFIX % MAGICSLOTS:
298: if (name[0] == PREFIX[0] && len == 1)
299: return PREFIX_INDEX;
300: break;
301: case K_ARCHIVE % MAGICSLOTS:
302: if (name[0] == ARCHIVE[0] && len == 1)
303: return ARCHIVE_INDEX;
304: break;
305: case K_MEMBER % MAGICSLOTS:
306: if (name[0] == MEMBER[0] && len == 1)
307: return MEMBER_INDEX;
308: break;
309: default:
310: break;
311: }
312: return -1;
313: }
1.37 espie 314:
315: void
316: Varq_Set(idx, val, gn)
317: int idx;
1.48 espie 318: const char *val;
1.37 espie 319: GNode *gn;
320: {
1.38 espie 321: /* We only look for a variable in the given context since anything set
322: * here will override anything in a lower context, so there's not much
323: * point in searching them all just to save a bit of memory... */
1.37 espie 324: Var *v = gn->context.locals[idx];
325:
326: if (v == NULL) {
327: v = new_var(varnames[idx], val);
328: v->flags = 0;
329: gn->context.locals[idx] = v;
330: } else {
331: Buf_Reset(&(v->val));
332: Buf_AddString(&(v->val), val);
333: }
334: if (DEBUG(VAR))
335: printf("%s:%s = %s\n", gn->name, varnames[idx], val);
336: }
337:
338: void
339: Varq_Append(idx, val, gn)
340: int idx;
1.48 espie 341: const char *val;
1.37 espie 342: GNode *gn;
343: {
1.48 espie 344: Var *v = gn->context.locals[idx];
1.37 espie 345:
346: if (v == NULL) {
347: v = new_var(varnames[idx], val);
348: v->flags = 0;
349: gn->context.locals[idx] = v;
350: } else {
351: Buf_AddSpace(&(v->val));
352: Buf_AddString(&(v->val), val);
353: }
354: if (DEBUG(VAR))
355: printf("%s:%s = %s\n", gn->name, varnames[idx], VarValue(v));
356: }
357:
358: char *
359: Varq_Value(idx, gn)
360: int idx;
361: GNode *gn;
362: {
363: Var *v = gn->context.locals[idx];
364:
365: if (v != NULL)
366: return VarValue(v);
367: else
368: return NULL;
369: }
370:
371: Boolean
372: Varq_Exists(idx, gn)
373: int idx;
374: GNode *gn;
375: {
376: return gn->context.locals[idx] != NULL;
377: }
1.1 deraadt 378:
1.35 espie 379:
1.38 espie 380: static const char *
1.35 espie 381: context_name(ctxt)
1.37 espie 382: GSymT *ctxt;
1.35 espie 383: {
384: if (ctxt == VAR_GLOBAL)
385: return "Global";
1.37 espie 386: else if (ctxt == VAR_CMD)
1.35 espie 387: return "Command";
1.37 espie 388: else
1.35 espie 389: return "Environment";
390: }
391:
1.37 espie 392: /* Create a variable, to pass to VarAdd. */
393: static Var *
394: new_var(name, val)
1.39 espie 395: const char *name;
396: const char *val;
1.37 espie 397: {
398: Var *v;
1.38 espie 399: const char *end = NULL;
1.37 espie 400:
1.38 espie 401: v = hash_create_entry(&var_info, name, &end);
1.37 espie 402:
403: if (val != NULL) {
404: size_t len = strlen(val);
405: Buf_Init(&(v->val), len+1);
406: Buf_AddChars(&(v->val), len, val);
407: } else
408: Buf_Init(&(v->val), 1);
409:
410: return v;
411: }
412:
1.38 espie 413: static Var *
414: getvar(ctxt, name, end, k)
415: GSymT *ctxt;
1.39 espie 416: const char *name;
1.38 espie 417: const char *end;
418: u_int32_t k;
1.1 deraadt 419: {
1.38 espie 420: return hash_find(ctxt, hash_lookup_interval(ctxt, name, end, k));
1.37 espie 421: }
422:
1.1 deraadt 423: /*-
424: *-----------------------------------------------------------------------
1.39 espie 425: * VarFind_interval --
1.1 deraadt 426: * Find the given variable in the given context and any other contexts
1.39 espie 427: * indicated. if end is NULL, name is a string, otherwise, only
428: * the interval name - end is concerned.
1.1 deraadt 429: *
430: * Results:
431: * A pointer to the structure describing the desired variable or
1.26 espie 432: * NULL if the variable does not exist.
1.1 deraadt 433: *
434: * Side Effects:
1.17 espie 435: * Caches env variables in the VAR_ENV context.
1.1 deraadt 436: *-----------------------------------------------------------------------
437: */
438: static Var *
1.39 espie 439: VarFind_interval(name, end, ctxt, flags)
440: const char *name; /* name to find */
441: const char *end; /* end of name */
1.35 espie 442: SymTable *ctxt; /* context in which to find it */
1.39 espie 443: int flags; /* FIND_MINE set means to look in the
444: * CTXT_GLOBAL and CTXT_CMD contexts also.
1.1 deraadt 445: * FIND_ENV set means to look in the
1.39 espie 446: * environment */
1.1 deraadt 447: {
1.38 espie 448: int idx;
449: u_int32_t k;
450:
451: idx = quick_lookup(name, &end, &k);
1.39 espie 452: return varfind(name, end, ctxt, flags, idx, k);
453: }
454:
455: static Var *
456: varfind(name, end, ctxt, flags, idx, k)
457: const char *name;
458: const char *end;
459: SymTable *ctxt;
460: int flags;
461: int idx;
462: u_int32_t k;
463: {
464: Var *v;
1.1 deraadt 465:
466: /*
467: * First look for the variable in the given context. If it's not there,
468: * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order,
469: * depending on the FIND_* flags in 'flags'
470: */
1.37 espie 471: if (ctxt == NULL)
472: v = NULL;
473: else if (ctxt == CTXT_GLOBAL || ctxt == CTXT_CMD || ctxt == CTXT_ENV)
1.38 espie 474: v = getvar((GSymT *)ctxt, name, end, k);
1.37 espie 475: else {
1.38 espie 476: if (idx == -1)
477: v = NULL;
478: else
479: v = ctxt->locals[idx];
1.37 espie 480: }
481: if (v != NULL)
482: return v;
483:
1.39 espie 484: if ((flags & FIND_MINE) && ctxt != CTXT_CMD)
1.38 espie 485: v = getvar(VAR_CMD, name, end, k);
1.37 espie 486: if (v != NULL)
487: return v;
488:
1.39 espie 489: if (!checkEnvFirst && (flags & FIND_MINE) && ctxt != CTXT_GLOBAL)
1.38 espie 490: v = getvar(VAR_GLOBAL, name, end, k);
1.37 espie 491: if (v != NULL)
492: return v;
493:
494: if ((flags & FIND_ENV)) {
495: char *env;
1.42 espie 496: char *n;
1.37 espie 497:
1.38 espie 498: v = getvar(VAR_ENV, name, end, k);
1.37 espie 499: if (v != NULL)
500: return v;
1.1 deraadt 501:
1.42 espie 502: /* getenv requires a null-terminated name */
503: n = interval_dup(name, end);
504: env = getenv(n);
505: free(n);
506: if (env != NULL)
1.37 espie 507: return VarAdd(name, env, VAR_ENV);
508: }
1.17 espie 509:
1.39 espie 510: if (checkEnvFirst && (flags & FIND_MINE) && ctxt != CTXT_GLOBAL)
1.38 espie 511: v = getvar(VAR_GLOBAL, name, end, k);
1.37 espie 512: return v;
1.1 deraadt 513: }
514:
515: /*-
516: *-----------------------------------------------------------------------
517: * VarAdd --
518: * Add a new variable of name name and value val to the given context
519: *
520: * Results:
1.17 espie 521: * The added variable
1.1 deraadt 522: *
523: * Side Effects:
1.48 espie 524: * The new variable is placed in the given context.
1.1 deraadt 525: * The name and val arguments are duplicated so they may
526: * safely be freed.
527: *-----------------------------------------------------------------------
528: */
1.17 espie 529: static Var *
530: VarAdd(name, val, ctxt)
1.39 espie 531: const char *name; /* name of variable to add */
532: const char *val; /* value to set it to */
1.37 espie 533: GSymT *ctxt; /* context in which to set it */
1.1 deraadt 534: {
1.38 espie 535: Var *v;
536: const char *end = NULL;
537: int idx;
538: u_int32_t k;
1.1 deraadt 539:
1.37 espie 540: v = new_var(name, val);
1.1 deraadt 541:
542: v->flags = 0;
543:
1.38 espie 544: idx = quick_lookup(name, &end, &k);
545:
1.48 espie 546: if (idx != -1)
1.38 espie 547: Parse_Error(PARSE_FATAL, "Trying to set dynamic variable %s",
548: v->name);
1.48 espie 549: else
1.38 espie 550: hash_insert(ctxt, hash_lookup_interval(ctxt, name, end, k), v);
1.17 espie 551: return v;
1.1 deraadt 552: }
553:
554:
555: /*-
556: *-----------------------------------------------------------------------
557: * VarDelete --
558: * Delete a variable and all the space associated with it.
559: *-----------------------------------------------------------------------
560: */
561: static void
562: VarDelete(vp)
1.48 espie 563: void *vp;
1.1 deraadt 564: {
1.48 espie 565: Var *v = (Var *) vp;
566:
1.23 espie 567: Buf_Destroy(&(v->val));
568: free(v);
1.1 deraadt 569: }
570:
571:
572:
573: /*-
574: *-----------------------------------------------------------------------
575: * Var_Delete --
576: * Remove a variable from a context.
577: *
578: * Side Effects:
579: * The Var structure is removed and freed.
580: *-----------------------------------------------------------------------
581: */
582: void
583: Var_Delete(name, ctxt)
1.48 espie 584: const char *name;
585: GSymT *ctxt;
1.1 deraadt 586: {
1.48 espie 587: Var *v;
588: u_int32_t k;
589: const char *end = NULL;
1.1 deraadt 590:
1.37 espie 591: if (DEBUG(VAR))
1.35 espie 592: printf("%s:delete %s\n", context_name(ctxt), name);
1.38 espie 593: (void)quick_lookup(name, &end, &k);
594: v = hash_remove(ctxt, hash_lookup_interval(ctxt, name, end, k));
1.37 espie 595:
1.38 espie 596: if (v != NULL)
1.30 espie 597: VarDelete(v);
1.1 deraadt 598: }
599:
600: /*-
601: *-----------------------------------------------------------------------
602: * Var_Set --
603: * Set the variable name to the value val in the given context.
604: *
605: * Side Effects:
606: * If the variable doesn't yet exist, a new record is created for it.
607: * Else the old value is freed and the new one stuck in its place
608: *
609: * Notes:
610: * The variable is searched for only in its context before being
611: * created in that context. I.e. if the context is VAR_GLOBAL,
612: * only VAR_GLOBAL->context is searched. Likewise if it is VAR_CMD, only
613: * VAR_CMD->context is searched. This is done to avoid the literally
614: * thousands of unnecessary strcmp's that used to be done to
615: * set, say, $(@) or $(<).
616: *-----------------------------------------------------------------------
617: */
618: void
1.35 espie 619: Var_Set(name, val, ctxt)
1.48 espie 620: const char *name; /* name of variable to set */
621: const char *val; /* value to give to the variable */
1.37 espie 622: GSymT *ctxt; /* context in which to set it */
1.1 deraadt 623: {
1.48 espie 624: Var *v;
1.1 deraadt 625:
626: /*
627: * We only look for a variable in the given context since anything set
628: * here will override anything in a lower context, so there's not much
629: * point in searching them all just to save a bit of memory...
630: */
1.37 espie 631: v = VarFind(name, (SymTable *)ctxt, 0);
1.38 espie 632: if (v == NULL)
1.17 espie 633: (void)VarAdd(name, val, ctxt);
1.38 espie 634: else {
1.23 espie 635: Buf_Reset(&(v->val));
636: Buf_AddString(&(v->val), val);
1.1 deraadt 637: }
1.37 espie 638: if (DEBUG(VAR))
639: printf("%s:%s = %s\n", context_name(ctxt), name, val);
1.1 deraadt 640: /*
641: * Any variables given on the command line are automatically exported
1.17 espie 642: * to the environment (as per POSIX standard).
643: * We put them into the env cache directly.
644: * (Note that additions to VAR_CMD occur very early, so VAR_ENV is
645: * actually empty at this point).
1.1 deraadt 646: */
647: if (ctxt == VAR_CMD) {
1.49 espie 648: esetenv(name, val);
1.17 espie 649: (void)VarAdd(name, val, VAR_ENV);
1.1 deraadt 650: }
651: }
652:
653: /*-
654: *-----------------------------------------------------------------------
655: * Var_Append --
656: * The variable of the given name has the given value appended to it in
657: * the given context.
658: *
659: * Side Effects:
660: * If the variable doesn't exist, it is created. Else the strings
661: * are concatenated (with a space in between).
662: *
663: * Notes:
664: * Only if the variable is being sought in the global context is the
665: * environment searched.
666: * XXX: Knows its calling circumstances in that if called with ctxt
667: * an actual target, it will only search that context since only
668: * a local variable could be being appended to. This is actually
669: * a big win and must be tolerated.
670: *-----------------------------------------------------------------------
671: */
672: void
1.35 espie 673: Var_Append(name, val, ctxt)
1.48 espie 674: const char *name; /* Name of variable to modify */
675: const char *val; /* String to append to it */
1.37 espie 676: GSymT *ctxt; /* Context in which this should occur */
1.1 deraadt 677: {
1.48 espie 678: Var *v;
1.1 deraadt 679:
1.37 espie 680: v = VarFind(name, (SymTable *)ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0);
1.1 deraadt 681:
1.26 espie 682: if (v == NULL) {
1.47 espie 683: v = VarAdd(name, val, ctxt);
1.1 deraadt 684: } else {
1.23 espie 685: Buf_AddSpace(&(v->val));
686: Buf_AddString(&(v->val), val);
1.1 deraadt 687: }
1.37 espie 688: if (DEBUG(VAR))
689: printf("%s:%s = %s\n", context_name(ctxt), name, VarValue(v));
1.1 deraadt 690: }
691:
692: /*-
693: *-----------------------------------------------------------------------
694: * Var_Exists --
695: * See if the given variable exists.
696: *
697: * Results:
698: * TRUE if it does, FALSE if it doesn't
699: *-----------------------------------------------------------------------
700: */
701: Boolean
702: Var_Exists(name, ctxt)
1.48 espie 703: const char *name; /* Variable to find */
1.37 espie 704: GSymT *ctxt; /* Context in which to start search */
1.1 deraadt 705: {
1.48 espie 706: Var *v;
1.1 deraadt 707:
1.39 espie 708: v = VarFind(name, (SymTable *)ctxt, FIND_MINE|FIND_ENV);
1.1 deraadt 709:
1.26 espie 710: if (v == NULL)
1.17 espie 711: return FALSE;
712: else
713: return TRUE;
1.1 deraadt 714: }
715:
716: /*-
717: *-----------------------------------------------------------------------
718: * Var_Value --
719: * Return the value of the named variable in the given context
720: *
721: * Results:
722: * The value if the variable exists, NULL if it doesn't
723: *-----------------------------------------------------------------------
724: */
725: char *
1.18 espie 726: Var_Value(name, ctxt)
1.48 espie 727: const char *name; /* name to find */
1.37 espie 728: GSymT *ctxt; /* context in which to search for it */
1.1 deraadt 729: {
1.48 espie 730: Var *v;
1.1 deraadt 731:
1.39 espie 732: v = VarFind(name, (SymTable *)ctxt, FIND_ENV | FIND_MINE);
1.26 espie 733: if (v != NULL)
1.23 espie 734: return VarValue(v);
1.21 espie 735: else
1.17 espie 736: return NULL;
1.1 deraadt 737: }
738:
1.45 espie 739: /*
740: *-----------------------------------------------------------------------
741: * v = var_name_with_dollar(str, &pos, ctxt, err, endc)
742: * handle variable name that contains a dollar
743: * str points to the first letter of the variable name,
744: * &pos to the current position in the name (first dollar at invocation,
745: * end of name specification at return).
746: * returns the corresponding variable.
747: *-----------------------------------------------------------------------
748: */
749: static Var *
750: var_name_with_dollar(str, pos, ctxt, err, endc)
1.48 espie 751: char *str; /* First dollar in variable name */
752: char **pos; /* Current position in variable spec */
1.45 espie 753: SymTable *ctxt; /* The context for the variable */
754: Boolean err; /* TRUE if undefined variables are an error */
755: char endc; /* End character for spec */
756: {
1.48 espie 757: BUFFER buf; /* Store the variable name */
758: size_t sublen; /* Deal with recursive expansions */
759: Boolean subfree;
760: char *n; /* Sub name */
761: Var *v;
1.45 espie 762:
763: Buf_Init(&buf, MAKE_BSIZE);
764:
1.48 espie 765: for (;;) {
1.45 espie 766: Buf_AddInterval(&buf, str, *pos);
767: n = Var_Parse(*pos, ctxt, err, &sublen, &subfree);
768: if (n != NULL)
769: Buf_AddString(&buf, n);
770: if (subfree)
771: free(n);
772: *pos += sublen;
773: str = *pos;
774: for (; **pos != '$'; (*pos)++) {
775: if (**pos == '\0' || **pos == endc || **pos == ':') {
1.51 ! espie 776: Buf_AddInterval(&buf, str, *pos);
1.45 espie 777: v = VarFind(Buf_Retrieve(&buf), ctxt, FIND_ENV | FIND_MINE);
778: Buf_Destroy(&buf);
779: return v;
780: }
781: }
782: }
783: }
784:
1.1 deraadt 785: /*-
786: *-----------------------------------------------------------------------
787: * Var_Parse --
788: * Given the start of a variable invocation, extract the variable
789: * name and find its value, then modify it according to the
790: * specification.
791: *
792: * Results:
793: * The (possibly-modified) value of the variable or var_Error if the
794: * specification is invalid. The length of the specification is
795: * placed in *lengthPtr (for invalid specifications, this is just
796: * 2...?).
797: * A Boolean in *freePtr telling whether the returned string should
798: * be freed by the caller.
799: *-----------------------------------------------------------------------
800: */
801: char *
1.35 espie 802: Var_Parse(str, ctxt, err, lengthPtr, freePtr)
1.44 espie 803: char *str; /* The string to parse */
804: SymTable *ctxt; /* The context for the variable */
805: Boolean err; /* TRUE if undefined variables are an error */
806: size_t *lengthPtr; /* OUT: The length of the specification */
807: Boolean *freePtr; /* OUT: TRUE if caller should free result */
808: {
809: char *tstr; /* Pointer into str */
810: Var *v; /* Variable in invocation */
811: char endc; /* Ending character when variable in parens
1.1 deraadt 812: * or braces */
1.44 espie 813: char *start;
814: char *val; /* Variable value */
815: u_int32_t k;
816: int idx;
1.5 millert 817:
1.1 deraadt 818: *freePtr = FALSE;
1.44 espie 819: start = str++;
1.5 millert 820:
1.44 espie 821: val = NULL;
1.45 espie 822: v = NULL;
823: idx = 0;
1.44 espie 824:
825: if (*str != '(' && *str != '{') {
826: tstr = str + 1;
827: *lengthPtr = 2;
828: endc = '\0';
1.1 deraadt 829: } else {
1.44 espie 830: endc = *str == '(' ? ')' : '}';
831: str++;
1.5 millert 832:
1.44 espie 833: /* Find eventual modifiers in the variable */
1.45 espie 834: for (tstr = str; *tstr != ':'; tstr++) {
835: if (*tstr == '$') {
836: v = var_name_with_dollar(str, &tstr, ctxt, err, endc);
837: if (*tstr == '\0' || *tstr == endc)
838: endc = '\0';
839: break;
840: } else if (*tstr == '\0' || *tstr == endc) {
1.44 espie 841: endc = '\0';
842: break;
1.1 deraadt 843: }
1.45 espie 844: }
1.44 espie 845: *lengthPtr = tstr+1 - start;
846: }
1.5 millert 847:
1.45 espie 848: if (v == NULL) {
849: idx = quick_lookup(str, &tstr, &k);
850: v = varfind(str, tstr, ctxt, FIND_ENV | FIND_MINE, idx, k);
851: }
1.44 espie 852: if (v == NULL) {
853: /* Find out about D and F forms of local variables. */
854: if (idx == -1 && tstr == str+2 && (str[1] == 'D' || str[1] == 'F')) {
855: switch (*str) {
856: case '@':
857: idx = TARGET_INDEX;
858: break;
859: case '!':
860: idx = ARCHIVE_INDEX;
861: break;
862: case '*':
863: idx = PREFIX_INDEX;
864: break;
865: case '%':
866: idx = MEMBER_INDEX;
867: break;
868: default:
869: break;
1.1 deraadt 870: }
1.44 espie 871: /* This is a DF form, check if we can expand it now. */
872: if (idx != -1 && ctxt != NULL && ctxt != CTXT_GLOBAL) {
873: v = varfind(str, str+1, ctxt, 0, idx, 0);
874: /* No need for nested expansion or anything, as we're
875: * the only one who sets these things and we sure don't
876: * do nested invocations in them... */
877: if (v != NULL) {
878: val = VarValue(v);
879: if (str[1] == 'D')
880: val = Var_GetHead(val);
881: else
882: val = Var_GetTail(val);
1.1 deraadt 883: *freePtr = TRUE;
1.44 espie 884: }
1.1 deraadt 885: }
886: }
1.44 espie 887: } else {
888: if (v->flags & VAR_IN_USE)
889: Fatal("Variable %s is recursive.", v->name);
890: /*NOTREACHED*/
891: else
892: v->flags |= VAR_IN_USE;
893: /* Before doing any modification, we have to make sure the value
894: * has been fully expanded. If it looks like recursion might be
895: * necessary (there's a dollar sign somewhere in the variable's value)
896: * we just call Var_Subst to do any other substitutions that are
897: * necessary. Note that the value returned by Var_Subst will have
898: * been dynamically-allocated, so it will need freeing when we
899: * return. */
900: val = VarValue(v);
901: if (strchr(val, '$') != NULL) {
902: val = Var_Subst(val, ctxt, err);
903: *freePtr = TRUE;
904: }
905:
906: v->flags &= ~VAR_IN_USE;
1.1 deraadt 907: }
1.44 espie 908: if (endc != '\0')
909: val = VarModifiers_Apply(val, ctxt, err, freePtr, tstr+1, endc,
1.42 espie 910: lengthPtr);
1.44 espie 911: if (val == NULL) {
912: /* Dynamic source that can't be expanded for now: copy the var
913: * specification instead. */
914: if (idx != -1 && (ctxt == NULL || ctxt == CTXT_GLOBAL)) {
1.42 espie 915: *freePtr = TRUE;
1.44 espie 916: val = interval_dup(start, start+ *lengthPtr);
917: } else
918: val = err ? var_Error : varNoError;
1.42 espie 919: }
1.44 espie 920:
921: return val;
1.42 espie 922: }
923:
1.1 deraadt 924: /*-
925: *-----------------------------------------------------------------------
926: * Var_Subst --
1.24 espie 927: * Substitute for all variables in a string in a context
1.1 deraadt 928: * If undefErr is TRUE, Parse_Error will be called when an undefined
929: * variable is encountered.
930: *
931: * Results:
932: * The resulting string.
933: *
934: * Side Effects:
935: * None. The old string must be freed by the caller
936: *-----------------------------------------------------------------------
937: */
938: char *
1.24 espie 939: Var_Subst(str, ctxt, undefErr)
1.1 deraadt 940: char *str; /* the string in which to substitute */
1.35 espie 941: SymTable *ctxt; /* the context wherein to find variables */
1.1 deraadt 942: Boolean undefErr; /* TRUE if undefineds are an error */
943: {
1.24 espie 944: BUFFER buf; /* Buffer for forming things */
1.1 deraadt 945: static Boolean errorReported; /* Set true if an error has already
946: * been reported to prevent a plethora
947: * of messages when recursing */
948:
1.23 espie 949: Buf_Init(&buf, MAKE_BSIZE);
1.1 deraadt 950: errorReported = FALSE;
951:
1.24 espie 952: for (;;) {
953: char *val; /* Value to substitute for a variable */
954: size_t length; /* Length of the variable invocation */
955: Boolean doFree; /* Set true if val should be freed */
956: const char *cp;
957:
958: /* copy uninteresting stuff */
959: for (cp = str; *str != '\0' && *str != '$'; str++)
960: ;
961: Buf_AddInterval(&buf, cp, str);
962: if (*str == '\0')
963: break;
964: if (str[1] == '$') {
965: /* A dollar sign may be escaped with another dollar sign. */
966: Buf_AddChar(&buf, '$');
967: str += 2;
968: continue;
969: }
970: val = Var_Parse(str, ctxt, undefErr, &length, &doFree);
971: /* When we come down here, val should either point to the
972: * value of this variable, suitably modified, or be NULL.
973: * Length should be the total length of the potential
974: * variable invocation (from $ to end character...) */
975: if (val == var_Error || val == varNoError) {
976: /* If performing old-time variable substitution, skip over
977: * the variable and continue with the substitution. Otherwise,
978: * store the dollar sign and advance str so we continue with
979: * the string... */
980: if (oldVars) {
981: str += length;
982: } else if (undefErr) {
983: /* If variable is undefined, complain and skip the
984: * variable. The complaint will stop us from doing anything
985: * when the file is parsed. */
986: if (!errorReported) {
987: Parse_Error(PARSE_FATAL,
988: "Undefined variable \"%.*s\"",length,str);
989: }
990: str += length;
991: errorReported = TRUE;
992: } else {
993: Buf_AddChar(&buf, *str);
994: str += 1;
995: }
996: } else {
997: /* We've now got a variable structure to store in. But first,
998: * advance the string pointer. */
999: str += length;
1000:
1001: /* Copy all the characters from the variable value straight
1002: * into the new string. */
1003: Buf_AddString(&buf, val);
1004: if (doFree)
1005: free(val);
1006: }
1007: }
1008: return Buf_Retrieve(&buf);
1009: }
1.1 deraadt 1010:
1.24 espie 1011: /*-
1012: *-----------------------------------------------------------------------
1013: * Var_SubstVar --
1014: * Substitute for one variable in the given string in the given context
1015: * If undefErr is TRUE, Parse_Error will be called when an undefined
1.50 espie 1016: * variable is encountered. Returns the string with substitutions.
1.24 espie 1017: *-----------------------------------------------------------------------
1018: */
1.50 espie 1019: char *
1020: Var_SubstVar(str, var, val, estimate)
1021: const char *str; /* The string in which to substitute */
1.24 espie 1022: const char *var; /* Named variable */
1.50 espie 1023: const char *val; /* Its value */
1024: size_t estimate; /* Size estimate for the result buffer */
1.24 espie 1025: {
1.50 espie 1026: BUFFER buf; /* Where to store the result */
1.24 espie 1027:
1.50 espie 1028: Buf_Init(&buf, estimate);
1.24 espie 1029: for (;;) {
1.50 espie 1030: const char *start;
1031: /* Copy uninteresting stuff */
1032: for (start = str; *str != '\0' && *str != '$'; str++)
1.24 espie 1033: ;
1.50 espie 1034: Buf_AddInterval(&buf, start, str);
1035:
1036: start = str;
1037: if (*str++ == '\0')
1.24 espie 1038: break;
1.50 espie 1039: str++;
1040: /* and escaped dollars */
1041: if (start[1] == '$') {
1042: Buf_AddInterval(&buf, start, start+2);
1.24 espie 1043: continue;
1044: }
1.50 espie 1045: /* Simple variable, if it's not us, copy. */
1046: if (start[1] != '(' && start[1] != '{') {
1047: if (start[1] != *var || var[1] != '\0') {
1048: Buf_AddChars(&buf, 2, start);
1.1 deraadt 1049: continue;
1.24 espie 1050: }
1.1 deraadt 1051: } else {
1.50 espie 1052: const char *p;
1.24 espie 1053: char endc;
1.1 deraadt 1054:
1.50 espie 1055: if (start[1] == '(')
1.24 espie 1056: endc = ')';
1.50 espie 1057: else
1.24 espie 1058: endc = '}';
1059:
1060: /* Find the end of the variable specification. */
1.50 espie 1061: p = str;
1.24 espie 1062: while (*p != '\0' && *p != ':' && *p != endc && *p != '$')
1063: p++;
1064: /* A variable inside the variable. We don't know how to
1065: * expand the external variable at this point, so we try
1066: * again with the nested variable. */
1067: if (*p == '$') {
1.50 espie 1068: Buf_AddInterval(&buf, start, p);
1.24 espie 1069: str = p;
1070: continue;
1.1 deraadt 1071: }
1.5 millert 1072:
1.50 espie 1073: if (strncmp(var, str, p - str) != 0 ||
1074: var[p - str] != '\0') {
1.24 espie 1075: /* Not the variable we want to expand. */
1.50 espie 1076: Buf_AddInterval(&buf, start, p);
1.24 espie 1077: str = p;
1078: continue;
1079: }
1.50 espie 1080: if (*p == ':') {
1081: size_t length; /* Length of the variable invocation */
1082: Boolean doFree; /* Set true if val should be freed */
1083: char *newval; /* Value substituted for a variable */
1084:
1085: length = p - str + 1;
1086: doFree = FALSE;
1087:
1088: /* val won't be freed since doFree == FALSE, but
1089: * VarModifiers_Apply doesn't know that, hence the cast. */
1090: newval = VarModifiers_Apply((char *)val, NULL, FALSE,
1091: &doFree, p+1, endc, &length);
1092: Buf_AddString(&buf, newval);
1093: if (doFree)
1094: free(newval);
1095: str += length;
1096: continue;
1097: } else
1098: str = p+1;
1.1 deraadt 1099: }
1.50 espie 1100: Buf_AddString(&buf, val);
1.1 deraadt 1101: }
1.50 espie 1102: return Buf_Retrieve(&buf);
1.1 deraadt 1103: }
1104:
1105: /*-
1106: *-----------------------------------------------------------------------
1107: * Var_Init --
1108: * Initialize the module
1109: *
1110: * Side Effects:
1.5 millert 1111: * The VAR_CMD and VAR_GLOBAL contexts are created
1.1 deraadt 1112: *-----------------------------------------------------------------------
1113: */
1114: void
1.33 espie 1115: Var_Init()
1.1 deraadt 1116: {
1.37 espie 1117: static GSymT global_vars, cmd_vars, env_vars;
1.35 espie 1118:
1119: VAR_GLOBAL = &global_vars;
1120: VAR_CMD = &cmd_vars;
1121: VAR_ENV = &env_vars;
1.38 espie 1122: hash_init(VAR_GLOBAL, 10, &var_info);
1123: hash_init(VAR_CMD, 5, &var_info);
1124: hash_init(VAR_ENV, 5, &var_info);
1.37 espie 1125: CTXT_GLOBAL = (SymTable *)VAR_GLOBAL;
1126: CTXT_CMD = (SymTable *)VAR_CMD;
1127: CTXT_ENV = (SymTable *)VAR_ENV;
1.1 deraadt 1128: }
1129:
1130:
1131: void
1.33 espie 1132: Var_End()
1.1 deraadt 1133: {
1.37 espie 1134: #ifdef CLEANUP
1.38 espie 1135: Var *v;
1136: unsigned int i;
1137:
1138: for (v = hash_first(VAR_GLOBAL, &i); v != NULL;
1139: v = hash_next(VAR_GLOBAL, &i))
1140: VarDelete(v);
1141: for (v = hash_first(VAR_CMD, &i); v != NULL;
1142: v = hash_next(VAR_CMD, &i))
1143: VarDelete(v);
1144: for (v = hash_first(VAR_ENV, &i); v != NULL;
1145: v = hash_next(VAR_ENV, &i))
1146: VarDelete(v);
1.37 espie 1147: #endif
1.1 deraadt 1148: }
1.5 millert 1149:
1.1 deraadt 1150:
1151: /****************** PRINT DEBUGGING INFO *****************/
1.31 espie 1152: static void
1153: VarPrintVar(vp)
1.32 espie 1154: void *vp;
1.1 deraadt 1155: {
1.31 espie 1156: Var *v = (Var *)vp;
1157:
1.23 espie 1158: printf("%-16s = %s\n", v->name, VarValue(v));
1.1 deraadt 1159: }
1160:
1161: /*-
1162: *-----------------------------------------------------------------------
1163: * Var_Dump --
1164: * print all variables in a context
1165: *-----------------------------------------------------------------------
1166: */
1167: void
1.35 espie 1168: Var_Dump(ctxt)
1.37 espie 1169: GSymT *ctxt;
1.1 deraadt 1170: {
1.38 espie 1171: Var *v;
1172: unsigned int i;
1173:
1174: for (v = hash_first(ctxt, &i); v != NULL;
1175: v = hash_next(ctxt, &i))
1176: VarPrintVar(v);
1.1 deraadt 1177: }
1.37 espie 1178:
1.46 espie 1179:
1180: #ifdef POSIX
1181:
1182: static const char *quotable = " \t\n\\'\"";
1183:
1184: /* In POSIX mode, variable assignments passed on the command line are
1185: * propagated to sub makes through MAKEFLAGS.
1186: */
1187: void
1188: Var_AddCmdline(name)
1189: const char *name;
1190: {
1191: Var *v;
1192: unsigned int i;
1193: BUFFER buf;
1194: char *s;
1195:
1196: Buf_Init(&buf, MAKE_BSIZE);
1197:
1198: for (v = hash_first(VAR_CMD, &i); v != NULL;
1199: v = hash_next(VAR_CMD, &i)) {
1200: /* We assume variable names don't need quoting */
1201: Buf_AddString(&buf, v->name);
1202: Buf_AddChar(&buf, '=');
1203: for (s = VarValue(v); *s != '\0'; s++) {
1204: if (strchr(quotable, *s))
1205: Buf_AddChar(&buf, '\\');
1206: Buf_AddChar(&buf, *s);
1207: }
1208: Buf_AddSpace(&buf);
1209: }
1210: Var_Append(name, Buf_Retrieve(&buf), VAR_GLOBAL);
1211: Buf_Destroy(&buf);
1212: }
1213: #endif