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