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
7 * This code is derived from software contributed to Berkeley by
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
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
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 $
40 * $DragonFly: src/usr.bin/make/var.c,v 1.63 2005/02/06 23:56:21 okumoto Exp $
45 * Variable-handling functions
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
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
59 * Var_Exists See if a variable exists.
61 * Var_Value Return the value of a variable in a context or
62 * NULL if the variable is undefined.
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.
70 * Var_Parse Parse a variable expansion from a string and
71 * return the result and the number of characters
74 * Var_Delete Delete a variable in a context.
76 * Var_Init Initialize this module.
79 * Var_Dump Print out all variables defined in the given
82 * XXX: There's a lot of duplication in these functions.
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.
106 char var_Error[] = "";
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...
113 static char varNoError[] = "";
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
120 * 2) the global context. Variables set in the Makefile are located in
121 * the global context. It is the penultimate context searched when
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
131 GNode *VAR_GLOBAL; /* variables from the makefile */
132 GNode *VAR_CMD; /* variables defined on the command-line */
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 */
138 #define OPEN_PAREN '('
139 #define CLOSE_PAREN ')'
140 #define OPEN_BRACKET '{'
141 #define CLOSE_BRACKET '}'
143 static Var *VarCreate(const char [], const char [], int);
144 static void VarDestroy(Var *, Boolean);
145 static char *VarGetPattern(GNode *, int, char **, int, int *, size_t *,
147 static char *VarModify(char *, VarModifyProc *, void *);
148 static int VarPrintVar(void *, void *);
151 *-----------------------------------------------------------------------
153 * See if the given variable matches the named one. Called from
154 * Lst_Find when searching for a variable of a given name.
157 * 0 if they match. non-zero otherwise.
161 *-----------------------------------------------------------------------
164 VarCmp(const void *v, const void *name)
167 return (strcmp(name, ((const Var *)v)->name));
171 *-----------------------------------------------------------------------
172 * VarPossiblyExpand --
173 * Expand a variable name's embedded variables in the given context.
176 * The contents of name, possibly expanded.
177 *-----------------------------------------------------------------------
180 VarPossiblyExpand(const char *name, GNode *ctxt)
185 * XXX make a temporary copy of the name because Var_Subst insists
186 * on writing into the string.
189 if (strchr(name, '$') != NULL) {
193 buf = Var_Subst(NULL, tmp, ctxt, 0);
194 str = Buf_GetAll(buf, NULL);
195 Buf_Destroy(buf, FALSE);
204 *-----------------------------------------------------------------------
206 * Find the given variable in the given context and any other contexts
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
215 * A pointer to the structure describing the desired variable or
216 * NULL if the variable does not exist.
220 *-----------------------------------------------------------------------
223 VarFind(const char *name, GNode *ctxt, int flags)
225 Boolean localCheckEnvFirst;
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
238 if (!strcmp(name, ".ALLSRC"))
240 if (!strcmp(name, ".ARCHIVE"))
244 if (!strcmp(name, ".IMPSRC"))
248 if (!strcmp(name, ".MEMBER"))
252 if (!strcmp(name, ".OODATE"))
256 if (!strcmp(name, ".PREFIX"))
260 if (!strcmp(name, ".TARGET"))
268 * Note whether this is one of the specific variables we were told through
269 * the -E flag to use environment-variable-override for.
271 if (Lst_Find(&envFirstVars, name, (CompareProc *)strcmp) != NULL) {
272 localCheckEnvFirst = TRUE;
274 localCheckEnvFirst = FALSE;
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'
282 var = Lst_Find(&ctxt->context, name, VarCmp);
284 if ((var == NULL) && (flags & FIND_CMD) && (ctxt != VAR_CMD)) {
285 var = Lst_Find(&VAR_CMD->context, name, VarCmp);
287 if ((var == NULL) && (flags & FIND_GLOBAL) && (ctxt != VAR_GLOBAL) &&
288 !checkEnvFirst && !localCheckEnvFirst)
290 var = Lst_Find(&VAR_GLOBAL->context, name, VarCmp);
292 if ((var == NULL) && (flags & FIND_ENV)) {
295 if ((env = getenv(name)) != NULL) {
296 v = VarCreate(name, env, VAR_FROM_ENV);
299 } else if ((checkEnvFirst || localCheckEnvFirst) &&
300 (flags & FIND_GLOBAL) && (ctxt != VAR_GLOBAL))
302 var = Lst_Find(&VAR_GLOBAL->context, name, VarCmp);
311 return (Lst_Datum(var));
316 *-----------------------------------------------------------------------
318 * Add a new variable of name name and value val to the given context.
324 * The new variable is placed at the front of the given context
325 * The name and val arguments are duplicated so they may
327 *-----------------------------------------------------------------------
330 VarAdd(const char *name, const char *val, GNode *ctxt)
332 Lst_AtFront(&ctxt->context, VarCreate(name, val, 0));
334 DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, name, val));
338 * Create a Var object.
340 * @param name Name of variable.
341 * @param value Value of variable.
342 * @param flags Flags set on variable.
345 VarCreate(const char name[], const char value[], int flags)
349 v = emalloc(sizeof(Var));
350 v->name = estrdup(name);
351 v->val = Buf_Init(0);
355 Buf_Append(v->val, value);
361 * Destroy a Var object.
363 * @param v Object to destroy.
364 * @param f true if internal buffer in Buffer object is to be
368 VarDestroy(Var *v, Boolean f)
370 Buf_Destroy(v->val, f);
376 *-----------------------------------------------------------------------
378 * Remove a variable from a context.
384 * The Var structure is removed and freed.
386 *-----------------------------------------------------------------------
389 Var_Delete(const char *name, GNode *ctxt)
393 DEBUGF(VAR, ("%s:delete %s\n", ctxt->name, name));
394 ln = Lst_Find(&ctxt->context, name, VarCmp);
396 VarDestroy(Lst_Datum(ln), TRUE);
397 Lst_Remove(&ctxt->context, ln);
402 *-----------------------------------------------------------------------
404 * Set the variable name to the value val in the given context.
410 * If the variable doesn't yet exist, a new record is created for it.
411 * Else the old value is freed and the new one stuck in its place
414 * The variable is searched for only in its context before being
415 * created in that context. I.e. if the context is VAR_GLOBAL,
416 * only VAR_GLOBAL->context is searched. Likewise if it is VAR_CMD, only
417 * VAR_CMD->context is searched. This is done to avoid the literally
418 * thousands of unnecessary strcmp's that used to be done to
419 * set, say, $(@) or $(<).
420 *-----------------------------------------------------------------------
423 Var_Set(const char *name, const char *val, GNode *ctxt)
429 * We only look for a variable in the given context since anything set
430 * here will override anything in a lower context, so there's not much
431 * point in searching them all just to save a bit of memory...
433 n = VarPossiblyExpand(name, ctxt);
434 v = VarFind(n, ctxt, 0);
436 VarAdd(n, val, ctxt);
439 Buf_Append(v->val, val);
441 DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, n, val));
444 * Any variables given on the command line are automatically exported
445 * to the environment (as per POSIX standard)
447 if (ctxt == VAR_CMD || (v != (Var *)NULL && (v->flags & VAR_TO_ENV))) {
455 * Set the VAR_TO_ENV flag on a variable
458 Var_SetEnv(const char *name, GNode *ctxt)
462 v = VarFind(name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV);
464 if ((v->flags & VAR_TO_ENV) == 0) {
465 v->flags |= VAR_TO_ENV;
466 setenv(v->name, Buf_GetAll(v->val, NULL), 1);
469 Error("Cannot set environment flag on non-existant variable %s", name);
474 *-----------------------------------------------------------------------
476 * The variable of the given name has the given value appended to it in
483 * If the variable doesn't exist, it is created. Else the strings
484 * are concatenated (with a space in between).
487 * Only if the variable is being sought in the global context is the
488 * environment searched.
489 * XXX: Knows its calling circumstances in that if called with ctxt
490 * an actual target, it will only search that context since only
491 * a local variable could be being appended to. This is actually
492 * a big win and must be tolerated.
493 *-----------------------------------------------------------------------
496 Var_Append(const char *name, const char *val, GNode *ctxt)
501 n = VarPossiblyExpand(name, ctxt);
502 v = VarFind(n, ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0);
505 VarAdd(n, val, ctxt);
507 Buf_AddByte(v->val, (Byte)' ');
508 Buf_Append(v->val, val);
510 DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, n,
511 (char *)Buf_GetAll(v->val, (size_t *)NULL)));
513 if (v->flags & VAR_FROM_ENV) {
515 * If the original variable came from the environment, we
516 * have to install it in the global context (we could place
517 * it in the environment, but then we should provide a way to
518 * export other variables...)
520 v->flags &= ~VAR_FROM_ENV;
521 Lst_AtFront(&ctxt->context, v);
528 *-----------------------------------------------------------------------
530 * See if the given variable exists.
533 * TRUE if it does, FALSE if it doesn't
538 *-----------------------------------------------------------------------
541 Var_Exists(const char *name, GNode *ctxt)
546 n = VarPossiblyExpand(name, ctxt);
547 v = VarFind(n, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV);
552 } else if (v->flags & VAR_FROM_ENV) {
559 *-----------------------------------------------------------------------
561 * Return the value of the named variable in the given context
564 * The value if the variable exists, NULL if it doesn't
568 *-----------------------------------------------------------------------
571 Var_Value(const char *name, GNode *ctxt, char **frp)
576 n = VarPossiblyExpand(name, ctxt);
577 v = VarFind(n, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
581 char *p = (char *)Buf_GetAll(v->val, (size_t *)NULL);
583 if (v->flags & VAR_FROM_ENV) {
584 VarDestroy(v, FALSE);
594 *-----------------------------------------------------------------------
596 * Modify each of the words of the passed string using the given
597 * function. Used to implement all modifiers.
600 * A string of all the words modified appropriately.
605 *-----------------------------------------------------------------------
608 VarModify(char *str, VarModifyProc *modProc, void *datum)
610 Buffer *buf; /* Buffer for the new string */
611 Boolean addSpace; /* TRUE if need to add a space to the
612 * buffer before adding the trimmed
614 char **av; /* word list [first word does not count] */
620 av = brk_string(str, &ac, FALSE);
622 for (i = 1; i < ac; i++)
623 addSpace = (*modProc)(av[i], addSpace, buf, datum);
625 Buf_AddByte(buf, '\0');
626 str = (char *)Buf_GetAll(buf, (size_t *)NULL);
627 Buf_Destroy(buf, FALSE);
632 *-----------------------------------------------------------------------
634 * Sort the words in the string.
637 * str String whose words should be sorted
638 * cmp A comparison function to control the ordering
641 * A string containing the words sorted
646 *-----------------------------------------------------------------------
649 VarSortWords(char *str, int (*cmp)(const void *, const void *))
656 av = brk_string(str, &ac, FALSE);
657 qsort(av + 1, ac - 1, sizeof(char *), cmp);
658 for (i = 1; i < ac; i++) {
659 Buf_Append(buf, av[i]);
660 Buf_AddByte(buf, (Byte)((i < ac - 1) ? ' ' : '\0'));
662 str = (char *)Buf_GetAll(buf, (size_t *)NULL);
663 Buf_Destroy(buf, FALSE);
668 SortIncreasing(const void *l, const void *r)
671 return (strcmp(*(const char* const*)l, *(const char* const*)r));
675 *-----------------------------------------------------------------------
677 * Pass through the tstr looking for 1) escaped delimiters,
678 * '$'s and backslashes (place the escaped character in
679 * uninterpreted) and 2) unescaped $'s that aren't before
680 * the delimiter (expand the variable substitution unless flags
681 * has VAR_NOSUBST set).
682 * Return the expanded string or NULL if the delimiter was missing
683 * If pattern is specified, handle escaped ampersands, and replace
684 * unescaped ampersands with the lhs of the pattern.
687 * A string of all the words modified appropriately.
688 * If length is specified, return the string length of the buffer
689 * If flags is specified and the last character of the pattern is a
690 * $ set the VAR_MATCH_END bit of flags.
694 *-----------------------------------------------------------------------
697 VarGetPattern(GNode *ctxt, int err, char **tstr, int delim, int *flags,
698 size_t *length, VarPattern *pattern)
701 Buffer *buf = Buf_Init(0);
707 #define IS_A_MATCH(cp, delim) \
708 ((cp[0] == '\\') && ((cp[1] == delim) || \
709 (cp[1] == '\\') || (cp[1] == '$') || (pattern && (cp[1] == '&'))))
712 * Skim through until the matching delimiter is found;
713 * pick up variable substitutions on the way. Also allow
714 * backslashes to quote the delimiter, $, and \, but don't
715 * touch other backslashes.
717 for (cp = *tstr; *cp && (*cp != delim); cp++) {
718 if (IS_A_MATCH(cp, delim)) {
719 Buf_AddByte(buf, (Byte)cp[1]);
721 } else if (*cp == '$') {
722 if (cp[1] == delim) {
724 Buf_AddByte(buf, (Byte)*cp);
727 * Unescaped $ at end of pattern => anchor
730 *flags |= VAR_MATCH_END;
732 if (flags == NULL || (*flags & VAR_NOSUBST) == 0) {
738 * If unescaped dollar sign not before the
739 * delimiter, assume it's a variable
740 * substitution and recurse.
742 cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
743 Buf_Append(buf, cp2);
750 if (*cp2 == OPEN_PAREN || *cp2 == OPEN_BRACKET) {
752 * Find the end of this variable reference
753 * and suck it in without further ado.
754 * It will be interperated later.
757 int want = (*cp2 == OPEN_PAREN) ? CLOSE_PAREN : CLOSE_BRACKET;
760 for (++cp2; *cp2 != '\0' && depth > 0; ++cp2) {
761 if (cp2[-1] != '\\') {
768 Buf_AppendRange(buf, cp, cp2);
771 Buf_AddByte(buf, (Byte)*cp);
775 else if (pattern && *cp == '&')
776 Buf_AddBytes(buf, pattern->leftLen, (Byte *)pattern->lhs);
778 Buf_AddByte(buf, (Byte)*cp);
781 Buf_AddByte(buf, (Byte)'\0');
789 cp = (char *)Buf_GetAll(buf, length);
790 *length -= 1; /* Don't count the NULL */
791 Buf_Destroy(buf, FALSE);
797 *-----------------------------------------------------------------------
799 * Quote shell meta-characters in the string
807 *-----------------------------------------------------------------------
810 Var_Quote(const char *str)
813 /* This should cover most shells :-( */
814 static char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~";
817 buf = Buf_Init(MAKE_BSIZE);
818 for (; *str; str++) {
819 if (strchr(meta, *str) != NULL)
820 Buf_AddByte(buf, (Byte)'\\');
821 Buf_AddByte(buf, (Byte)*str);
823 Buf_AddByte(buf, (Byte)'\0');
824 ret = Buf_GetAll(buf, NULL);
825 Buf_Destroy(buf, FALSE);
830 *-----------------------------------------------------------------------
832 * Print the error caused by a regcomp or regexec call.
838 * An error gets printed.
840 *-----------------------------------------------------------------------
843 VarREError(int err, regex_t *pat, const char *str)
848 errlen = regerror(err, pat, 0, 0);
849 errbuf = emalloc(errlen);
850 regerror(err, pat, errbuf, errlen);
851 Error("%s: %s", str, errbuf);
856 *-----------------------------------------------------------------------
858 * Given the start of a variable invocation, extract the variable
859 * name and find its value, then modify it according to the
863 * The (possibly-modified) value of the variable or var_Error if the
864 * specification is invalid. The length of the specification is
865 * placed in *lengthPtr (for invalid specifications, this is just
866 * 2 to skip the '$' and the following letter, or 1 if '$' was the
867 * last character in the string).
868 * A Boolean in *freePtr telling whether the returned string should
869 * be freed by the caller.
874 *-----------------------------------------------------------------------
877 Var_Parse(char *str, GNode *ctxt, Boolean err, size_t *lengthPtr,
880 char *tstr; /* Pointer into str */
881 Var *v; /* Variable in invocation */
882 char *cp; /* Secondary pointer into str (place marker
884 Boolean haveModifier;/* TRUE if have modifiers for the variable */
885 char endc; /* Ending character when variable in parens
887 char startc=0; /* Starting character when variable in parens
891 Boolean dynamic; /* TRUE if the variable is local and we're
892 * expanding it in a non-local context. This
893 * is done to support dynamic sources. The
894 * result is just the invocation, unaltered */
895 int vlen; /* length of variable name, after embedded variable
903 * It is assumed that Var_Parse() is called with str[0] == '$'
906 if (str[1] == OPEN_PAREN || str[1] == OPEN_BRACKET) {
907 /* build up expanded variable name in this buffer */
908 Buffer *buf = Buf_Init(MAKE_BSIZE);
911 * Skip to the end character or a colon, whichever comes first,
912 * replacing embedded variables as we go.
915 endc = (startc == OPEN_PAREN) ? CLOSE_PAREN : CLOSE_BRACKET;
918 while (*tstr != '\0' && *tstr != endc && *tstr != ':') {
924 rval = Var_Parse(tstr, ctxt, err, &rlen, &rfree);
925 if (rval == var_Error) {
926 Fatal("Error expanding embedded variable.");
927 } else if (rval != NULL) {
928 Buf_Append(buf, rval);
934 Buf_AddByte(buf, (Byte)*tstr);
941 * If we never did find the end character, return NULL
942 * right now, setting the length to be the distance to
943 * the end of the string, since that's what make does.
945 *lengthPtr = tstr - str;
949 haveModifier = (*tstr == ':');
950 *tstr = '\0'; /* modify input string */
952 Buf_AddByte(buf, (Byte)'\0');
953 str = Buf_GetAll(buf, (size_t *)NULL);
956 v = VarFind(str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
957 if ((v == (Var *)NULL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
958 (vlen == 2) && (str[1] == 'F' || str[1] == 'D'))
961 * Check for bogus D and F forms of local variables since we're
962 * in a local context and the name is the right length.
976 * Well, it's local -- go look for it.
980 v = VarFind(vname, ctxt, 0);
982 if (v != NULL && !haveModifier) {
984 * No need for nested expansion or anything, as we're
985 * the only one who sets these things and we sure don't
986 * put nested invocations in them...
988 val = (char *)Buf_GetAll(v->val, (size_t *)NULL);
991 val = VarModify(val, VarHead, (void *)NULL);
993 val = VarModify(val, VarTail, (void *)NULL);
996 * Resulting string is dynamically allocated, so
997 * tell caller to free it.
1000 *lengthPtr = tstr-start+1;
1002 Buf_Destroy(buf, TRUE);
1012 if (v == (Var *)NULL) {
1014 (((vlen == 2) && (str[1] == 'F' || str[1] == 'D')))) &&
1015 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
1018 * If substituting a local variable in a non-local context,
1019 * assume it's for dynamic source stuff. We have to handle
1020 * this specially and return the longhand for the variable
1021 * with the dollar sign escaped so it makes it back to the
1022 * caller. Only four of the local variables are treated
1023 * specially as they are the only four that will be set
1024 * when dynamic sources are expanded.
1036 } else if ((vlen > 2) && (str[0] == '.') &&
1037 isupper((unsigned char)str[1]) &&
1038 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
1043 if ((strncmp(str, ".TARGET", len) == 0) ||
1044 (strncmp(str, ".ARCHIVE", len) == 0) ||
1045 (strncmp(str, ".PREFIX", len) == 0) ||
1046 (strncmp(str, ".MEMBER", len) == 0))
1054 * Still need to get to the end of the variable specification,
1055 * so kludge up a Var structure for the modifications
1057 v = VarCreate(str, NULL, VAR_JUNK);
1061 * No modifiers -- have specification length so we can return
1064 *lengthPtr = tstr - start + 1;
1067 str = emalloc(*lengthPtr + 1);
1068 strncpy(str, start, *lengthPtr);
1069 str[*lengthPtr] = '\0';
1071 Buf_Destroy(buf, TRUE);
1074 Buf_Destroy(buf, TRUE);
1075 return (err ? var_Error : varNoError);
1079 Buf_Destroy(buf, TRUE);
1083 * If it's not bounded by braces of some sort, life is much simpler.
1084 * We just need to check for the first character and return the
1085 * value if it exists.
1092 v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
1093 if (v == (Var *)NULL) {
1099 if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
1101 * If substituting a local variable in a non-local context,
1102 * assume it's for dynamic source stuff. We have to handle
1103 * this specially and return the longhand for the variable
1104 * with the dollar sign escaped so it makes it back to the
1105 * caller. Only four of the local variables are treated
1106 * specially as they are the only four that will be set
1107 * when dynamic sources are expanded.
1109 /* XXX: It looks like $% and $! are reversed here */
1112 return ("$(.TARGET)");
1114 return ("$(.ARCHIVE)");
1116 return ("$(.PREFIX)");
1118 return ("$(.MEMBER)");
1126 return (err ? var_Error : varNoError);
1128 haveModifier = FALSE;
1134 if (v->flags & VAR_IN_USE) {
1135 Fatal("Variable %s is recursive.", v->name);
1138 v->flags |= VAR_IN_USE;
1142 * Before doing any modification, we have to make sure the value
1143 * has been fully expanded. If it looks like recursion might be
1144 * necessary (there's a dollar sign somewhere in the variable's value)
1145 * we just call Var_Subst to do any other substitutions that are
1146 * necessary. Note that the value returned by Var_Subst will have
1147 * been dynamically-allocated, so it will need freeing when we
1150 str = (char *)Buf_GetAll(v->val, (size_t *)NULL);
1151 if (strchr(str, '$') != NULL) {
1154 buf = Var_Subst(NULL, str, ctxt, err);
1155 str = Buf_GetAll(buf, NULL);
1156 Buf_Destroy(buf, FALSE);
1161 v->flags &= ~VAR_IN_USE;
1164 * Now we need to apply any modifiers the user wants applied.
1166 * :M<pattern> words which match the given <pattern>.
1167 * <pattern> is of the standard file
1169 * :S<d><pat1><d><pat2><d>[g]
1170 * Substitute <pat2> for <pat1> in the value
1171 * :C<d><pat1><d><pat2><d>[g]
1172 * Substitute <pat2> for regex <pat1> in the value
1173 * :H Substitute the head of each word
1174 * :T Substitute the tail of each word
1175 * :E Substitute the extension (minus '.') of
1177 * :R Substitute the root of each word
1178 * (pathname minus the suffix).
1179 * :lhs=rhs Like :S, but the rhs goes to the end of
1181 * :U Converts variable to upper-case.
1182 * :L Converts variable to lower-case.
1184 if ((str != NULL) && haveModifier) {
1186 * Skip initial colon while putting it back.
1189 while (*tstr != endc) {
1190 char *newStr; /* New value to return */
1191 char termc; /* Character which terminated scan */
1193 DEBUGF(VAR, ("Applying :%c to \"%s\"\n", *tstr, str));
1204 *cp != '\0' && *cp != ':' && *cp != endc;
1207 if (*cp == '\\' && (cp[1] == ':' || cp[1] == endc)) {
1216 * Need to compress the \:'s out of the pattern, so
1217 * allocate enough room to hold the uncompressed
1218 * pattern (note that cp started at tstr+1, so
1219 * cp - tstr takes the null byte into account) and
1220 * compress the pattern into the space.
1222 pattern = emalloc(cp - tstr);
1223 for (cp2 = pattern, cp = tstr + 1;
1227 if ((*cp == '\\') &&
1228 (cp[1] == ':' || cp[1] == endc)) {
1237 if (*tstr == 'M' || *tstr == 'm') {
1238 newStr = VarModify(str, VarMatch, pattern);
1240 newStr = VarModify(str, VarNoMatch, pattern);
1251 Buffer *buf; /* Buffer for patterns */
1258 * If pattern begins with '^', it is anchored to the
1259 * start of the word -- skip over it and flag pattern.
1262 pattern.flags |= VAR_MATCH_START;
1269 * Pass through the lhs looking for 1) escaped delimiters,
1270 * '$'s and backslashes (place the escaped character in
1271 * uninterpreted) and 2) unescaped $'s that aren't before
1272 * the delimiter (expand the variable substitution).
1273 * The result is left in the Buffer buf.
1275 for (cp = tstr; *cp != '\0' && *cp != del; cp++) {
1276 if ((*cp == '\\') &&
1281 Buf_AddByte(buf, (Byte)cp[1]);
1283 } else if (*cp == '$') {
1286 * If unescaped dollar sign not before the
1287 * delimiter, assume it's a variable
1288 * substitution and recurse.
1294 cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
1295 Buf_Append(buf, cp2);
1302 * Unescaped $ at end of pattern => anchor
1305 pattern.flags |= VAR_MATCH_END;
1308 Buf_AddByte(buf, (Byte)*cp);
1312 Buf_AddByte(buf, (Byte)'\0');
1315 * If lhs didn't end with the delimiter, complain and
1319 Fatal("Unclosed substitution for %s (%c missing)",
1324 * Fetch pattern and destroy buffer, but preserve the data
1325 * in it, since that's our lhs. Note that Buf_GetAll
1326 * will return the actual number of bytes, which includes
1327 * the null byte, so we have to decrement the length by
1330 pattern.lhs = (char *)Buf_GetAll(buf, &pattern.leftLen);
1332 Buf_Destroy(buf, FALSE);
1335 * Now comes the replacement string. Three things need to
1336 * be done here: 1) need to compress escaped delimiters and
1337 * ampersands and 2) need to replace unescaped ampersands
1338 * with the l.h.s. (since this isn't regexp, we can do
1339 * it right here) and 3) expand any variable substitutions.
1344 for (cp = tstr; *cp != '\0' && *cp != del; cp++) {
1345 if ((*cp == '\\') &&
1351 Buf_AddByte(buf, (Byte)cp[1]);
1353 } else if ((*cp == '$') && (cp[1] != del)) {
1358 cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
1359 Buf_Append(buf, cp2);
1364 } else if (*cp == '&') {
1365 Buf_AddBytes(buf, pattern.leftLen,
1366 (Byte *)pattern.lhs);
1368 Buf_AddByte(buf, (Byte)*cp);
1372 Buf_AddByte(buf, (Byte)'\0');
1375 * If didn't end in delimiter character, complain
1378 Fatal("Unclosed substitution for %s (%c missing)",
1382 pattern.rhs = (char *)Buf_GetAll(buf, &pattern.rightLen);
1384 Buf_Destroy(buf, FALSE);
1387 * Check for global substitution. If 'g' after the final
1388 * delimiter, substitution is global and is marked that
1393 pattern.flags |= VAR_SUB_GLOBAL;
1398 * Global substitution of the empty string causes an
1399 * infinite number of matches, unless anchored by '^'
1400 * (start of string) or '$' (end of string). Catch the
1401 * infinite substitution here.
1402 * Note that flags can only contain the 3 bits we're
1403 * interested in so we don't have to mask unrelated
1404 * bits. We can test for equality.
1406 if (!pattern.leftLen && pattern.flags == VAR_SUB_GLOBAL)
1407 Fatal("Global substitution of the empty string");
1410 newStr = VarModify(str, VarSubstitute, &pattern);
1412 * Free the two strings.
1420 VarREPattern pattern;
1430 if ((re = VarGetPattern(ctxt, err, &cp, delim, NULL,
1431 NULL, NULL)) == NULL) {
1432 /* was: goto cleanup */
1433 *lengthPtr = cp - start + 1;
1437 Fatal("Unclosed substitution for %s (%c missing)",
1442 if ((pattern.replace = VarGetPattern(ctxt, err, &cp,
1443 delim, NULL, NULL, NULL)) == NULL){
1446 /* was: goto cleanup */
1447 *lengthPtr = cp - start + 1;
1451 Fatal("Unclosed substitution for %s (%c missing)",
1459 pattern.flags |= VAR_SUB_GLOBAL;
1462 pattern.flags |= VAR_SUB_ONE;
1472 error = regcomp(&pattern.re, re, REG_EXTENDED);
1475 *lengthPtr = cp - start + 1;
1476 VarREError(error, &pattern.re, "RE substitution error");
1477 free(pattern.replace);
1481 pattern.nsub = pattern.re.re_nsub + 1;
1482 if (pattern.nsub < 1)
1484 if (pattern.nsub > 10)
1486 pattern.matches = emalloc(pattern.nsub *
1487 sizeof(regmatch_t));
1488 newStr = VarModify(str, VarRESubstitute, &pattern);
1489 regfree(&pattern.re);
1490 free(pattern.replace);
1491 free(pattern.matches);
1495 if (tstr[1] == endc || tstr[1] == ':') {
1497 buf = Buf_Init(MAKE_BSIZE);
1498 for (cp = str; *cp ; cp++)
1499 Buf_AddByte(buf, (Byte)tolower(*cp));
1501 Buf_AddByte(buf, (Byte)'\0');
1502 newStr = (char *)Buf_GetAll(buf, (size_t *)NULL);
1503 Buf_Destroy(buf, FALSE);
1511 if (tstr[1] == endc || tstr[1] == ':') {
1512 newStr = VarSortWords(str, SortIncreasing);
1519 if (tstr[1] == endc || tstr[1] == ':') {
1520 newStr = Var_Quote(str);
1527 if (tstr[1] == endc || tstr[1] == ':') {
1528 newStr = VarModify(str, VarTail, (void *)NULL);
1535 if (tstr[1] == endc || tstr[1] == ':') {
1537 buf = Buf_Init(MAKE_BSIZE);
1538 for (cp = str; *cp ; cp++)
1539 Buf_AddByte(buf, (Byte)toupper(*cp));
1541 Buf_AddByte(buf, (Byte)'\0');
1542 newStr = (char *)Buf_GetAll(buf, (size_t *)NULL);
1543 Buf_Destroy(buf, FALSE);
1551 if (tstr[1] == endc || tstr[1] == ':') {
1552 newStr = VarModify(str, VarHead, (void *)NULL);
1559 if (tstr[1] == endc || tstr[1] == ':') {
1560 newStr = VarModify(str, VarSuffix, (void *)NULL);
1567 if (tstr[1] == endc || tstr[1] == ':') {
1568 newStr = VarModify(str, VarRoot, (void *)NULL);
1576 if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) {
1579 Buffer *buf = Cmd_Exec(str, &error);
1580 newStr = Buf_GetAll(buf, NULL);
1581 Buf_Destroy(buf, FALSE);
1595 * This can either be a bogus modifier or a System-V
1596 * substitution command.
1605 * First we make a pass through the string trying
1606 * to verify it is a SYSV-make-style translation:
1607 * it must be: <string1>=<string2>)
1611 while (*cp != '\0' && cnt) {
1614 /* continue looking for endc */
1616 else if (*cp == endc)
1618 else if (*cp == startc)
1623 if (*cp == endc && eqFound) {
1626 * Now we break this sucker into the lhs and
1627 * rhs. We must null terminate them of course.
1632 if ((pattern.lhs = VarGetPattern(ctxt,
1633 err, &cp, delim, &pattern.flags, &pattern.leftLen,
1635 /* was: goto cleanup */
1636 *lengthPtr = cp - start + 1;
1640 Fatal("Unclosed substitution for %s (%c missing)",
1646 if ((pattern.rhs = VarGetPattern(ctxt,
1647 err, &cp, delim, NULL, &pattern.rightLen,
1648 &pattern)) == NULL) {
1649 /* was: goto cleanup */
1650 *lengthPtr = cp - start + 1;
1654 Fatal("Unclosed substitution for %s (%c missing)",
1660 * SYSV modifications happen through the whole
1661 * string. Note the pattern is anchored at the end.
1665 newStr = VarModify(str, VarSYSVMatch, &pattern);
1674 Error("Unknown modifier '%c'\n", *tstr);
1676 *cp != ':' && *cp != endc && *cp != '\0';
1684 DEBUGF(VAR, ("Result is \"%s\"\n", newStr));
1690 if (str != var_Error) {
1695 if (termc == '\0') {
1696 Error("Unclosed variable specification for %s", v->name);
1697 } else if (termc == ':') {
1704 *lengthPtr = tstr - start + 1;
1706 *lengthPtr = tstr - start + 1;
1710 if (v->flags & VAR_FROM_ENV) {
1711 Boolean destroy = FALSE;
1713 if (str != (char *)Buf_GetAll(v->val, (size_t *)NULL)) {
1717 * Returning the value unmodified, so tell the caller to free
1722 VarDestroy(v, destroy);
1723 } else if (v->flags & VAR_JUNK) {
1725 * Perform any free'ing needed and set *freePtr to FALSE so the caller
1726 * doesn't try to free a static pointer.
1732 VarDestroy(v, TRUE);
1734 str = emalloc(*lengthPtr + 1);
1735 strncpy(str, start, *lengthPtr);
1736 str[*lengthPtr] = '\0';
1739 str = err ? var_Error : varNoError;
1746 *-----------------------------------------------------------------------
1748 * Substitute for all variables in the given string in the given context
1749 * If undefErr is TRUE, Parse_Error will be called when an undefined
1750 * variable is encountered.
1753 * The resulting string.
1756 * None. The old string must be freed by the caller
1757 *-----------------------------------------------------------------------
1760 Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr)
1762 Boolean errorReported;
1763 Buffer *buf; /* Buffer for forming things */
1766 * Set TRUE if an error has already been reported to prevent a
1767 * plethora of messages when recursing.
1769 errorReported = FALSE;
1773 if (var == NULL && (str[0] == '$') && (str[1] == '$')) {
1775 * A dollar sign may be escaped either with another dollar sign.
1776 * In such a case, we skip over the escape character and store the
1777 * dollar sign into the buffer directly.
1779 Buf_AddByte(buf, (Byte)str[0]);
1782 } else if (str[0] == '$') {
1783 char *val; /* Value to substitute for a variable */
1784 size_t length; /* Length of the variable invocation */
1785 Boolean doFree; /* Set true if val should be freed */
1787 * Variable invocation.
1792 if (str[1] == OPEN_PAREN || str[1] == OPEN_BRACKET) {
1793 const char *p = str + 2;
1796 * Scan up to the end of the variable name.
1798 while (*p != '\0' &&
1800 *p != CLOSE_PAREN &&
1801 *p != CLOSE_BRACKET &&
1807 * A variable inside the variable. We cannot expand
1808 * the external variable yet, so we try again with
1812 Buf_AppendRange(buf, str, p);
1817 if (var[p - (str + 2)] == '\0' && strncmp(var, str + 2, p - (str + 2)) == 0) {
1821 * Not the variable we want to expand, scan
1822 * until the next variable
1824 while (*p != '$' && *p != '\0')
1827 Buf_AppendRange(buf, str, p);
1834 * Single letter variable name.
1836 if (var[1] == '\0' && str[1] == var[0]) {
1839 Buf_AddBytes(buf, 2, (const Byte *)str);
1850 val = Var_Parse(str, ctxt, undefErr, &length, &doFree);
1853 * When we come down here, val should either point to the
1854 * value of this variable, suitably modified, or be NULL.
1855 * Length should be the total length of the potential
1856 * variable invocation (from $ to end character...)
1858 if (val == var_Error || val == varNoError) {
1860 * If performing old-time variable substitution, skip over
1861 * the variable and continue with the substitution. Otherwise,
1862 * store the dollar sign and advance str so we continue with
1867 } else if (undefErr) {
1869 * If variable is undefined, complain and skip the
1870 * variable. The complaint will stop us from doing anything
1871 * when the file is parsed.
1873 if (!errorReported) {
1874 Parse_Error(PARSE_FATAL,
1875 "Undefined variable \"%.*s\"",length,str);
1878 errorReported = TRUE;
1880 Buf_AddByte(buf, (Byte)*str);
1885 * We've now got a variable structure to store in. But first,
1886 * advance the string pointer.
1891 * Copy all the characters from the variable value straight
1892 * into the new string.
1894 Buf_Append(buf, val);
1902 * Skip as many characters as possible -- either to the end of
1903 * the string or to the next dollar sign (variable invocation).
1905 const char *cp = str;
1909 } while (str[0] != '$' && str[0] != '\0');
1911 Buf_AppendRange(buf, cp, str);
1919 *-----------------------------------------------------------------------
1921 * Return the tail from each of a list of words. Used to set the
1922 * System V local variables.
1925 * The resulting string.
1930 *-----------------------------------------------------------------------
1933 Var_GetTail(char *file)
1936 return (VarModify(file, VarTail, (void *)NULL));
1940 *-----------------------------------------------------------------------
1942 * Find the leading components of a (list of) filename(s).
1943 * XXX: VarHead does not replace foo by ., as (sun) System V make
1947 * The leading components.
1952 *-----------------------------------------------------------------------
1955 Var_GetHead(char *file)
1958 return (VarModify(file, VarHead, (void *)NULL));
1962 *-----------------------------------------------------------------------
1964 * Initialize the module
1970 * The VAR_CMD and VAR_GLOBAL contexts are created
1971 *-----------------------------------------------------------------------
1977 VAR_GLOBAL = Targ_NewGN("Global");
1978 VAR_CMD = Targ_NewGN("Command");
1981 /****************** PRINT DEBUGGING INFO *****************/
1983 VarPrintVar(void *vp, void *dummy __unused)
1985 Var *v = (Var *) vp;
1987 printf("%-16s = %s\n", v->name, (char *)Buf_GetAll(v->val, (size_t *)NULL));
1992 *-----------------------------------------------------------------------
1994 * print all variables in a context
1995 *-----------------------------------------------------------------------
1998 Var_Dump(GNode *ctxt)
2001 Lst_ForEach(&ctxt->context, VarPrintVar, (void *)NULL);