xref: /openbsd/usr.bin/make/var.c (revision d485f761)
1 /*	$OpenPackages$ */
2 /*	$OpenBSD: var.c,v 1.55 2001/05/23 12:34:51 espie Exp $	*/
3 /*	$NetBSD: var.c,v 1.18 1997/03/18 19:24:46 christos Exp $	*/
4 
5 /*
6  * Copyright (c) 1999,2000 Marc Espie.
7  *
8  * Extensive code modifications for the OpenBSD project.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OPENBSD
23  * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 /*
32  * Copyright (c) 1988, 1989, 1990, 1993
33  *	The Regents of the University of California.  All rights reserved.
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 #include <sys/types.h>
70 #include <assert.h>
71 #include <stddef.h>
72 #include <stdio.h>
73 #include <stdlib.h>
74 #include <string.h>
75 
76 #include "config.h"
77 #include "defines.h"
78 #include "buf.h"
79 #include "stats.h"
80 #include "ohash.h"
81 #include "varmodifiers.h"
82 #include "var.h"
83 #include "varname.h"
84 #include "error.h"
85 #include "str.h"
86 #include "var_int.h"
87 #include "memory.h"
88 #include "symtable.h"
89 #include "gnode.h"
90 
91 /* extended indices for System V stuff */
92 #define FTARGET_INDEX	7
93 #define DTARGET_INDEX	8
94 #define FPREFIX_INDEX	9
95 #define DPREFIX_INDEX	10
96 #define FARCHIVE_INDEX	11
97 #define DARCHIVE_INDEX	12
98 #define FMEMBER_INDEX	13
99 #define DMEMBER_INDEX	14
100 
101 #define EXTENDED2SIMPLE(i)	(((i)-LOCAL_SIZE)/2)
102 #define IS_EXTENDED_F(i)	((i)%2 == 1)
103 
104 /*
105  * This is a harmless return value for Var_Parse that can be used by Var_Subst
106  * to determine if there was an error in parsing -- easier than returning
107  * a flag, as things outside this module don't give a hoot.
108  */
109 char	var_Error[] = "";
110 
111 /*
112  * Similar to var_Error, but returned when the 'err' flag for Var_Parse is
113  * set false. Why not just use a constant? Well, gcc likes to condense
114  * identical string instances...
115  */
116 static char	varNoError[] = "";
117 
118 /*
119  * Variable values are obtained from four different contexts:
120  *	1) the process environment. The process environment itself
121  *	   may not be changed, but these variables may be modified,
122  *	   unless make is invoked with -e, in which case those variables
123  *	   are unmodifiable and supersede the global context.
124  *	2) the global context. Variables set in the Makefile are located in
125  *	    the global context. It is the penultimate context searched when
126  *	    substituting.
127  *	3) the command-line context. All variables set on the command line
128  *	   are placed in this context. They are UNALTERABLE once placed here.
129  *	4) the local context. Each target has associated with it a context
130  *	   list. On this list are located the structures describing such
131  *	   local variables as $(@) and $(*)
132  * The four contexts are searched in the reverse order from which they are
133  * listed.
134  */
135 GSymT		*VAR_GLOBAL;	/* variables from the makefile */
136 GSymT		*VAR_CMD;	/* variables defined on the command-line */
137 
138 static SymTable *CTXT_GLOBAL, *CTXT_CMD;
139 
140 
141 static char *varnames[] = {
142     TARGET,
143     PREFIX,
144     ARCHIVE,
145     MEMBER,
146     OODATE,
147     ALLSRC,
148     IMPSRC,
149     FTARGET,
150     DTARGET,
151     FPREFIX,
152     DPREFIX,
153     FARCHIVE,
154     DARCHIVE,
155     FMEMBER,
156     DMEMBER
157     };
158 
159 
160 #define FIND_MINE	0x1   /* look in CTXT_CMD and CTXT_GLOBAL */
161 #define FIND_ENV	0x2   /* look in the environment */
162 
163 typedef struct Var_ {
164     BUFFER	  val;		/* its value */
165     unsigned int  flags;	/* miscellaneous status flags */
166 #define VAR_IN_USE	1	/* Variable's value currently being used.
167 				 * Used to avoid recursion */
168 #define VAR_READ_ONLY	2	/* Environment variable not modifiable */
169 #define VAR_FROM_ENV	4	/* Var was read from env */
170 #define VAR_DUMMY	8	/* Var does not exist, actually */
171     char	  name[1];	/* the variable's name */
172 }  Var;
173 
174 
175 static struct ohash_info var_info = {
176 	offsetof(Var, name),
177     NULL, hash_alloc, hash_free, element_alloc };
178 static int quick_lookup(const char *, const char **, u_int32_t *);
179 #define VarValue(v)	Buf_Retrieve(&((v)->val))
180 static Var *varfind(const char *, const char *, SymTable *, int, int, u_int32_t);
181 static Var *VarFindi(const char *, const char *, SymTable *, int);
182 static Var *VarAdd(const char *, const char *, u_int32_t, const char *, GSymT *);
183 static void VarDelete(void *);
184 static void VarPrintVar(Var *);
185 static const char *context_name(GSymT *);
186 static Var *new_var(const char *, const char *, const char *);
187 static Var *getvar(GSymT *, const char *, const char *, u_int32_t);
188 static Var *create_var(const char *, const char *);
189 static Var *var_from_env(const char *, const char *, u_int32_t);
190 static void var_init_string(Var *, const char *);
191 
192 static const char *find_0(const char *);
193 static const char *find_rparen(const char *);
194 static const char *find_ket(const char *);
195 typedef const char * (*find_t)(const char *);
196 static find_t find_pos(int);
197 
198 /* retrieve the hashed values  for well-known variables.  */
199 #include    "varhashconsts.h"
200 
201 void
202 SymTable_Init(ctxt)
203     SymTable	*ctxt;
204 {
205     static SymTable sym_template;
206     memcpy(ctxt, &sym_template, sizeof(*ctxt));
207 }
208 
209 #ifdef CLEANUP
210 void
211 SymTable_Destroy(ctxt)
212     SymTable	*ctxt;
213 {
214     int i;
215 
216     for (i = 0; i < LOCAL_SIZE; i++)
217 	if (ctxt->locals[i] != NULL)
218 	    VarDelete(ctxt->locals[i]);
219 }
220 #endif
221 
222 static int
223 quick_lookup(name, end, pk)
224     const char *name;
225     const char **end;
226     u_int32_t *pk;
227 {
228     size_t len;
229 
230     *pk = ohash_interval(name, end);
231     len = *end - name;
232 	/* substitute short version for long local name */
233     switch (*pk % MAGICSLOTS1) { 	    /* MAGICSLOTS should be the    */
234     case K_LONGALLSRC % MAGICSLOTS1:	    /* smallest constant yielding  */
235 					    /* distinct case values	   */
236 	if (*pk == K_LONGALLSRC && strncmp(name, LONGALLSRC, len) == 0 &&
237 	    len == strlen(LONGALLSRC))
238 	    return ALLSRC_INDEX;
239 	break;
240     case K_LONGARCHIVE % MAGICSLOTS1:
241 	if (*pk == K_LONGARCHIVE && strncmp(name, LONGARCHIVE, len) == 0 &&
242 	    len == strlen(LONGARCHIVE))
243 	    return ARCHIVE_INDEX;
244 	break;
245     case K_LONGIMPSRC % MAGICSLOTS1:
246 	if (*pk == K_LONGIMPSRC && strncmp(name, LONGIMPSRC, len) == 0 &&
247 	    len == strlen(LONGIMPSRC))
248 	    return IMPSRC_INDEX;
249 	break;
250     case K_LONGMEMBER % MAGICSLOTS1:
251 	if (*pk == K_LONGMEMBER && strncmp(name, LONGMEMBER, len) == 0 &&
252 	    len == strlen(LONGMEMBER))
253 	    return MEMBER_INDEX;
254 	break;
255     case K_LONGOODATE % MAGICSLOTS1:
256 	if (*pk == K_LONGOODATE && strncmp(name, LONGOODATE, len) == 0 &&
257 	    len == strlen(LONGOODATE))
258 	    return OODATE_INDEX;
259 	break;
260     case K_LONGPREFIX % MAGICSLOTS1:
261 	if (*pk == K_LONGPREFIX && strncmp(name, LONGPREFIX, len) == 0 &&
262 	    len == strlen(LONGPREFIX))
263 	    return PREFIX_INDEX;
264 	break;
265     case K_LONGTARGET % MAGICSLOTS1:
266 	if (*pk == K_LONGTARGET && strncmp(name, LONGTARGET, len) == 0 &&
267 	    len == strlen(LONGTARGET))
268 	    return TARGET_INDEX;
269 	break;
270     case K_TARGET % MAGICSLOTS1:
271 	if (name[0] == TARGET[0] && len == 1)
272 	    return TARGET_INDEX;
273 	break;
274     case K_OODATE % MAGICSLOTS1:
275 	if (name[0] == OODATE[0] && len == 1)
276 	    return OODATE_INDEX;
277 	break;
278     case K_ALLSRC % MAGICSLOTS1:
279 	if (name[0] == ALLSRC[0] && len == 1)
280 	    return ALLSRC_INDEX;
281 	break;
282     case K_IMPSRC % MAGICSLOTS1:
283 	if (name[0] == IMPSRC[0] && len == 1)
284 	    return IMPSRC_INDEX;
285 	break;
286     case K_PREFIX % MAGICSLOTS1:
287 	if (name[0] == PREFIX[0] && len == 1)
288 	    return PREFIX_INDEX;
289 	break;
290     case K_ARCHIVE % MAGICSLOTS1:
291 	if (name[0] == ARCHIVE[0] && len == 1)
292 	    return ARCHIVE_INDEX;
293 	break;
294     case K_MEMBER % MAGICSLOTS1:
295 	if (name[0] == MEMBER[0] && len == 1)
296 	    return MEMBER_INDEX;
297 	break;
298     case K_FTARGET % MAGICSLOTS1:
299     	if (name[0] == FTARGET[0] && name[1] == FTARGET[1] && len == 2)
300 	    return FTARGET_INDEX;
301 	break;
302     case K_DTARGET % MAGICSLOTS1:
303     	if (name[0] == DTARGET[0] && name[1] == DTARGET[1] && len == 2)
304 	    return DTARGET_INDEX;
305 	break;
306     case K_FPREFIX % MAGICSLOTS1:
307     	if (name[0] == FPREFIX[0] && name[1] == FPREFIX[1] && len == 2)
308 	    return FPREFIX_INDEX;
309 	break;
310     case K_DPREFIX % MAGICSLOTS1:
311     	if (name[0] == DPREFIX[0] && name[1] == DPREFIX[1] && len == 2)
312 	    return DPREFIX_INDEX;
313 	break;
314     case K_FARCHIVE % MAGICSLOTS1:
315     	if (name[0] == FARCHIVE[0] && name[1] == FARCHIVE[1] && len == 2)
316 	    return FARCHIVE_INDEX;
317 	break;
318     case K_DARCHIVE % MAGICSLOTS1:
319     	if (name[0] == DARCHIVE[0] && name[1] == DARCHIVE[1] && len == 2)
320 	    return DARCHIVE_INDEX;
321 	break;
322     case K_FMEMBER % MAGICSLOTS1:
323     	if (name[0] == FMEMBER[0] && name[1] == FMEMBER[1] && len == 2)
324 	    return FMEMBER_INDEX;
325 	break;
326     case K_DMEMBER % MAGICSLOTS1:
327     	if (name[0] == DMEMBER[0] && name[1] == DMEMBER[1] && len == 2)
328 	    return DMEMBER_INDEX;
329 	break;
330     default:
331 	break;
332     }
333     return -1;
334 }
335 
336 void
337 Varq_Set(idx, val, gn)
338     int 	idx;
339     const char	*val;
340     GNode	*gn;
341 {
342     /* We only look for a variable in the given context since anything set
343      * here will override anything in a lower context, so there's not much
344      * point in searching them all just to save a bit of memory...  */
345     Var *v = gn->context.locals[idx];
346 
347     if (v == NULL) {
348 	v = new_var(varnames[idx], NULL, val);
349 	v->flags = 0;
350 	gn->context.locals[idx] = v;
351     } else {
352 	Buf_Reset(&(v->val));
353 	Buf_AddString(&(v->val), val);
354 
355     }
356     if (DEBUG(VAR))
357 	printf("%s:%s = %s\n", gn->name, varnames[idx], val);
358 }
359 
360 void
361 Varq_Append(idx, val, gn)
362     int 	idx;
363     const char	*val;
364     GNode	*gn;
365 {
366     Var *v = gn->context.locals[idx];
367 
368     if (v == NULL) {
369 	v = new_var(varnames[idx], NULL, val);
370 	v->flags = 0;
371 	gn->context.locals[idx] = v;
372     } else {
373 	Buf_AddSpace(&(v->val));
374 	Buf_AddString(&(v->val), val);
375     }
376     if (DEBUG(VAR))
377 	printf("%s:%s = %s\n", gn->name, varnames[idx], VarValue(v));
378 }
379 
380 char *
381 Varq_Value(idx, gn)
382     int 	idx;
383     GNode	*gn;
384 {
385     Var *v = gn->context.locals[idx];
386 
387     if (v == NULL)
388     	return NULL;
389     else
390 	return VarValue(v);
391 }
392 
393 static const char *
394 context_name(ctxt)
395     GSymT *ctxt;
396 {
397     if (ctxt == VAR_GLOBAL)
398 	return "Global";
399     if (ctxt == VAR_CMD)
400 	return "Command";
401     return "Error";
402 }
403 
404 /* We separate var creation proper from setting of initial value:
405  * VAR_DUMMY corresponds to `lazy' setup, e.g., always create global
406  * variable at first lookup, and then fill it up when value is wanted.
407  * This avoids looking through the environment several times.
408  */
409 static Var *
410 create_var(name, end)
411     const char	*name;
412     const char	*end;
413 {
414     return ohash_create_entry(&var_info, name, &end);
415 }
416 
417 /* Set the initial value a var should have */
418 static void
419 var_init_string(v, val)
420     Var *v;
421     const char *val;
422 {
423     size_t len;
424 
425     len = strlen(val);
426     Buf_Init(&(v->val), len+1);
427     Buf_AddChars(&(v->val), len, val);
428 }
429 
430 static Var *
431 new_var(name, end, val)
432     const char	*name;
433     const char	*end;
434     const char	*val;
435 {
436     Var 	*v;
437 
438     v = create_var(name, end);
439 #ifdef STATS_VAR_LOOKUP
440     STAT_VAR_CREATION++;
441 #endif
442     if (val != NULL)
443 	var_init_string(v, val);
444     else
445 	Buf_Init(&(v->val), 1);
446 
447     return v;
448 }
449 
450 static Var *
451 var_from_env(name, end, k)
452     const char	*name;
453     const char *end;
454     u_int32_t	k;
455 {
456     char	*env;
457     Var 	*v;
458 
459     /* getenv requires a null-terminated name, so we create the var
460      * structure first.  */
461     v = create_var(name, end);
462     env = getenv(v->name);
463     if (env == NULL)
464 	v->flags = VAR_DUMMY;
465     else {
466 	var_init_string(v, env);
467 	if (checkEnvFirst)
468 	    v->flags = VAR_READ_ONLY | VAR_FROM_ENV;
469 	else
470 	    v->flags = VAR_FROM_ENV;
471     }
472 
473 #ifdef STATS_VAR_LOOKUP
474     STAT_VAR_FROM_ENV++;
475 #endif
476 
477     ohash_insert(VAR_GLOBAL, ohash_lookup_interval(VAR_GLOBAL, name, end, k), v);
478     return v;
479 }
480 
481 static Var *
482 getvar(ctxt, name, end, k)
483     GSymT	*ctxt;
484     const char	*name;
485     const char	*end;
486     u_int32_t	k;
487 {
488     return ohash_find(ctxt, ohash_lookup_interval(ctxt, name, end, k));
489 }
490 
491 /*-
492  *-----------------------------------------------------------------------
493  * VarFindi --
494  *	Find the given variable in the given context and any other contexts
495  *	indicated.  if end is NULL, name is a string, otherwise, only
496  *	the interval name - end  is concerned.
497  *
498  * Results:
499  *	A pointer to the structure describing the desired variable or
500  *	NULL if the variable does not exist.
501  *-----------------------------------------------------------------------
502  */
503 static Var *
504 VarFindi(name, end, ctxt, flags)
505     const char		*name;	/* name to find */
506     const char		*end;	/* end of name */
507     SymTable		*ctxt;	/* context in which to find it */
508     int 		flags;	/* FIND_MINE set means to look in the
509 				 * CTXT_GLOBAL and CTXT_CMD contexts also.
510 				 * FIND_ENV set means to look in the
511 				 * environment */
512 {
513     u_int32_t		k;
514     int 		idx;
515 
516 #ifdef STATS_VAR_LOOKUP
517     STAT_VAR_FIND++;
518 #endif
519 
520     idx = quick_lookup(name, &end, &k);
521     return varfind(name, end, ctxt, flags, idx, k);
522 }
523 
524 static Var *
525 varfind(name, end, ctxt, flags, idx, k)
526     const char		*name;
527     const char		*end;
528     SymTable		*ctxt;
529     int 		flags;
530     int 		idx;
531     u_int32_t		k;
532 {
533     Var 		*v;
534 
535     /* Handle local variables first */
536     if (idx != -1) {
537     	if (ctxt != NULL && ctxt != CTXT_CMD && ctxt != CTXT_GLOBAL) {
538 		if (idx < LOCAL_SIZE)
539 		    return ctxt->locals[idx];
540 		else
541 		    return ctxt->locals[EXTENDED2SIMPLE(idx)];
542 	} else
543 	    return NULL;
544     }
545     /* First look for the variable in the given context. If it's not there,
546        look for it in CTXT_CMD, CTXT_GLOBAL and the environment,
547        depending on the FIND_* flags in 'flags' */
548     if (ctxt == CTXT_CMD || ctxt == CTXT_GLOBAL)
549 	v = getvar((GSymT *)ctxt, name, end, k);
550     else
551     	v = NULL;
552 
553     if (v == NULL)
554 	switch (flags) {
555 	case 0:
556 	    break;
557 	case FIND_MINE:
558 	    if (ctxt != CTXT_CMD)
559 		v = getvar(VAR_CMD, name, end, k);
560 	    if (v == NULL && ctxt != CTXT_GLOBAL)
561 		v = getvar(VAR_GLOBAL, name, end, k);
562 	    break;
563 	case FIND_ENV:
564 	    v = var_from_env(name, end, k);
565 	    break;
566 	case FIND_ENV | FIND_MINE:
567 	    if (ctxt != CTXT_CMD)
568 		v = getvar(VAR_CMD, name, end, k);
569 	    if (v == NULL) {
570 		if (ctxt != CTXT_GLOBAL)
571 		    v = getvar(VAR_GLOBAL, name, end, k);
572 		if (v == NULL)
573 		    v = var_from_env(name, end, k);
574 		else if (checkEnvFirst && (v->flags & VAR_FROM_ENV) == 0) {
575 		    char *env;
576 
577 		    env = getenv(v->name);
578 		    if (env != NULL) {
579 			Buf_Reset(&(v->val));
580 			Buf_AddString(&(v->val), env);
581 		    }
582 		    /* XXX even if no such env variable, fake it, to avoid
583 		     * further lookup */
584 		    v->flags |= VAR_FROM_ENV;
585 		}
586 	    }
587 	    break;
588 	}
589     return v;
590 }
591 
592 /*-
593  *-----------------------------------------------------------------------
594  * VarAdd  --
595  *	Add a new variable of name name and value val to the given context
596  *
597  * Results:
598  *	The added variable.
599  *
600  * Side Effects:
601  *	The new variable is placed in the given context.
602  *	The name and val arguments are duplicated so they may
603  *	safely be freed.
604  *-----------------------------------------------------------------------
605  */
606 static Var *
607 VarAdd(name, end, k, val, ctxt)
608     const char	*name;	/* name of variable to add */
609     const char	*end;
610     u_int32_t 	k;
611     const char	*val;	/* value to set it to */
612     GSymT	*ctxt;	/* context in which to set it */
613 {
614     Var   *v;
615 
616     v = new_var(name, end, val);
617 
618     v->flags = 0;
619 
620     ohash_insert(ctxt, ohash_lookup_interval(ctxt, name, end, k), v);
621     if (DEBUG(VAR))
622 	printf("%s:%s = %s\n", context_name(ctxt), v->name, val);
623     return v;
624 }
625 
626 /*-
627  *-----------------------------------------------------------------------
628  * VarDelete  --
629  *	Delete a variable and all the space associated with it.
630  *-----------------------------------------------------------------------
631  */
632 static void
633 VarDelete(vp)
634     void *vp;
635 {
636     Var *v = (Var *)vp;
637 
638     if ((v->flags & VAR_DUMMY) == 0)
639 	Buf_Destroy(&(v->val));
640     free(v);
641 }
642 
643 
644 
645 void
646 Var_Delete(name)
647     const char	  *name;
648 {
649     Var 	*v;
650     u_int32_t 	k;
651     unsigned int slot;
652     const char 	*end = NULL;
653     int		idx;
654 
655 
656     if (DEBUG(VAR))
657 	printf("delete %s\n", name);
658 
659     idx = quick_lookup(name, &end, &k);
660     if (idx != -1)
661     	Parse_Error(PARSE_FATAL, "Trying to delete dynamic variable");
662     slot = ohash_lookup_interval(VAR_GLOBAL, name, end, k);
663     v = ohash_find(VAR_GLOBAL, slot);
664     if (v != NULL && (v->flags & VAR_READ_ONLY) == 0) {
665 	ohash_remove(VAR_GLOBAL, slot);
666 	VarDelete(v);
667     }
668 }
669 
670 /* 	The variable is searched for only in its context before being
671  *	created in that context. I.e. if the context is CTXT_GLOBAL,
672  *	only CTXT_GLOBAL is searched. Likewise if it is CTXT_CMD, only
673  *	CTXT_CMD is searched.
674  */
675 void
676 Var_Seti(name, end, val, ctxt)
677     const char	*name;	/* name of variable to set */
678     const char	*end;
679     const char	*val;	/* value to give to the variable */
680     GSymT	*ctxt;	/* context in which to set it */
681 {
682     Var   *v;
683     u_int32_t	k;
684     int		idx;
685 
686     idx = quick_lookup(name, &end, &k);
687     if (idx != -1)
688     	Parse_Error(PARSE_FATAL, "Trying to set dynamic variable $%s",
689 	    varnames[idx]);
690 
691     /* We only look for a variable in the given context since anything set
692      * here will override anything in a lower context, so there's not much
693      * point in searching them all just to save a bit of memory...  */
694     v = varfind(name, end, (SymTable *)ctxt, 0, idx, k);
695     if (v == NULL)
696 	v = VarAdd(name, end, k, val, ctxt);
697     else {
698 	if ((v->flags & VAR_READ_ONLY) == 0) {
699 	    if ((v->flags & VAR_DUMMY) == 0) {
700 		Buf_Reset(&(v->val));
701 		Buf_AddString(&(v->val), val);
702 	    } else {
703 		var_init_string(v, val);
704 		v->flags &= ~VAR_DUMMY;
705 	    }
706 
707 	}
708     }
709     if (DEBUG(VAR))
710 	printf("%s:%s = %s\n", context_name(ctxt), v->name, val);
711     /* Any variables given on the command line are automatically exported
712      * to the environment (as per POSIX standard).  */
713     if (ctxt == VAR_CMD)
714 	esetenv(v->name, val);
715 }
716 
717 void
718 Var_Appendi(name, end, val, ctxt)
719     const char	*name;	/* Name of variable to modify */
720     const char	*end;
721     const char	*val;	/* String to append to it */
722     GSymT	*ctxt;	/* Context in which this should occur */
723 {
724     Var   *v;
725     u_int32_t	k;
726     int		idx;
727 
728     assert(ctxt == VAR_GLOBAL || ctxt == VAR_CMD);
729 
730     idx = quick_lookup(name, &end, &k);
731     if (idx != -1)
732     	Parse_Error(PARSE_FATAL, "Trying to append to dynamic variable $%s",
733 	    varnames[idx]);
734 
735     v = varfind(name, end, (SymTable *)ctxt, FIND_ENV, idx, k);
736 
737     if ((v->flags & VAR_READ_ONLY) == 0) {
738 	if ((v->flags & VAR_DUMMY) == 0) {
739 	    Buf_AddSpace(&(v->val));
740 	    Buf_AddString(&(v->val), val);
741 	} else {
742 	    var_init_string(v, val);
743 	    v->flags &= ~VAR_DUMMY;
744 	}
745 
746     }
747     if (DEBUG(VAR))
748 	printf("%s:%s = %s\n", context_name(ctxt), v->name, VarValue(v));
749 }
750 
751 char *
752 Var_Valuei(name, end)
753     const char	*name;	/* name to find */
754     const char	*end;
755 {
756     Var 	   *v;
757 
758     v = VarFindi(name, end, NULL, FIND_ENV | FIND_MINE);
759     if (v != NULL && (v->flags & VAR_DUMMY) == 0)
760 	return VarValue(v);
761     else
762 	return NULL;
763 }
764 
765 static const char *
766 find_0(p)
767 	const char *p;
768 {
769 	while (*p != '$' && *p != '\0' && *p != ':')
770 		p++;
771 	return p;
772 }
773 
774 static const char *
775 find_rparen(p)
776 	const char *p;
777 {
778 	while (*p != '$' && *p != '\0' && *p != ')' && *p != ':')
779 		p++;
780 	return p;
781 }
782 
783 static const char *
784 find_ket(p)
785 	const char *p;
786 {
787 	while (*p != '$' && *p != '\0' && *p != '}' && *p != ':')
788 		p++;
789 	return p;
790 }
791 
792 static find_t
793 find_pos(c)
794 	int c;
795 {
796 	switch(c) {
797 	case '\0':
798 		return find_0;
799 	case ')':
800 		return find_rparen;
801 	case '}':
802 		return find_ket;
803 	default:
804 		return 0;
805 	}
806 }
807 
808 size_t
809 Var_ParseSkip(str, ctxt, result)
810     const char	*str;
811     SymTable	*ctxt;
812     bool *result;
813 {
814     const char	*tstr;		/* Pointer into str */
815     Var 	*v;		/* Variable in invocation */
816     char	endc;		/* Ending character when variable in parens
817 				 * or braces */
818     const char	*start;
819     size_t	length;
820     struct Name name;
821 
822     v = NULL;
823     start = str;
824     str++;
825 
826     if (*str != '(' && *str != '{') {
827 	name.tofree = false;
828 	tstr = str + 1;
829 	length = 2;
830 	endc = '\0';
831     } else {
832 	endc = *str == '(' ? ')' : '}';
833 	str++;
834 
835 	/* Find eventual modifiers in the variable */
836 	tstr = VarName_Get(str, &name, ctxt, false, find_pos(endc));
837 	VarName_Free(&name);
838 	length = tstr - start;
839 	if (*tstr != 0)
840 	    length++;
841     }
842 
843     if (result != NULL)
844 	*result = true;
845     if (*tstr == ':' && endc != '\0')
846 	 if (VarModifiers_Apply(NULL, NULL, ctxt, true, NULL, tstr, endc,
847 	    &length) == var_Error)
848 		*result = false;
849     return length;
850 }
851 
852 /* As of now, Var_ParseBuffer is just a wrapper around Var_Parse. For
853  * speed, it may be better to revisit the implementation to do things
854  * directly. */
855 bool
856 Var_ParseBuffer(buf, str, ctxt, err, lengthPtr)
857     Buffer	buf;
858     const char	*str;
859     SymTable	*ctxt;
860     bool	err;
861     size_t	*lengthPtr;
862 {
863     char	*result;
864     bool	freeIt;
865 
866     result = Var_Parse(str, ctxt, err, lengthPtr, &freeIt);
867     if (result == var_Error)
868 	return false;
869 
870     Buf_AddString(buf, result);
871     if (freeIt)
872 	free(result);
873     return true;
874 }
875 
876 char *
877 Var_Parse(str, ctxt, err, lengthPtr, freePtr)
878     const char	*str;		/* The string to parse */
879     SymTable	*ctxt;		/* The context for the variable */
880     bool	err;		/* true if undefined variables are an error */
881     size_t	*lengthPtr;	/* OUT: The length of the specification */
882     bool	*freePtr;	/* OUT: true if caller should free result */
883 {
884     const char	*tstr;		/* Pointer into str */
885     Var 	*v;		/* Variable in invocation */
886     char	endc;		/* Ending character when variable in parens
887 				 * or braces */
888     struct Name	name;
889     const char	*start;
890     char	*val;		/* Variable value  */
891     u_int32_t	k;
892     int 	idx;
893 
894     *freePtr = false;
895     start = str++;
896 
897     val = NULL;
898     v = NULL;
899     idx = -1;
900 
901     if (*str != '(' && *str != '{') {
902     	name.s = str;
903 	name.e = str+1;
904 	name.tofree = false;
905 	tstr = str + 1;
906 	*lengthPtr = 2;
907 	endc = '\0';
908     } else {
909 	endc = *str == '(' ? ')' : '}';
910 	str++;
911 
912 	/* Find eventual modifiers in the variable */
913 	tstr = VarName_Get(str, &name, ctxt, false, find_pos(endc));
914 	*lengthPtr = tstr - start;
915 	if (*tstr != '\0')
916 		(*lengthPtr)++;
917     }
918 
919     idx = quick_lookup(name.s, &name.e, &k);
920     v = varfind(name.s, name.e, ctxt, FIND_ENV | FIND_MINE, idx, k);
921     if (v != NULL && (v->flags & VAR_DUMMY) == 0) {
922 	if (v->flags & VAR_IN_USE)
923 	    Fatal("Variable %s is recursive.", v->name);
924 	    /*NOTREACHED*/
925 	else
926 	    v->flags |= VAR_IN_USE;
927 
928 	/* Before doing any modification, we have to make sure the value
929 	 * has been fully expanded. If it looks like recursion might be
930 	 * necessary (there's a dollar sign somewhere in the variable's value)
931 	 * we just call Var_Subst to do any other substitutions that are
932 	 * necessary. Note that the value returned by Var_Subst will have
933 	 * been dynamically-allocated, so it will need freeing when we
934 	 * return.  */
935 	val = VarValue(v);
936 	if (idx == -1) {
937 	    if (strchr(val, '$') != NULL) {
938 		val = Var_Subst(val, ctxt, err);
939 		*freePtr = true;
940 	    }
941 	} else if (idx >= LOCAL_SIZE) {
942 	    if (IS_EXTENDED_F(idx))
943 		val = Var_GetTail(val);
944 	    else
945 		val = Var_GetHead(val);
946 	    *freePtr = true;
947 	}
948 	v->flags &= ~VAR_IN_USE;
949     }
950     if (*tstr == ':' && endc != '\0')
951 	val = VarModifiers_Apply(val, &name, ctxt, err, freePtr, tstr, endc,
952 	    lengthPtr);
953     if (val == NULL) {
954 	val = err ? var_Error : varNoError;
955 	/* Dynamic source */
956 	if (idx != -1) {
957 	    /* can't be expanded for now: copy the var spec instead. */
958 	    if (ctxt == NULL || ctxt == CTXT_GLOBAL || ctxt == CTXT_CMD) {
959 		*freePtr = true;
960 		val = Str_dupi(start, start+ *lengthPtr);
961 	    } else {
962 	    /* somehow, this should have been expanded already. */
963 		GNode *n;
964 
965 		n = (GNode *)(((char *)ctxt) - offsetof(GNode, context));
966 		if (idx >= LOCAL_SIZE)
967 			idx = EXTENDED2SIMPLE(idx);
968 		switch(idx) {
969 		case IMPSRC_INDEX:
970 		    Fatal("Using $< in a non-suffix rule context is a GNUmake idiom (line %lu of %s)",
971 			n->lineno, n->fname);
972 		default:
973 		    Error("Using undefined dynamic variable $%s (line %lu of %s)",
974 			varnames[idx], n->lineno, n->fname);
975 		    break;
976 		}
977 	    }
978 	}
979     }
980     VarName_Free(&name);
981     return val;
982 }
983 
984 char *
985 Var_Subst(str, ctxt, undefErr)
986     const char	  *str; 	    /* the string in which to substitute */
987     SymTable	  *ctxt;	    /* the context wherein to find variables */
988     bool	  undefErr;	    /* true if undefineds are an error */
989 {
990     BUFFER	  buf;		    /* Buffer for forming things */
991     static bool errorReported;   /* Set true if an error has already
992 				     * been reported to prevent a plethora
993 				     * of messages when recursing */
994 
995     Buf_Init(&buf, MAKE_BSIZE);
996     errorReported = false;
997 
998     for (;;) {
999 	char		*val;		/* Value to substitute for a variable */
1000 	size_t		length; 	/* Length of the variable invocation */
1001 	bool 	doFree; 	/* Set true if val should be freed */
1002 	const char *cp;
1003 
1004 	/* copy uninteresting stuff */
1005 	for (cp = str; *str != '\0' && *str != '$'; str++)
1006 	    ;
1007 	Buf_Addi(&buf, cp, str);
1008 	if (*str == '\0')
1009 	    break;
1010 	if (str[1] == '$') {
1011 	    /* A dollar sign may be escaped with another dollar sign.  */
1012 	    Buf_AddChar(&buf, '$');
1013 	    str += 2;
1014 	    continue;
1015 	}
1016 	val = Var_Parse(str, ctxt, undefErr, &length, &doFree);
1017 	/* When we come down here, val should either point to the
1018 	 * value of this variable, suitably modified, or be NULL.
1019 	 * Length should be the total length of the potential
1020 	 * variable invocation (from $ to end character...) */
1021 	if (val == var_Error || val == varNoError) {
1022 	    /* If performing old-time variable substitution, skip over
1023 	     * the variable and continue with the substitution. Otherwise,
1024 	     * store the dollar sign and advance str so we continue with
1025 	     * the string...  */
1026 	    if (oldVars)
1027 		str += length;
1028 	    else if (undefErr) {
1029 		/* If variable is undefined, complain and skip the
1030 		 * variable. The complaint will stop us from doing anything
1031 		 * when the file is parsed.  */
1032 		if (!errorReported)
1033 		    Parse_Error(PARSE_FATAL,
1034 				 "Undefined variable \"%.*s\"",length,str);
1035 		str += length;
1036 		errorReported = true;
1037 	    } else {
1038 		Buf_AddChar(&buf, *str);
1039 		str++;
1040 	    }
1041 	} else {
1042 	    /* We've now got a variable structure to store in. But first,
1043 	     * advance the string pointer.  */
1044 	    str += length;
1045 
1046 	    /* Copy all the characters from the variable value straight
1047 	     * into the new string.  */
1048 	    Buf_AddString(&buf, val);
1049 	    if (doFree)
1050 		free(val);
1051 	}
1052     }
1053     return  Buf_Retrieve(&buf);
1054 }
1055 
1056 void
1057 Var_SubstVar(buf, str, var, val)
1058     Buffer	buf;
1059     const char	*str;		/* The string in which to substitute */
1060     const char	*var;		/* Named variable */
1061     const char	*val;		/* Its value */
1062 {
1063 
1064     assert(*var != '\0');
1065 
1066     for (;;) {
1067 	const char *start;
1068 	/* Copy uninteresting stuff */
1069 	for (start = str; *str != '\0' && *str != '$'; str++)
1070 	    ;
1071 	Buf_Addi(buf, start, str);
1072 
1073 	start = str;
1074 	if (*str++ == '\0')
1075 	    break;
1076 	str++;
1077 	/* and escaped dollars */
1078 	if (start[1] == '$') {
1079 	    Buf_Addi(buf, start, start+2);
1080 	    continue;
1081 	}
1082 	/* Simple variable, if it's not us, copy.  */
1083 	if (start[1] != '(' && start[1] != '{') {
1084 	    if (start[1] != *var || var[1] != '\0') {
1085 		Buf_AddChars(buf, 2, start);
1086 		continue;
1087 	    }
1088 	} else {
1089 	    const char *p;
1090 	    char endc;
1091 
1092 	    if (start[1] == '(')
1093 		endc = ')';
1094 	    else
1095 		endc = '}';
1096 
1097 	    /* Find the end of the variable specification.  */
1098 	    p = str;
1099 	    while (*p != '\0' && *p != ':' && *p != endc && *p != '$')
1100 		p++;
1101 	    /* A variable inside the variable.	We don't know how to
1102 	     * expand the external variable at this point, so we try
1103 	     * again with the nested variable.	*/
1104 	    if (*p == '$') {
1105 		Buf_Addi(buf, start, p);
1106 		str = p;
1107 		continue;
1108 	    }
1109 
1110 	    if (strncmp(var, str, p - str) != 0 ||
1111 		var[p - str] != '\0') {
1112 		/* Not the variable we want to expand.	*/
1113 		Buf_Addi(buf, start, p);
1114 		str = p;
1115 		continue;
1116 	    }
1117 	    if (*p == ':') {
1118 		size_t	length; 	/* Length of the variable invocation */
1119 		bool doFree; 	/* Set true if val should be freed */
1120 		char	*newval;	/* Value substituted for a variable */
1121 		struct Name name;
1122 
1123 		length = p - str + 1;
1124 		doFree = false;
1125 		name.s = var;
1126 		name.e = var + (p-str);
1127 
1128 		/* val won't be freed since doFree == false, but
1129 		 * VarModifiers_Apply doesn't know that, hence the cast. */
1130 		newval = VarModifiers_Apply((char *)val, &name, NULL, false,
1131 		    &doFree, p, endc, &length);
1132 		Buf_AddString(buf, newval);
1133 		if (doFree)
1134 		    free(newval);
1135 		str += length;
1136 		continue;
1137 	    } else
1138 		str = p+1;
1139 	}
1140 	Buf_AddString(buf, val);
1141     }
1142 }
1143 
1144 /*-
1145  *-----------------------------------------------------------------------
1146  * Var_Init --
1147  *	Initialize the module
1148  *
1149  * Side Effects:
1150  *	The CTXT_CMD and CTXT_GLOBAL contexts are initialized
1151  *-----------------------------------------------------------------------
1152  */
1153 void
1154 Var_Init()
1155 {
1156     static GSymT global_vars, cmd_vars;
1157 
1158     VAR_GLOBAL = &global_vars;
1159     VAR_CMD = &cmd_vars;
1160     ohash_init(VAR_GLOBAL, 10, &var_info);
1161     ohash_init(VAR_CMD, 5, &var_info);
1162     CTXT_GLOBAL = (SymTable *)VAR_GLOBAL;
1163     CTXT_CMD = (SymTable *)VAR_CMD;
1164 
1165     VarModifiers_Init();
1166 }
1167 
1168 
1169 #ifdef CLEANUP
1170 void
1171 Var_End()
1172 {
1173     Var *v;
1174     unsigned int i;
1175 
1176     for (v = ohash_first(VAR_GLOBAL, &i); v != NULL;
1177 	v = ohash_next(VAR_GLOBAL, &i))
1178 	    VarDelete(v);
1179     for (v = ohash_first(VAR_CMD, &i); v != NULL;
1180 	v = ohash_next(VAR_CMD, &i))
1181 	    VarDelete(v);
1182 }
1183 #endif
1184 
1185 static const char *interpret(int);
1186 
1187 static const char *
1188 interpret(f)
1189     int f;
1190 {
1191     if (f & VAR_DUMMY)
1192 	return "(D)";
1193     return "";
1194 }
1195 
1196 
1197 /****************** PRINT DEBUGGING INFO *****************/
1198 static void
1199 VarPrintVar(v)
1200     Var    *v;
1201 {
1202     printf("%-16s%s = %s\n", v->name, interpret(v->flags),
1203 	(v->flags & VAR_DUMMY) == 0 ? VarValue(v) : "(none)");
1204 }
1205 
1206 void
1207 Var_Dump()
1208 {
1209     Var *v;
1210     unsigned int i;
1211 
1212     printf("#*** Global Variables:\n");
1213 
1214     for (v = ohash_first(VAR_GLOBAL, &i); v != NULL;
1215 	v = ohash_next(VAR_GLOBAL, &i))
1216 	VarPrintVar(v);
1217 
1218     printf("#*** Command-line Variables:\n");
1219 
1220     for (v = ohash_first(VAR_CMD, &i); v != NULL; v = ohash_next(VAR_CMD, &i))
1221 	VarPrintVar(v);
1222 }
1223 
1224 static const char *quotable = " \t\n\\'\"";
1225 
1226 /* In POSIX mode, variable assignments passed on the command line are
1227  * propagated to sub makes through MAKEFLAGS.
1228  */
1229 void
1230 Var_AddCmdline(name)
1231 	const char *name;
1232 {
1233     Var *v;
1234     unsigned int i;
1235     BUFFER buf;
1236     char *s;
1237 
1238     Buf_Init(&buf, MAKE_BSIZE);
1239 
1240     for (v = ohash_first(VAR_CMD, &i); v != NULL;
1241 	v = ohash_next(VAR_CMD, &i)) {
1242 		/* We assume variable names don't need quoting */
1243 		Buf_AddString(&buf, v->name);
1244 		Buf_AddChar(&buf, '=');
1245 		for (s = VarValue(v); *s != '\0'; s++) {
1246 			if (strchr(quotable, *s))
1247 				Buf_AddChar(&buf, '\\');
1248 			Buf_AddChar(&buf, *s);
1249 		}
1250 		Buf_AddSpace(&buf);
1251     }
1252     Var_Append(name, Buf_Retrieve(&buf), VAR_GLOBAL);
1253     Buf_Destroy(&buf);
1254 }
1255