Don't cast lvavalues.
[dragonfly.git] / usr.bin / make / var.c
CommitLineData
edf6dd37 1/*-
984263bc
MD
2 * Copyright (c) 1988, 1989, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1989 by Berkeley Softworks
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Adam de Boor.
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 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
1de703da
MD
37 *
38 * @(#)var.c 8.3 (Berkeley) 3/19/94
39 * $FreeBSD: src/usr.bin/make/var.c,v 1.16.2.3 2002/02/27 14:18:57 cjc Exp $
4103da37 40 * $DragonFly: src/usr.bin/make/var.c,v 1.61 2005/02/06 23:22:04 okumoto Exp $
984263bc
MD
41 */
42
984263bc
MD
43/*-
44 * var.c --
45 * Variable-handling functions
46 *
47 * Interface:
48 * Var_Set Set the value of a variable in the given
49 * context. The variable is created if it doesn't
50 * yet exist. The value and variable name need not
51 * be preserved.
52 *
53 * Var_Append Append more characters to an existing variable
54 * in the given context. The variable needn't
55 * exist already -- it will be created if it doesn't.
56 * A space is placed between the old value and the
57 * new one.
58 *
59 * Var_Exists See if a variable exists.
60 *
61 * Var_Value Return the value of a variable in a context or
62 * NULL if the variable is undefined.
63 *
64 * Var_Subst Substitute named variable, or all variables if
65 * NULL in a string using
66 * the given context as the top-most one. If the
67 * third argument is non-zero, Parse_Error is
68 * called if any variables are undefined.
69 *
70 * Var_Parse Parse a variable expansion from a string and
71 * return the result and the number of characters
72 * consumed.
73 *
74 * Var_Delete Delete a variable in a context.
75 *
76 * Var_Init Initialize this module.
77 *
78 * Debugging:
79 * Var_Dump Print out all variables defined in the given
80 * context.
81 *
82 * XXX: There's a lot of duplication in these functions.
83 */
84
9863ce62
MO
85#include <ctype.h>
86#include <stdlib.h>
87#include <string.h>
88
89#include "buf.h"
90#include "config.h"
91#include "globals.h"
92#include "GNode.h"
93#include "make.h"
89aa31f8 94#include "nonints.h"
9863ce62
MO
95#include "parse.h"
96#include "str.h"
97#include "targ.h"
98#include "util.h"
99#include "var.h"
984263bc
MD
100
101/*
102 * This is a harmless return value for Var_Parse that can be used by Var_Subst
103 * to determine if there was an error in parsing -- easier than returning
104 * a flag, as things outside this module don't give a hoot.
105 */
106char var_Error[] = "";
107
108/*
109 * Similar to var_Error, but returned when the 'err' flag for Var_Parse is
110 * set false. Why not just use a constant? Well, gcc likes to condense
111 * identical string instances...
112 */
113static char varNoError[] = "";
114
115/*
116 * Internally, variables are contained in four different contexts.
117 * 1) the environment. They may not be changed. If an environment
118 * variable is appended-to, the result is placed in the global
119 * 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 */
b83dbac0
MO
131GNode *VAR_GLOBAL; /* variables from the makefile */
132GNode *VAR_CMD; /* variables defined on the command-line */
984263bc 133
b83dbac0
MO
134#define FIND_CMD 0x1 /* look in VAR_CMD when searching */
135#define FIND_GLOBAL 0x2 /* look in VAR_GLOBAL as well */
136#define FIND_ENV 0x4 /* look in the environment also */
984263bc 137
de3fa3f4
MO
138#define OPEN_PAREN '('
139#define CLOSE_PAREN ')'
140#define OPEN_BRACKET '{'
141#define CLOSE_BRACKET '}'
142
5cfd56df
MO
143static Var *VarCreate(const char [], const char [], int);
144static void VarDestroy(Var *, Boolean);
9cf296a4 145static char *VarGetPattern(GNode *, int, char **, int, int *, size_t *,
b83dbac0 146 VarPattern *);
07d5ef71 147static char *VarModify(char *, VarModifyProc *, void *);
9edd457e 148static int VarPrintVar(void *, void *);
984263bc
MD
149
150/*-
151 *-----------------------------------------------------------------------
152 * VarCmp --
153 * See if the given variable matches the named one. Called from
154 * Lst_Find when searching for a variable of a given name.
155 *
156 * Results:
157 * 0 if they match. non-zero otherwise.
158 *
159 * Side Effects:
160 * none
161 *-----------------------------------------------------------------------
162 */
163static int
d98710ab 164VarCmp(const void *v, const void *name)
984263bc 165{
8e4eb27a 166
d98710ab 167 return (strcmp(name, ((const Var *)v)->name));
984263bc
MD
168}
169
db29db6d
MD
170/*-
171 *-----------------------------------------------------------------------
172 * VarPossiblyExpand --
b83dbac0 173 * Expand a variable name's embedded variables in the given context.
db29db6d
MD
174 *
175 * Results:
b83dbac0 176 * The contents of name, possibly expanded.
db29db6d
MD
177 *-----------------------------------------------------------------------
178 */
605113f3
MO
179static char *
180VarPossiblyExpand(const char *name, GNode *ctxt)
db29db6d 181{
69021aba
MO
182 char *tmp;
183
184 /*
185 * XXX make a temporary copy of the name because Var_Subst insists
186 * on writing into the string.
187 */
188 tmp = estrdup(name);
189 if (strchr(name, '$') != NULL) {
190 Buffer *buf;
191 char *str;
192
193 buf = Var_Subst(NULL, tmp, ctxt, 0);
194 str = Buf_GetAll(buf, NULL);
195 Buf_Destroy(buf, FALSE);
196
197 return(str);
198 } else {
199 return(tmp);
200 }
db29db6d
MD
201}
202
984263bc
MD
203/*-
204 *-----------------------------------------------------------------------
205 * VarFind --
206 * Find the given variable in the given context and any other contexts
207 * indicated.
208 *
84de9e23
MD
209 * Flags:
210 * FIND_GLOBAL set means look in the VAR_GLOBAL context too
211 * FIND_CMD set means to look in the VAR_CMD context too
212 * FIND_ENV set means to look in the environment
213 *
984263bc
MD
214 * Results:
215 * A pointer to the structure describing the desired variable or
9edd457e 216 * NULL if the variable does not exist.
984263bc
MD
217 *
218 * Side Effects:
219 * None
220 *-----------------------------------------------------------------------
221 */
222static Var *
ea6d42d8 223VarFind(const char *name, GNode *ctxt, int flags)
984263bc
MD
224{
225 Boolean localCheckEnvFirst;
e035e56b 226 LstNode *var;
984263bc
MD
227 Var *v;
228
275de3ca
MO
229 /*
230 * If the variable name begins with a '.', it could very well be one of
231 * the local ones. We check the name against all the local variables
232 * and substitute the short version in for 'name' if it matches one of
233 * them.
234 */
4103da37 235 if (name[0] == '.')
275de3ca
MO
236 switch (name[1]) {
237 case 'A':
238 if (!strcmp(name, ".ALLSRC"))
239 name = ALLSRC;
240 if (!strcmp(name, ".ARCHIVE"))
241 name = ARCHIVE;
242 break;
243 case 'I':
244 if (!strcmp(name, ".IMPSRC"))
245 name = IMPSRC;
246 break;
247 case 'M':
248 if (!strcmp(name, ".MEMBER"))
249 name = MEMBER;
250 break;
251 case 'O':
252 if (!strcmp(name, ".OODATE"))
253 name = OODATE;
254 break;
255 case 'P':
256 if (!strcmp(name, ".PREFIX"))
257 name = PREFIX;
258 break;
259 case 'T':
260 if (!strcmp(name, ".TARGET"))
261 name = TARGET;
262 break;
4103da37
MO
263 default:
264 break;
275de3ca 265 }
984263bc
MD
266
267 /*
268 * Note whether this is one of the specific variables we were told through
269 * the -E flag to use environment-variable-override for.
270 */
0a7e0b85 271 if (Lst_Find(&envFirstVars, name, (CompareProc *)strcmp) != NULL) {
984263bc
MD
272 localCheckEnvFirst = TRUE;
273 } else {
274 localCheckEnvFirst = FALSE;
275 }
276
277 /*
278 * First look for the variable in the given context. If it's not there,
279 * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order,
280 * depending on the FIND_* flags in 'flags'
281 */
0a7e0b85 282 var = Lst_Find(&ctxt->context, name, VarCmp);
984263bc 283
9edd457e 284 if ((var == NULL) && (flags & FIND_CMD) && (ctxt != VAR_CMD)) {
0a7e0b85 285 var = Lst_Find(&VAR_CMD->context, name, VarCmp);
984263bc 286 }
9edd457e 287 if ((var == NULL) && (flags & FIND_GLOBAL) && (ctxt != VAR_GLOBAL) &&
984263bc
MD
288 !checkEnvFirst && !localCheckEnvFirst)
289 {
0a7e0b85 290 var = Lst_Find(&VAR_GLOBAL->context, name, VarCmp);
984263bc 291 }
9edd457e 292 if ((var == NULL) && (flags & FIND_ENV)) {
984263bc
MD
293 char *env;
294
fbfaa208 295 if ((env = getenv(name)) != NULL) {
5cfd56df 296 v = VarCreate(name, env, VAR_FROM_ENV);
984263bc 297
984263bc
MD
298 return (v);
299 } else if ((checkEnvFirst || localCheckEnvFirst) &&
300 (flags & FIND_GLOBAL) && (ctxt != VAR_GLOBAL))
301 {
0a7e0b85 302 var = Lst_Find(&VAR_GLOBAL->context, name, VarCmp);
9edd457e 303 if (var == NULL) {
9a4c88c2 304 return (NULL);
984263bc 305 } else {
9a4c88c2 306 return (Lst_Datum(var));
984263bc
MD
307 }
308 } else {
9a4c88c2 309 return (NULL);
984263bc 310 }
9edd457e 311 } else if (var == NULL) {
9a4c88c2 312 return (NULL);
984263bc 313 } else {
9a4c88c2 314 return (Lst_Datum(var));
984263bc
MD
315 }
316}
317
318/*-
319 *-----------------------------------------------------------------------
320 * VarAdd --
84de9e23 321 * Add a new variable of name name and value val to the given context.
984263bc
MD
322 *
323 * Results:
324 * None
325 *
326 * Side Effects:
327 * The new variable is placed at the front of the given context
328 * The name and val arguments are duplicated so they may
329 * safely be freed.
330 *-----------------------------------------------------------------------
331 */
332static void
ea6d42d8 333VarAdd(const char *name, const char *val, GNode *ctxt)
984263bc 334{
5cfd56df
MO
335 Lst_AtFront(&ctxt->context, VarCreate(name, val, 0));
336
337 DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, name, val));
338}
339
340/*
341 * Create a Var object.
342 *
343 * @param name Name of variable.
344 * @param value Value of variable.
345 * @param flags Flags set on variable.
346 */
347static Var *
348VarCreate(const char name[], const char value[], int flags)
349{
350 Var *v;
984263bc 351
9a4c88c2 352 v = emalloc(sizeof(Var));
5cfd56df
MO
353 v->name = estrdup(name);
354 v->val = Buf_Init(0);
355 v->flags = flags;
3be279c4 356
5cfd56df
MO
357 if (value != NULL) {
358 Buf_Append(v->val, value);
fcf95e9c 359 }
5cfd56df 360 return (v);
984263bc
MD
361}
362
5cfd56df
MO
363/*
364 * Destroy a Var object.
984263bc 365 *
5cfd56df
MO
366 * @param v Object to destroy.
367 * @param f true if internal buffer in Buffer object is to be
368 * removed.
984263bc
MD
369 */
370static void
5cfd56df 371VarDestroy(Var *v, Boolean f)
984263bc 372{
5cfd56df 373 Buf_Destroy(v->val, f);
984263bc 374 free(v->name);
9edd457e 375 free(v);
984263bc
MD
376}
377
984263bc
MD
378/*-
379 *-----------------------------------------------------------------------
380 * Var_Delete --
381 * Remove a variable from a context.
382 *
383 * Results:
384 * None.
385 *
386 * Side Effects:
387 * The Var structure is removed and freed.
388 *
389 *-----------------------------------------------------------------------
390 */
391void
7034e6b9 392Var_Delete(const char *name, GNode *ctxt)
984263bc 393{
e035e56b 394 LstNode *ln;
984263bc 395
913800f5 396 DEBUGF(VAR, ("%s:delete %s\n", ctxt->name, name));
0a7e0b85 397 ln = Lst_Find(&ctxt->context, name, VarCmp);
9edd457e 398 if (ln != NULL) {
5cfd56df 399 VarDestroy(Lst_Datum(ln), TRUE);
0a7e0b85 400 Lst_Remove(&ctxt->context, ln);
984263bc
MD
401 }
402}
403
404/*-
405 *-----------------------------------------------------------------------
406 * Var_Set --
407 * Set the variable name to the value val in the given context.
408 *
409 * Results:
410 * None.
411 *
412 * Side Effects:
413 * If the variable doesn't yet exist, a new record is created for it.
414 * Else the old value is freed and the new one stuck in its place
415 *
416 * Notes:
417 * The variable is searched for only in its context before being
418 * created in that context. I.e. if the context is VAR_GLOBAL,
419 * only VAR_GLOBAL->context is searched. Likewise if it is VAR_CMD, only
420 * VAR_CMD->context is searched. This is done to avoid the literally
421 * thousands of unnecessary strcmp's that used to be done to
422 * set, say, $(@) or $(<).
423 *-----------------------------------------------------------------------
424 */
425void
ea6d42d8 426Var_Set(const char *name, const char *val, GNode *ctxt)
984263bc 427{
605113f3
MO
428 Var *v;
429 char *n;
984263bc
MD
430
431 /*
432 * We only look for a variable in the given context since anything set
433 * here will override anything in a lower context, so there's not much
434 * point in searching them all just to save a bit of memory...
435 */
605113f3
MO
436 n = VarPossiblyExpand(name, ctxt);
437 v = VarFind(n, ctxt, 0);
9a4c88c2 438 if (v == NULL) {
605113f3 439 VarAdd(n, val, ctxt);
984263bc 440 } else {
0964826d 441 Buf_Clear(v->val);
fcf95e9c 442 Buf_Append(v->val, val);
984263bc 443
605113f3 444 DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, n, val));
984263bc
MD
445 }
446 /*
447 * Any variables given on the command line are automatically exported
448 * to the environment (as per POSIX standard)
449 */
9edd457e 450 if (ctxt == VAR_CMD || (v != (Var *)NULL && (v->flags & VAR_TO_ENV))) {
605113f3 451 setenv(n, val, 1);
984263bc 452 }
605113f3 453 free(n);
984263bc
MD
454}
455
be7281c9
MD
456/*
457 * Var_SetEnv --
458 * Set the VAR_TO_ENV flag on a variable
459 */
460void
ea6d42d8 461Var_SetEnv(const char *name, GNode *ctxt)
be7281c9 462{
f72581d7 463 Var *v;
be7281c9
MD
464
465 v = VarFind(name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV);
466 if (v) {
467 if ((v->flags & VAR_TO_ENV) == 0) {
ea01430f 468 v->flags |= VAR_TO_ENV;
be7281c9
MD
469 setenv(v->name, Buf_GetAll(v->val, NULL), 1);
470 }
471 } else {
472 Error("Cannot set environment flag on non-existant variable %s", name);
473 }
474}
475
984263bc
MD
476/*-
477 *-----------------------------------------------------------------------
478 * Var_Append --
479 * The variable of the given name has the given value appended to it in
480 * the given context.
481 *
482 * Results:
483 * None
484 *
485 * Side Effects:
486 * If the variable doesn't exist, it is created. Else the strings
487 * are concatenated (with a space in between).
488 *
489 * Notes:
490 * Only if the variable is being sought in the global context is the
491 * environment searched.
492 * XXX: Knows its calling circumstances in that if called with ctxt
493 * an actual target, it will only search that context since only
494 * a local variable could be being appended to. This is actually
495 * a big win and must be tolerated.
496 *-----------------------------------------------------------------------
497 */
498void
ea6d42d8 499Var_Append(const char *name, const char *val, GNode *ctxt)
984263bc 500{
605113f3
MO
501 Var *v;
502 char *n;
984263bc 503
605113f3
MO
504 n = VarPossiblyExpand(name, ctxt);
505 v = VarFind(n, ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0);
7034e6b9 506
9a4c88c2 507 if (v == NULL) {
605113f3 508 VarAdd(n, val, ctxt);
984263bc
MD
509 } else {
510 Buf_AddByte(v->val, (Byte)' ');
fcf95e9c 511 Buf_Append(v->val, val);
984263bc 512
605113f3 513 DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, n,
9cf296a4 514 (char *)Buf_GetAll(v->val, (size_t *)NULL)));
984263bc
MD
515
516 if (v->flags & VAR_FROM_ENV) {
517 /*
518 * If the original variable came from the environment, we
519 * have to install it in the global context (we could place
520 * it in the environment, but then we should provide a way to
521 * export other variables...)
522 */
523 v->flags &= ~VAR_FROM_ENV;
0a7e0b85 524 Lst_AtFront(&ctxt->context, v);
984263bc
MD
525 }
526 }
605113f3 527 free(n);
984263bc
MD
528}
529
530/*-
531 *-----------------------------------------------------------------------
532 * Var_Exists --
533 * See if the given variable exists.
534 *
535 * Results:
536 * TRUE if it does, FALSE if it doesn't
537 *
538 * Side Effects:
539 * None.
540 *
541 *-----------------------------------------------------------------------
542 */
543Boolean
605113f3 544Var_Exists(const char *name, GNode *ctxt)
984263bc 545{
605113f3
MO
546 Var *v;
547 char *n;
984263bc 548
605113f3
MO
549 n = VarPossiblyExpand(name, ctxt);
550 v = VarFind(n, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV);
551 free(n);
984263bc 552
9a4c88c2 553 if (v == NULL) {
fbfaa208 554 return (FALSE);
984263bc 555 } else if (v->flags & VAR_FROM_ENV) {
5cfd56df 556 VarDestroy(v, TRUE);
984263bc 557 }
fbfaa208 558 return (TRUE);
984263bc
MD
559}
560
561/*-
562 *-----------------------------------------------------------------------
563 * Var_Value --
564 * Return the value of the named variable in the given context
565 *
566 * Results:
567 * The value if the variable exists, NULL if it doesn't
568 *
569 * Side Effects:
570 * None
571 *-----------------------------------------------------------------------
572 */
573char *
605113f3 574Var_Value(const char *name, GNode *ctxt, char **frp)
984263bc 575{
605113f3
MO
576 Var *v;
577 char *n;
984263bc 578
605113f3
MO
579 n = VarPossiblyExpand(name, ctxt);
580 v = VarFind(n, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
581 free(n);
984263bc 582 *frp = NULL;
9a4c88c2 583 if (v != NULL) {
9cf296a4 584 char *p = (char *)Buf_GetAll(v->val, (size_t *)NULL);
9a4c88c2 585
984263bc 586 if (v->flags & VAR_FROM_ENV) {
5cfd56df 587 VarDestroy(v, FALSE);
984263bc
MD
588 *frp = p;
589 }
fbfaa208 590 return (p);
984263bc 591 } else {
9a4c88c2 592 return (NULL);
984263bc
MD
593 }
594}
595
984263bc
MD
596/*-
597 *-----------------------------------------------------------------------
598 * VarModify --
599 * Modify each of the words of the passed string using the given
600 * function. Used to implement all modifiers.
601 *
602 * Results:
603 * A string of all the words modified appropriately.
604 *
605 * Side Effects:
606 * None.
607 *
608 *-----------------------------------------------------------------------
609 */
610static char *
07d5ef71 611VarModify(char *str, VarModifyProc *modProc, void *datum)
984263bc 612{
6a3d9147 613 Buffer *buf; /* Buffer for the new string */
984263bc
MD
614 Boolean addSpace; /* TRUE if need to add a space to the
615 * buffer before adding the trimmed
616 * word */
617 char **av; /* word list [first word does not count] */
618 int ac, i;
619
fbfaa208 620 buf = Buf_Init(0);
984263bc
MD
621 addSpace = FALSE;
622
623 av = brk_string(str, &ac, FALSE);
624
625 for (i = 1; i < ac; i++)
626 addSpace = (*modProc)(av[i], addSpace, buf, datum);
627
8294fbb3 628 Buf_AddByte(buf, '\0');
9cf296a4 629 str = (char *)Buf_GetAll(buf, (size_t *)NULL);
fbfaa208 630 Buf_Destroy(buf, FALSE);
984263bc
MD
631 return (str);
632}
633
372b1ac6
JS
634/*-
635 *-----------------------------------------------------------------------
636 * VarSortWords --
637 * Sort the words in the string.
638 *
639 * Input:
640 * str String whose words should be sorted
641 * cmp A comparison function to control the ordering
642 *
643 * Results:
644 * A string containing the words sorted
645 *
646 * Side Effects:
647 * None.
648 *
649 *-----------------------------------------------------------------------
650 */
651static char *
652VarSortWords(char *str, int (*cmp)(const void *, const void *))
653{
6a3d9147 654 Buffer *buf;
372b1ac6
JS
655 char **av;
656 int ac, i;
657
658 buf = Buf_Init(0);
659 av = brk_string(str, &ac, FALSE);
9a4c88c2 660 qsort(av + 1, ac - 1, sizeof(char *), cmp);
372b1ac6 661 for (i = 1; i < ac; i++) {
fcf95e9c 662 Buf_Append(buf, av[i]);
372b1ac6
JS
663 Buf_AddByte(buf, (Byte)((i < ac - 1) ? ' ' : '\0'));
664 }
9cf296a4 665 str = (char *)Buf_GetAll(buf, (size_t *)NULL);
372b1ac6
JS
666 Buf_Destroy(buf, FALSE);
667 return (str);
668}
669
670static int
671SortIncreasing(const void *l, const void *r)
672{
8e4eb27a 673
372b1ac6
JS
674 return (strcmp(*(const char* const*)l, *(const char* const*)r));
675}
676
984263bc
MD
677/*-
678 *-----------------------------------------------------------------------
679 * VarGetPattern --
680 * Pass through the tstr looking for 1) escaped delimiters,
681 * '$'s and backslashes (place the escaped character in
682 * uninterpreted) and 2) unescaped $'s that aren't before
683 * the delimiter (expand the variable substitution unless flags
684 * has VAR_NOSUBST set).
685 * Return the expanded string or NULL if the delimiter was missing
686 * If pattern is specified, handle escaped ampersands, and replace
687 * unescaped ampersands with the lhs of the pattern.
688 *
689 * Results:
690 * A string of all the words modified appropriately.
691 * If length is specified, return the string length of the buffer
692 * If flags is specified and the last character of the pattern is a
693 * $ set the VAR_MATCH_END bit of flags.
694 *
695 * Side Effects:
696 * None.
697 *-----------------------------------------------------------------------
698 */
699static char *
84de9e23 700VarGetPattern(GNode *ctxt, int err, char **tstr, int delim, int *flags,
9cf296a4 701 size_t *length, VarPattern *pattern)
984263bc
MD
702{
703 char *cp;
6a3d9147 704 Buffer *buf = Buf_Init(0);
9cf296a4 705 size_t junk;
fbfaa208 706
984263bc
MD
707 if (length == NULL)
708 length = &junk;
709
913800f5 710#define IS_A_MATCH(cp, delim) \
984263bc
MD
711 ((cp[0] == '\\') && ((cp[1] == delim) || \
712 (cp[1] == '\\') || (cp[1] == '$') || (pattern && (cp[1] == '&'))))
713
714 /*
715 * Skim through until the matching delimiter is found;
716 * pick up variable substitutions on the way. Also allow
717 * backslashes to quote the delimiter, $, and \, but don't
718 * touch other backslashes.
719 */
720 for (cp = *tstr; *cp && (*cp != delim); cp++) {
721 if (IS_A_MATCH(cp, delim)) {
fbfaa208 722 Buf_AddByte(buf, (Byte)cp[1]);
984263bc
MD
723 cp++;
724 } else if (*cp == '$') {
725 if (cp[1] == delim) {
726 if (flags == NULL)
fbfaa208 727 Buf_AddByte(buf, (Byte)*cp);
984263bc
MD
728 else
729 /*
730 * Unescaped $ at end of pattern => anchor
731 * pattern at end.
732 */
733 *flags |= VAR_MATCH_END;
734 } else {
735 if (flags == NULL || (*flags & VAR_NOSUBST) == 0) {
736 char *cp2;
9cf296a4 737 size_t len;
984263bc
MD
738 Boolean freeIt;
739
740 /*
741 * If unescaped dollar sign not before the
742 * delimiter, assume it's a variable
743 * substitution and recurse.
744 */
745 cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
fcf95e9c 746 Buf_Append(buf, cp2);
984263bc
MD
747 if (freeIt)
748 free(cp2);
749 cp += len - 1;
750 } else {
751 char *cp2 = &cp[1];
752
de3fa3f4 753 if (*cp2 == OPEN_PAREN || *cp2 == OPEN_BRACKET) {
984263bc
MD
754 /*
755 * Find the end of this variable reference
756 * and suck it in without further ado.
757 * It will be interperated later.
758 */
759 int have = *cp2;
de3fa3f4 760 int want = (*cp2 == OPEN_PAREN) ? CLOSE_PAREN : CLOSE_BRACKET;
984263bc
MD
761 int depth = 1;
762
763 for (++cp2; *cp2 != '\0' && depth > 0; ++cp2) {
764 if (cp2[-1] != '\\') {
765 if (*cp2 == have)
766 ++depth;
767 if (*cp2 == want)
768 --depth;
769 }
770 }
76b1c519 771 Buf_AppendRange(buf, cp, cp2);
984263bc
MD
772 cp = --cp2;
773 } else
fbfaa208 774 Buf_AddByte(buf, (Byte)*cp);
984263bc
MD
775 }
776 }
777 }
778 else if (pattern && *cp == '&')
779 Buf_AddBytes(buf, pattern->leftLen, (Byte *)pattern->lhs);
780 else
fbfaa208 781 Buf_AddByte(buf, (Byte)*cp);
984263bc
MD
782 }
783
8294fbb3
MO
784 Buf_AddByte(buf, (Byte)'\0');
785
984263bc
MD
786 if (*cp != delim) {
787 *tstr = cp;
788 *length = 0;
fbfaa208
MO
789 return (NULL);
790 } else {
984263bc 791 *tstr = ++cp;
fbfaa208 792 cp = (char *)Buf_GetAll(buf, length);
984263bc
MD
793 *length -= 1; /* Don't count the NULL */
794 Buf_Destroy(buf, FALSE);
fbfaa208 795 return (cp);
984263bc
MD
796 }
797}
798
984263bc
MD
799/*-
800 *-----------------------------------------------------------------------
c382ef3f 801 * Var_Quote --
984263bc
MD
802 * Quote shell meta-characters in the string
803 *
804 * Results:
805 * The quoted string
806 *
807 * Side Effects:
808 * None.
809 *
810 *-----------------------------------------------------------------------
811 */
c382ef3f
JS
812char *
813Var_Quote(const char *str)
984263bc 814{
6a3d9147 815 Buffer *buf;
984263bc
MD
816 /* This should cover most shells :-( */
817 static char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~";
b839b89f 818 char *ret;
984263bc 819
fbfaa208 820 buf = Buf_Init(MAKE_BSIZE);
984263bc
MD
821 for (; *str; str++) {
822 if (strchr(meta, *str) != NULL)
823 Buf_AddByte(buf, (Byte)'\\');
824 Buf_AddByte(buf, (Byte)*str);
825 }
8294fbb3 826 Buf_AddByte(buf, (Byte)'\0');
b839b89f 827 ret = Buf_GetAll(buf, NULL);
fbfaa208 828 Buf_Destroy(buf, FALSE);
b839b89f 829 return (ret);
984263bc
MD
830}
831
422e5813
MO
832/*-
833 *-----------------------------------------------------------------------
834 * VarREError --
835 * Print the error caused by a regcomp or regexec call.
836 *
837 * Results:
838 * None.
839 *
840 * Side Effects:
841 * An error gets printed.
842 *
843 *-----------------------------------------------------------------------
844 */
845void
846VarREError(int err, regex_t *pat, const char *str)
847{
848 char *errbuf;
849 int errlen;
850
851 errlen = regerror(err, pat, 0, 0);
852 errbuf = emalloc(errlen);
853 regerror(err, pat, errbuf, errlen);
854 Error("%s: %s", str, errbuf);
855 free(errbuf);
856}
857
984263bc
MD
858/*-
859 *-----------------------------------------------------------------------
860 * Var_Parse --
861 * Given the start of a variable invocation, extract the variable
862 * name and find its value, then modify it according to the
863 * specification.
864 *
865 * Results:
866 * The (possibly-modified) value of the variable or var_Error if the
867 * specification is invalid. The length of the specification is
868 * placed in *lengthPtr (for invalid specifications, this is just
3b340ba1
JS
869 * 2 to skip the '$' and the following letter, or 1 if '$' was the
870 * last character in the string).
984263bc
MD
871 * A Boolean in *freePtr telling whether the returned string should
872 * be freed by the caller.
873 *
874 * Side Effects:
875 * None.
876 *
877 *-----------------------------------------------------------------------
878 */
879char *
7034e6b9
MO
880Var_Parse(char *str, GNode *ctxt, Boolean err, size_t *lengthPtr,
881 Boolean *freePtr)
984263bc 882{
9a309bcc 883 char *tstr; /* Pointer into str */
984263bc
MD
884 Var *v; /* Variable in invocation */
885 char *cp; /* Secondary pointer into str (place marker
886 * for tstr) */
887 Boolean haveModifier;/* TRUE if have modifiers for the variable */
9a309bcc 888 char endc; /* Ending character when variable in parens
984263bc 889 * or braces */
9a309bcc 890 char startc=0; /* Starting character when variable in parens
984263bc
MD
891 * or braces */
892 int cnt; /* Used to count brace pairs when variable in
893 * in parens or braces */
894 char *start;
895 char delim;
896 Boolean dynamic; /* TRUE if the variable is local and we're
897 * expanding it in a non-local context. This
898 * is done to support dynamic sources. The
899 * result is just the invocation, unaltered */
900 int vlen; /* length of variable name, after embedded variable
901 * expansion */
902
903 *freePtr = FALSE;
904 dynamic = FALSE;
905 start = str;
906
12fcaf94
MO
907 /*
908 * It is assumed that Var_Parse() is called with str[0] == '$'
909 */
910
de3fa3f4 911 if (str[1] != OPEN_PAREN && str[1] != OPEN_BRACKET) {
984263bc
MD
912 /*
913 * If it's not bounded by braces of some sort, life is much simpler.
914 * We just need to check for the first character and return the
915 * value if it exists.
916 */
917 char name[2];
918
919 name[0] = str[1];
920 name[1] = '\0';
921
fbfaa208 922 v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
9edd457e 923 if (v == (Var *)NULL) {
3b340ba1
JS
924 if (str[1] != '\0')
925 *lengthPtr = 2;
926 else
927 *lengthPtr = 1;
984263bc
MD
928
929 if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
930 /*
931 * If substituting a local variable in a non-local context,
932 * assume it's for dynamic source stuff. We have to handle
933 * this specially and return the longhand for the variable
934 * with the dollar sign escaped so it makes it back to the
935 * caller. Only four of the local variables are treated
936 * specially as they are the only four that will be set
937 * when dynamic sources are expanded.
938 */
939 /* XXX: It looks like $% and $! are reversed here */
940 switch (str[1]) {
941 case '@':
fbfaa208 942 return ("$(.TARGET)");
984263bc 943 case '%':
fbfaa208 944 return ("$(.ARCHIVE)");
984263bc 945 case '*':
fbfaa208 946 return ("$(.PREFIX)");
984263bc 947 case '!':
fbfaa208 948 return ("$(.MEMBER)");
454224cf
MD
949 default:
950 break;
984263bc
MD
951 }
952 }
953 /*
954 * Error
955 */
956 return (err ? var_Error : varNoError);
957 } else {
958 haveModifier = FALSE;
959 tstr = &str[1];
960 endc = str[1];
961 }
962 } else {
963 /* build up expanded variable name in this buffer */
6a3d9147 964 Buffer *buf = Buf_Init(MAKE_BSIZE);
984263bc 965
984263bc
MD
966 /*
967 * Skip to the end character or a colon, whichever comes first,
968 * replacing embedded variables as we go.
969 */
12fcaf94
MO
970 startc = str[1];
971 endc = (startc == OPEN_PAREN) ? CLOSE_PAREN : CLOSE_BRACKET;
972
973 tstr = str + 2;;
974 while (*tstr != '\0' && *tstr != endc && *tstr != ':') {
975 if (*tstr == '$') {
976 size_t rlen;
977 Boolean rfree;
978 char *rval;
979
980 rval = Var_Parse(tstr, ctxt, err, &rlen, &rfree);
981 if (rval == var_Error) {
982 Fatal("Error expanding embedded variable.");
983 } else if (rval != NULL) {
984 Buf_Append(buf, rval);
985 if (rfree)
986 free(rval);
987 }
988 tstr += rlen - 1;
989 } else {
990 Buf_AddByte(buf, (Byte)*tstr);
991 }
992 tstr++;
993 }
fbfaa208 994
984263bc
MD
995 if (*tstr == '\0') {
996 /*
997 * If we never did find the end character, return NULL
998 * right now, setting the length to be the distance to
999 * the end of the string, since that's what make does.
1000 */
1001 *lengthPtr = tstr - str;
1002 return (var_Error);
1003 }
fbfaa208 1004
984263bc 1005 haveModifier = (*tstr == ':');
12fcaf94 1006 *tstr = '\0'; /* modify input string */
984263bc 1007
8294fbb3 1008 Buf_AddByte(buf, (Byte)'\0');
9cf296a4 1009 str = Buf_GetAll(buf, (size_t *)NULL);
984263bc
MD
1010 vlen = strlen(str);
1011
fbfaa208 1012 v = VarFind(str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
9edd457e 1013 if ((v == (Var *)NULL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
984263bc
MD
1014 (vlen == 2) && (str[1] == 'F' || str[1] == 'D'))
1015 {
1016 /*
1017 * Check for bogus D and F forms of local variables since we're
1018 * in a local context and the name is the right length.
1019 */
fbfaa208 1020 switch (str[0]) {
984263bc
MD
1021 case '@':
1022 case '%':
1023 case '*':
1024 case '!':
1025 case '>':
1026 case '<':
1027 {
1028 char vname[2];
1029 char *val;
1030
1031 /*
1032 * Well, it's local -- go look for it.
1033 */
1034 vname[0] = str[0];
1035 vname[1] = '\0';
1036 v = VarFind(vname, ctxt, 0);
1037
9a4c88c2 1038 if (v != NULL && !haveModifier) {
984263bc
MD
1039 /*
1040 * No need for nested expansion or anything, as we're
1041 * the only one who sets these things and we sure don't
1042 * put nested invocations in them...
1043 */
9cf296a4 1044 val = (char *)Buf_GetAll(v->val, (size_t *)NULL);
984263bc
MD
1045
1046 if (str[1] == 'D') {
9a4c88c2 1047 val = VarModify(val, VarHead, (void *)NULL);
984263bc 1048 } else {
9a4c88c2 1049 val = VarModify(val, VarTail, (void *)NULL);
984263bc
MD
1050 }
1051 /*
1052 * Resulting string is dynamically allocated, so
1053 * tell caller to free it.
1054 */
1055 *freePtr = TRUE;
1056 *lengthPtr = tstr-start+1;
1057 *tstr = endc;
1058 Buf_Destroy(buf, TRUE);
fbfaa208 1059 return (val);
984263bc
MD
1060 }
1061 break;
454224cf
MD
1062 default:
1063 break;
984263bc
MD
1064 }
1065 }
1066 }
1067
9edd457e 1068 if (v == (Var *)NULL) {
984263bc 1069 if (((vlen == 1) ||
fbfaa208 1070 (((vlen == 2) && (str[1] == 'F' || str[1] == 'D')))) &&
984263bc
MD
1071 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
1072 {
1073 /*
1074 * If substituting a local variable in a non-local context,
1075 * assume it's for dynamic source stuff. We have to handle
1076 * this specially and return the longhand for the variable
1077 * with the dollar sign escaped so it makes it back to the
1078 * caller. Only four of the local variables are treated
1079 * specially as they are the only four that will be set
1080 * when dynamic sources are expanded.
1081 */
1082 switch (str[0]) {
1083 case '@':
1084 case '%':
1085 case '*':
1086 case '!':
1087 dynamic = TRUE;
1088 break;
454224cf
MD
1089 default:
1090 break;
984263bc
MD
1091 }
1092 } else if ((vlen > 2) && (str[0] == '.') &&
fbfaa208 1093 isupper((unsigned char)str[1]) &&
984263bc
MD
1094 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
1095 {
1096 int len;
1097
1098 len = vlen - 1;
1099 if ((strncmp(str, ".TARGET", len) == 0) ||
1100 (strncmp(str, ".ARCHIVE", len) == 0) ||
1101 (strncmp(str, ".PREFIX", len) == 0) ||
1102 (strncmp(str, ".MEMBER", len) == 0))
1103 {
1104 dynamic = TRUE;
1105 }
1106 }
1107
1108 if (!haveModifier) {
1109 /*
1110 * No modifiers -- have specification length so we can return
1111 * now.
1112 */
1113 *lengthPtr = tstr - start + 1;
1114 *tstr = endc;
1115 if (dynamic) {
1116 str = emalloc(*lengthPtr + 1);
1117 strncpy(str, start, *lengthPtr);
1118 str[*lengthPtr] = '\0';
1119 *freePtr = TRUE;
1120 Buf_Destroy(buf, TRUE);
fbfaa208 1121 return (str);
984263bc
MD
1122 } else {
1123 Buf_Destroy(buf, TRUE);
1124 return (err ? var_Error : varNoError);
1125 }
1126 } else {
1127 /*
1128 * Still need to get to the end of the variable specification,
1129 * so kludge up a Var structure for the modifications
1130 */
5cfd56df 1131 v = VarCreate(str, NULL, VAR_JUNK);
984263bc
MD
1132 }
1133 }
1134 Buf_Destroy(buf, TRUE);
1135 }
1136
1137 if (v->flags & VAR_IN_USE) {
1138 Fatal("Variable %s is recursive.", v->name);
1139 /*NOTREACHED*/
1140 } else {
1141 v->flags |= VAR_IN_USE;
1142 }
12fcaf94 1143
984263bc
MD
1144 /*
1145 * Before doing any modification, we have to make sure the value
1146 * has been fully expanded. If it looks like recursion might be
1147 * necessary (there's a dollar sign somewhere in the variable's value)
1148 * we just call Var_Subst to do any other substitutions that are
1149 * necessary. Note that the value returned by Var_Subst will have
1150 * been dynamically-allocated, so it will need freeing when we
1151 * return.
1152 */
9cf296a4 1153 str = (char *)Buf_GetAll(v->val, (size_t *)NULL);
b0ef9278
MO
1154 if (strchr(str, '$') != NULL) {
1155 Buffer *buf;
1156
1157 buf = Var_Subst(NULL, str, ctxt, err);
1158 str = Buf_GetAll(buf, NULL);
1159 Buf_Destroy(buf, FALSE);
1160
984263bc
MD
1161 *freePtr = TRUE;
1162 }
1163
1164 v->flags &= ~VAR_IN_USE;
1165
1166 /*
1167 * Now we need to apply any modifiers the user wants applied.
1168 * These are:
1169 * :M<pattern> words which match the given <pattern>.
1170 * <pattern> is of the standard file
1171 * wildcarding form.
1172 * :S<d><pat1><d><pat2><d>[g]
1173 * Substitute <pat2> for <pat1> in the value
1174 * :C<d><pat1><d><pat2><d>[g]
1175 * Substitute <pat2> for regex <pat1> in the value
1176 * :H Substitute the head of each word
1177 * :T Substitute the tail of each word
1178 * :E Substitute the extension (minus '.') of
1179 * each word
1180 * :R Substitute the root of each word
1181 * (pathname minus the suffix).
1182 * :lhs=rhs Like :S, but the rhs goes to the end of
1183 * the invocation.
1184 * :U Converts variable to upper-case.
1185 * :L Converts variable to lower-case.
1186 */
9a4c88c2 1187 if ((str != NULL) && haveModifier) {
984263bc
MD
1188 /*
1189 * Skip initial colon while putting it back.
1190 */
1191 *tstr++ = ':';
1192 while (*tstr != endc) {
1193 char *newStr; /* New value to return */
1194 char termc; /* Character which terminated scan */
1195
913800f5 1196 DEBUGF(VAR, ("Applying :%c to \"%s\"\n", *tstr, str));
984263bc 1197 switch (*tstr) {
984263bc
MD
1198 case 'N':
1199 case 'M':
1200 {
1201 char *pattern;
1202 char *cp2;
1203 Boolean copy;
1204
1205 copy = FALSE;
1206 for (cp = tstr + 1;
1207 *cp != '\0' && *cp != ':' && *cp != endc;
1208 cp++)
1209 {
fbfaa208 1210 if (*cp == '\\' && (cp[1] == ':' || cp[1] == endc)) {
984263bc
MD
1211 copy = TRUE;
1212 cp++;
1213 }
1214 }
1215 termc = *cp;
1216 *cp = '\0';
1217 if (copy) {
1218 /*
1219 * Need to compress the \:'s out of the pattern, so
1220 * allocate enough room to hold the uncompressed
1221 * pattern (note that cp started at tstr+1, so
1222 * cp - tstr takes the null byte into account) and
1223 * compress the pattern into the space.
1224 */
1225 pattern = emalloc(cp - tstr);
1226 for (cp2 = pattern, cp = tstr + 1;
1227 *cp != '\0';
1228 cp++, cp2++)
1229 {
1230 if ((*cp == '\\') &&
1231 (cp[1] == ':' || cp[1] == endc)) {
1232 cp++;
1233 }
1234 *cp2 = *cp;
1235 }
1236 *cp2 = '\0';
1237 } else {
1238 pattern = &tstr[1];
1239 }
1240 if (*tstr == 'M' || *tstr == 'm') {
9a4c88c2 1241 newStr = VarModify(str, VarMatch, pattern);
984263bc 1242 } else {
9a4c88c2 1243 newStr = VarModify(str, VarNoMatch, pattern);
984263bc
MD
1244 }
1245 if (copy) {
1246 free(pattern);
1247 }
1248 break;
1249 }
1250 case 'S':
1251 {
1252 VarPattern pattern;
454224cf 1253 char del;
6a3d9147 1254 Buffer *buf; /* Buffer for patterns */
984263bc
MD
1255
1256 pattern.flags = 0;
454224cf 1257 del = tstr[1];
984263bc
MD
1258 tstr += 2;
1259
1260 /*
1261 * If pattern begins with '^', it is anchored to the
1262 * start of the word -- skip over it and flag pattern.
1263 */
1264 if (*tstr == '^') {
1265 pattern.flags |= VAR_MATCH_START;
1266 tstr += 1;
1267 }
1268
1269 buf = Buf_Init(0);
1270
1271 /*
1272 * Pass through the lhs looking for 1) escaped delimiters,
1273 * '$'s and backslashes (place the escaped character in
1274 * uninterpreted) and 2) unescaped $'s that aren't before
1275 * the delimiter (expand the variable substitution).
1276 * The result is left in the Buffer buf.
1277 */
454224cf 1278 for (cp = tstr; *cp != '\0' && *cp != del; cp++) {
984263bc 1279 if ((*cp == '\\') &&
454224cf 1280 ((cp[1] == del) ||
984263bc
MD
1281 (cp[1] == '$') ||
1282 (cp[1] == '\\')))
1283 {
1284 Buf_AddByte(buf, (Byte)cp[1]);
1285 cp++;
1286 } else if (*cp == '$') {
454224cf 1287 if (cp[1] != del) {
984263bc
MD
1288 /*
1289 * If unescaped dollar sign not before the
1290 * delimiter, assume it's a variable
1291 * substitution and recurse.
1292 */
1293 char *cp2;
9cf296a4 1294 size_t len;
984263bc
MD
1295 Boolean freeIt;
1296
1297 cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
fcf95e9c 1298 Buf_Append(buf, cp2);
984263bc
MD
1299 if (freeIt) {
1300 free(cp2);
1301 }
1302 cp += len - 1;
1303 } else {
1304 /*
1305 * Unescaped $ at end of pattern => anchor
1306 * pattern at end.
1307 */
1308 pattern.flags |= VAR_MATCH_END;
1309 }
1310 } else {
1311 Buf_AddByte(buf, (Byte)*cp);
1312 }
1313 }
1314
8294fbb3
MO
1315 Buf_AddByte(buf, (Byte)'\0');
1316
984263bc
MD
1317 /*
1318 * If lhs didn't end with the delimiter, complain and
d2ffb6f1 1319 * exit.
984263bc 1320 */
454224cf 1321 if (*cp != del) {
d2ffb6f1 1322 Fatal("Unclosed substitution for %s (%c missing)",
454224cf 1323 v->name, del);
984263bc
MD
1324 }
1325
1326 /*
1327 * Fetch pattern and destroy buffer, but preserve the data
1328 * in it, since that's our lhs. Note that Buf_GetAll
1329 * will return the actual number of bytes, which includes
1330 * the null byte, so we have to decrement the length by
1331 * one.
1332 */
1333 pattern.lhs = (char *)Buf_GetAll(buf, &pattern.leftLen);
1334 pattern.leftLen--;
1335 Buf_Destroy(buf, FALSE);
1336
1337 /*
1338 * Now comes the replacement string. Three things need to
1339 * be done here: 1) need to compress escaped delimiters and
1340 * ampersands and 2) need to replace unescaped ampersands
1341 * with the l.h.s. (since this isn't regexp, we can do
1342 * it right here) and 3) expand any variable substitutions.
1343 */
1344 buf = Buf_Init(0);
1345
1346 tstr = cp + 1;
454224cf 1347 for (cp = tstr; *cp != '\0' && *cp != del; cp++) {
984263bc 1348 if ((*cp == '\\') &&
454224cf 1349 ((cp[1] == del) ||
984263bc
MD
1350 (cp[1] == '&') ||
1351 (cp[1] == '\\') ||
1352 (cp[1] == '$')))
1353 {
1354 Buf_AddByte(buf, (Byte)cp[1]);
1355 cp++;
454224cf 1356 } else if ((*cp == '$') && (cp[1] != del)) {
984263bc 1357 char *cp2;
9cf296a4 1358 size_t len;
984263bc
MD
1359 Boolean freeIt;
1360
1361 cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
fcf95e9c 1362 Buf_Append(buf, cp2);
984263bc
MD
1363 cp += len - 1;
1364 if (freeIt) {
1365 free(cp2);
1366 }
1367 } else if (*cp == '&') {
1368 Buf_AddBytes(buf, pattern.leftLen,
1369 (Byte *)pattern.lhs);
1370 } else {
1371 Buf_AddByte(buf, (Byte)*cp);
1372 }
1373 }
1374
8294fbb3
MO
1375 Buf_AddByte(buf, (Byte)'\0');
1376
984263bc
MD
1377 /*
1378 * If didn't end in delimiter character, complain
1379 */
454224cf 1380 if (*cp != del) {
d2ffb6f1 1381 Fatal("Unclosed substitution for %s (%c missing)",
454224cf 1382 v->name, del);
984263bc
MD
1383 }
1384
1385 pattern.rhs = (char *)Buf_GetAll(buf, &pattern.rightLen);
1386 pattern.rightLen--;
1387 Buf_Destroy(buf, FALSE);
1388
1389 /*
1390 * Check for global substitution. If 'g' after the final
1391 * delimiter, substitution is global and is marked that
1392 * way.
1393 */
1394 cp++;
1395 if (*cp == 'g') {
1396 pattern.flags |= VAR_SUB_GLOBAL;
1397 cp++;
1398 }
1399
6065a492
MD
1400 /*
1401 * Global substitution of the empty string causes an
1402 * infinite number of matches, unless anchored by '^'
1403 * (start of string) or '$' (end of string). Catch the
1404 * infinite substitution here.
1405 * Note that flags can only contain the 3 bits we're
1406 * interested in so we don't have to mask unrelated
1407 * bits. We can test for equality.
1408 */
1409 if (!pattern.leftLen && pattern.flags == VAR_SUB_GLOBAL)
1410 Fatal("Global substitution of the empty string");
1411
984263bc 1412 termc = *cp;
9a4c88c2 1413 newStr = VarModify(str, VarSubstitute, &pattern);
984263bc
MD
1414 /*
1415 * Free the two strings.
1416 */
1417 free(pattern.lhs);
1418 free(pattern.rhs);
1419 break;
1420 }
1421 case 'C':
1422 {
1423 VarREPattern pattern;
1424 char *re;
1425 int error;
1426
1427 pattern.flags = 0;
1428 delim = tstr[1];
1429 tstr += 2;
1430
1431 cp = tstr;
1432
1433 if ((re = VarGetPattern(ctxt, err, &cp, delim, NULL,
1434 NULL, NULL)) == NULL) {
1435 /* was: goto cleanup */
1436 *lengthPtr = cp - start + 1;
1437 if (*freePtr)
1438 free(str);
1439 if (delim != '\0')
d2ffb6f1 1440 Fatal("Unclosed substitution for %s (%c missing)",
984263bc
MD
1441 v->name, delim);
1442 return (var_Error);
1443 }
1444
1445 if ((pattern.replace = VarGetPattern(ctxt, err, &cp,
1446 delim, NULL, NULL, NULL)) == NULL){
1447 free(re);
1448
1449 /* was: goto cleanup */
1450 *lengthPtr = cp - start + 1;
1451 if (*freePtr)
1452 free(str);
1453 if (delim != '\0')
d2ffb6f1 1454 Fatal("Unclosed substitution for %s (%c missing)",
984263bc
MD
1455 v->name, delim);
1456 return (var_Error);
1457 }
1458
1459 for (;; cp++) {
1460 switch (*cp) {
1461 case 'g':
1462 pattern.flags |= VAR_SUB_GLOBAL;
1463 continue;
1464 case '1':
1465 pattern.flags |= VAR_SUB_ONE;
1466 continue;
454224cf
MD
1467 default:
1468 break;
984263bc
MD
1469 }
1470 break;
1471 }
1472
1473 termc = *cp;
1474
1475 error = regcomp(&pattern.re, re, REG_EXTENDED);
1476 free(re);
1477 if (error) {
1478 *lengthPtr = cp - start + 1;
1479 VarREError(error, &pattern.re, "RE substitution error");
1480 free(pattern.replace);
1481 return (var_Error);
1482 }
1483
1484 pattern.nsub = pattern.re.re_nsub + 1;
1485 if (pattern.nsub < 1)
1486 pattern.nsub = 1;
1487 if (pattern.nsub > 10)
1488 pattern.nsub = 10;
1489 pattern.matches = emalloc(pattern.nsub *
1490 sizeof(regmatch_t));
9a4c88c2 1491 newStr = VarModify(str, VarRESubstitute, &pattern);
984263bc
MD
1492 regfree(&pattern.re);
1493 free(pattern.replace);
1494 free(pattern.matches);
1495 break;
1496 }
754c8e77
JS
1497 case 'L':
1498 if (tstr[1] == endc || tstr[1] == ':') {
6a3d9147 1499 Buffer *buf;
754c8e77
JS
1500 buf = Buf_Init(MAKE_BSIZE);
1501 for (cp = str; *cp ; cp++)
fbfaa208 1502 Buf_AddByte(buf, (Byte)tolower(*cp));
754c8e77 1503
8294fbb3 1504 Buf_AddByte(buf, (Byte)'\0');
9cf296a4 1505 newStr = (char *)Buf_GetAll(buf, (size_t *)NULL);
754c8e77
JS
1506 Buf_Destroy(buf, FALSE);
1507
1508 cp = tstr + 1;
1509 termc = *cp;
1510 break;
1511 }
1512 /* FALLTHROUGH */
372b1ac6
JS
1513 case 'O':
1514 if (tstr[1] == endc || tstr[1] == ':') {
1515 newStr = VarSortWords(str, SortIncreasing);
1516 cp = tstr + 1;
1517 termc = *cp;
1518 break;
1519 }
1520 /* FALLTHROUGH */
984263bc
MD
1521 case 'Q':
1522 if (tstr[1] == endc || tstr[1] == ':') {
fbfaa208 1523 newStr = Var_Quote(str);
984263bc
MD
1524 cp = tstr + 1;
1525 termc = *cp;
1526 break;
1527 }
1528 /*FALLTHRU*/
1529 case 'T':
1530 if (tstr[1] == endc || tstr[1] == ':') {
9a4c88c2 1531 newStr = VarModify(str, VarTail, (void *)NULL);
984263bc
MD
1532 cp = tstr + 1;
1533 termc = *cp;
1534 break;
1535 }
1536 /*FALLTHRU*/
754c8e77
JS
1537 case 'U':
1538 if (tstr[1] == endc || tstr[1] == ':') {
6a3d9147 1539 Buffer *buf;
754c8e77
JS
1540 buf = Buf_Init(MAKE_BSIZE);
1541 for (cp = str; *cp ; cp++)
fbfaa208 1542 Buf_AddByte(buf, (Byte)toupper(*cp));
754c8e77 1543
8294fbb3 1544 Buf_AddByte(buf, (Byte)'\0');
9cf296a4 1545 newStr = (char *)Buf_GetAll(buf, (size_t *)NULL);
754c8e77
JS
1546 Buf_Destroy(buf, FALSE);
1547
1548 cp = tstr + 1;
1549 termc = *cp;
1550 break;
1551 }
1552 /* FALLTHROUGH */
984263bc
MD
1553 case 'H':
1554 if (tstr[1] == endc || tstr[1] == ':') {
9a4c88c2 1555 newStr = VarModify(str, VarHead, (void *)NULL);
984263bc
MD
1556 cp = tstr + 1;
1557 termc = *cp;
1558 break;
1559 }
1560 /*FALLTHRU*/
1561 case 'E':
1562 if (tstr[1] == endc || tstr[1] == ':') {
9a4c88c2 1563 newStr = VarModify(str, VarSuffix, (void *)NULL);
984263bc
MD
1564 cp = tstr + 1;
1565 termc = *cp;
1566 break;
1567 }
1568 /*FALLTHRU*/
1569 case 'R':
1570 if (tstr[1] == endc || tstr[1] == ':') {
9a4c88c2 1571 newStr = VarModify(str, VarRoot, (void *)NULL);
984263bc
MD
1572 cp = tstr + 1;
1573 termc = *cp;
1574 break;
1575 }
1576 /*FALLTHRU*/
1577#ifdef SUNSHCMD
1578 case 's':
1579 if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) {
230209a1 1580 const char *error;
628ad7f9
MO
1581 {
1582 Buffer *buf = Cmd_Exec(str, &error);
1583 newStr = Buf_GetAll(buf, NULL);
1584 Buf_Destroy(buf, FALSE);
1585 }
454224cf 1586 if (error)
fbfaa208 1587 Error(error, str);
984263bc
MD
1588 cp = tstr + 2;
1589 termc = *cp;
1590 break;
1591 }
1592 /*FALLTHRU*/
1593#endif
1594 default:
1595 {
1596#ifdef SYSVVARSUB
1597 /*
1598 * This can either be a bogus modifier or a System-V
1599 * substitution command.
1600 */
1601 VarPattern pattern;
1602 Boolean eqFound;
1603
1604 pattern.flags = 0;
1605 eqFound = FALSE;
1606 /*
1607 * First we make a pass through the string trying
1608 * to verify it is a SYSV-make-style translation:
1609 * it must be: <string1>=<string2>)
1610 */
1611 cp = tstr;
1612 cnt = 1;
1613 while (*cp != '\0' && cnt) {
1614 if (*cp == '=') {
1615 eqFound = TRUE;
1616 /* continue looking for endc */
1617 }
1618 else if (*cp == endc)
1619 cnt--;
1620 else if (*cp == startc)
1621 cnt++;
1622 if (cnt)
1623 cp++;
1624 }
1625 if (*cp == endc && eqFound) {
1626
1627 /*
1628 * Now we break this sucker into the lhs and
1629 * rhs. We must null terminate them of course.
1630 */
754c8e77
JS
1631 cp = tstr;
1632
1633 delim = '=';
1634 if ((pattern.lhs = VarGetPattern(ctxt,
1635 err, &cp, delim, &pattern.flags, &pattern.leftLen,
1636 NULL)) == NULL) {
1637 /* was: goto cleanup */
1638 *lengthPtr = cp - start + 1;
1639 if (*freePtr)
1640 free(str);
1641 if (delim != '\0')
1642 Fatal("Unclosed substitution for %s (%c missing)",
1643 v->name, delim);
1644 return (var_Error);
1645 }
1646
1647 delim = endc;
1648 if ((pattern.rhs = VarGetPattern(ctxt,
1649 err, &cp, delim, NULL, &pattern.rightLen,
1650 &pattern)) == NULL) {
1651 /* was: goto cleanup */
1652 *lengthPtr = cp - start + 1;
1653 if (*freePtr)
1654 free(str);
1655 if (delim != '\0')
1656 Fatal("Unclosed substitution for %s (%c missing)",
1657 v->name, delim);
1658 return (var_Error);
984263bc 1659 }
984263bc
MD
1660
1661 /*
1662 * SYSV modifications happen through the whole
1663 * string. Note the pattern is anchored at the end.
1664 */
754c8e77
JS
1665 termc = *--cp;
1666 delim = '\0';
9a4c88c2 1667 newStr = VarModify(str, VarSYSVMatch, &pattern);
984263bc 1668
754c8e77
JS
1669 free(pattern.lhs);
1670 free(pattern.rhs);
1671
984263bc
MD
1672 termc = endc;
1673 } else
1674#endif
1675 {
fbfaa208 1676 Error("Unknown modifier '%c'\n", *tstr);
984263bc
MD
1677 for (cp = tstr+1;
1678 *cp != ':' && *cp != endc && *cp != '\0';
1679 cp++)
1680 continue;
1681 termc = *cp;
1682 newStr = var_Error;
1683 }
1684 }
1685 }
913800f5 1686 DEBUGF(VAR, ("Result is \"%s\"\n", newStr));
984263bc
MD
1687
1688 if (*freePtr) {
fbfaa208 1689 free(str);
984263bc
MD
1690 }
1691 str = newStr;
1692 if (str != var_Error) {
1693 *freePtr = TRUE;
1694 } else {
1695 *freePtr = FALSE;
1696 }
1697 if (termc == '\0') {
1698 Error("Unclosed variable specification for %s", v->name);
1699 } else if (termc == ':') {
1700 *cp++ = termc;
1701 } else {
1702 *cp = termc;
1703 }
1704 tstr = cp;
1705 }
1706 *lengthPtr = tstr - start + 1;
1707 } else {
1708 *lengthPtr = tstr - start + 1;
1709 *tstr = endc;
1710 }
1711
1712 if (v->flags & VAR_FROM_ENV) {
1713 Boolean destroy = FALSE;
1714
9cf296a4 1715 if (str != (char *)Buf_GetAll(v->val, (size_t *)NULL)) {
984263bc
MD
1716 destroy = TRUE;
1717 } else {
1718 /*
1719 * Returning the value unmodified, so tell the caller to free
1720 * the thing.
1721 */
1722 *freePtr = TRUE;
1723 }
5cfd56df 1724 VarDestroy(v, destroy);
984263bc
MD
1725 } else if (v->flags & VAR_JUNK) {
1726 /*
1727 * Perform any free'ing needed and set *freePtr to FALSE so the caller
1728 * doesn't try to free a static pointer.
1729 */
1730 if (*freePtr) {
1731 free(str);
1732 }
1733 *freePtr = FALSE;
5cfd56df 1734 VarDestroy(v, TRUE);
984263bc
MD
1735 if (dynamic) {
1736 str = emalloc(*lengthPtr + 1);
1737 strncpy(str, start, *lengthPtr);
1738 str[*lengthPtr] = '\0';
1739 *freePtr = TRUE;
1740 } else {
1741 str = err ? var_Error : varNoError;
1742 }
1743 }
1744 return (str);
1745}
1746
1747/*-
1748 *-----------------------------------------------------------------------
1749 * Var_Subst --
1750 * Substitute for all variables in the given string in the given context
1751 * If undefErr is TRUE, Parse_Error will be called when an undefined
1752 * variable is encountered.
1753 *
1754 * Results:
1755 * The resulting string.
1756 *
1757 * Side Effects:
1758 * None. The old string must be freed by the caller
1759 *-----------------------------------------------------------------------
1760 */
b0ef9278 1761Buffer *
ea6d42d8 1762Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr)
984263bc 1763{
b0ef9278
MO
1764 Boolean errorReported;
1765 Buffer *buf; /* Buffer for forming things */
984263bc 1766
b0ef9278
MO
1767 /*
1768 * Set TRUE if an error has already been reported to prevent a
1769 * plethora of messages when recursing.
1770 */
984263bc
MD
1771 errorReported = FALSE;
1772
b0ef9278 1773 buf = Buf_Init(0);
984263bc 1774 while (*str) {
f9402228 1775 if (var == NULL && (str[0] == '$') && (str[1] == '$')) {
984263bc
MD
1776 /*
1777 * A dollar sign may be escaped either with another dollar sign.
1778 * In such a case, we skip over the escape character and store the
1779 * dollar sign into the buffer directly.
1780 */
f9402228
MO
1781 Buf_AddByte(buf, (Byte)str[0]);
1782 str += 2;
1783
b0ef9278
MO
1784 } else if (str[0] == '$') {
1785 char *val; /* Value to substitute for a variable */
1786 size_t length; /* Length of the variable invocation */
1787 Boolean doFree; /* Set true if val should be freed */
de3fa3f4
MO
1788 /*
1789 * Variable invocation.
1790 */
984263bc
MD
1791 if (var != NULL) {
1792 int expand;
1793 for (;;) {
b0ef9278 1794 if (str[1] == OPEN_PAREN || str[1] == OPEN_BRACKET) {
de3fa3f4 1795 const char *p = str + 2;
984263bc
MD
1796
1797 /*
1798 * Scan up to the end of the variable name.
1799 */
de3fa3f4
MO
1800 while (*p != '\0' &&
1801 *p != ':' &&
1802 *p != CLOSE_PAREN &&
1803 *p != CLOSE_BRACKET &&
1804 *p != '$') {
1805 ++p;
1806 }
b0ef9278 1807
984263bc
MD
1808 /*
1809 * A variable inside the variable. We cannot expand
1810 * the external variable yet, so we try again with
1811 * the nested one
1812 */
1813 if (*p == '$') {
76b1c519 1814 Buf_AppendRange(buf, str, p);
984263bc
MD
1815 str = p;
1816 continue;
1817 }
1818
b0ef9278
MO
1819 if (var[p - (str + 2)] == '\0' && strncmp(var, str + 2, p - (str + 2)) == 0) {
1820 expand = TRUE;
1821 } else {
984263bc
MD
1822 /*
1823 * Not the variable we want to expand, scan
1824 * until the next variable
1825 */
b0ef9278
MO
1826 while (*p != '$' && *p != '\0')
1827 ++p;
1828
76b1c519 1829 Buf_AppendRange(buf, str, p);
984263bc
MD
1830 str = p;
1831 expand = FALSE;
b0ef9278
MO
1832 }
1833
1834 } else {
1835 /*
1836 * Single letter variable name.
1837 */
1838 if (var[1] == '\0' && str[1] == var[0]) {
984263bc 1839 expand = TRUE;
b0ef9278
MO
1840 } else {
1841 Buf_AddBytes(buf, 2, (const Byte *)str);
1842 str += 2;
1843 expand = FALSE;
f9402228 1844 }
984263bc 1845 }
b0ef9278 1846 break;
984263bc
MD
1847 }
1848 if (!expand)
1849 continue;
1850 }
1851
fbfaa208 1852 val = Var_Parse(str, ctxt, undefErr, &length, &doFree);
984263bc
MD
1853
1854 /*
1855 * When we come down here, val should either point to the
1856 * value of this variable, suitably modified, or be NULL.
1857 * Length should be the total length of the potential
1858 * variable invocation (from $ to end character...)
1859 */
1860 if (val == var_Error || val == varNoError) {
1861 /*
1862 * If performing old-time variable substitution, skip over
1863 * the variable and continue with the substitution. Otherwise,
1864 * store the dollar sign and advance str so we continue with
1865 * the string...
1866 */
1867 if (oldVars) {
1868 str += length;
1869 } else if (undefErr) {
1870 /*
1871 * If variable is undefined, complain and skip the
1872 * variable. The complaint will stop us from doing anything
1873 * when the file is parsed.
1874 */
1875 if (!errorReported) {
fbfaa208 1876 Parse_Error(PARSE_FATAL,
984263bc
MD
1877 "Undefined variable \"%.*s\"",length,str);
1878 }
1879 str += length;
1880 errorReported = TRUE;
1881 } else {
bf2bcf34 1882 Buf_AddByte(buf, (Byte)*str);
984263bc
MD
1883 str += 1;
1884 }
1885 } else {
1886 /*
1887 * We've now got a variable structure to store in. But first,
1888 * advance the string pointer.
1889 */
1890 str += length;
1891
1892 /*
1893 * Copy all the characters from the variable value straight
1894 * into the new string.
1895 */
fcf95e9c 1896 Buf_Append(buf, val);
984263bc 1897 if (doFree) {
fbfaa208 1898 free(val);
984263bc
MD
1899 }
1900 }
b0ef9278
MO
1901
1902 } else {
1903 /*
1904 * Skip as many characters as possible -- either to the end of
1905 * the string or to the next dollar sign (variable invocation).
1906 */
1907 const char *cp = str;
1908
1909 do {
1910 str++;
1911 } while (str[0] != '$' && str[0] != '\0');
1912
1913 Buf_AppendRange(buf, cp, str);
984263bc
MD
1914 }
1915 }
1916
b0ef9278 1917 return (buf);
984263bc
MD
1918}
1919
1920/*-
1921 *-----------------------------------------------------------------------
1922 * Var_GetTail --
1923 * Return the tail from each of a list of words. Used to set the
1924 * System V local variables.
1925 *
1926 * Results:
1927 * The resulting string.
1928 *
1929 * Side Effects:
1930 * None.
1931 *
1932 *-----------------------------------------------------------------------
1933 */
1934char *
84de9e23 1935Var_GetTail(char *file)
984263bc 1936{
8e4eb27a 1937
9a4c88c2 1938 return (VarModify(file, VarTail, (void *)NULL));
984263bc
MD
1939}
1940
1941/*-
1942 *-----------------------------------------------------------------------
1943 * Var_GetHead --
1944 * Find the leading components of a (list of) filename(s).
1945 * XXX: VarHead does not replace foo by ., as (sun) System V make
1946 * does.
1947 *
1948 * Results:
1949 * The leading components.
1950 *
1951 * Side Effects:
1952 * None.
1953 *
1954 *-----------------------------------------------------------------------
1955 */
1956char *
84de9e23 1957Var_GetHead(char *file)
984263bc 1958{
fbfaa208 1959
9a4c88c2 1960 return (VarModify(file, VarHead, (void *)NULL));
984263bc
MD
1961}
1962
1963/*-
1964 *-----------------------------------------------------------------------
1965 * Var_Init --
1966 * Initialize the module
1967 *
1968 * Results:
1969 * None
1970 *
1971 * Side Effects:
1972 * The VAR_CMD and VAR_GLOBAL contexts are created
1973 *-----------------------------------------------------------------------
1974 */
1975void
fbfaa208 1976Var_Init(void)
984263bc 1977{
8e4eb27a 1978
fbfaa208
MO
1979 VAR_GLOBAL = Targ_NewGN("Global");
1980 VAR_CMD = Targ_NewGN("Command");
984263bc
MD
1981}
1982
984263bc
MD
1983/****************** PRINT DEBUGGING INFO *****************/
1984static int
fbfaa208 1985VarPrintVar(void *vp, void *dummy __unused)
984263bc
MD
1986{
1987 Var *v = (Var *) vp;
fbfaa208 1988
9cf296a4 1989 printf("%-16s = %s\n", v->name, (char *)Buf_GetAll(v->val, (size_t *)NULL));
84de9e23 1990 return (0);
984263bc
MD
1991}
1992
1993/*-
1994 *-----------------------------------------------------------------------
1995 * Var_Dump --
1996 * print all variables in a context
1997 *-----------------------------------------------------------------------
1998 */
1999void
fbfaa208 2000Var_Dump(GNode *ctxt)
984263bc 2001{
09040c89 2002
0a7e0b85 2003 Lst_ForEach(&ctxt->context, VarPrintVar, (void *)NULL);
984263bc 2004}