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