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
41 #include <sys/cdefs.h>
42 __FBSDID("$FreeBSD$");
46 * Variable-handling functions
49 * Var_Set Set the value of a variable in the given
50 * context. The variable is created if it doesn't
51 * yet exist. The value and variable name need not
54 * Var_Append Append more characters to an existing variable
55 * in the given context. The variable needn't
56 * exist already -- it will be created if it doesn't.
57 * A space is placed between the old value and the
60 * Var_Exists See if a variable exists.
62 * Var_Value Return the value of a variable in a context or
63 * NULL if the variable is undefined.
65 * Var_Subst Substitute named variable, or all variables if
66 * NULL in a string using
67 * the given context as the top-most one. If the
68 * third argument is non-zero, Parse_Error is
69 * called if any variables are undefined.
71 * Var_Parse Parse a variable expansion from a string and
72 * return the result and the number of characters
75 * Var_Delete Delete a variable in a context.
77 * Var_Init Initialize this module.
80 * Var_Dump Print out all variables defined in the given
83 * XXX: There's a lot of duplication in these functions.
87 #include <sys/types.h>
94 * This is a harmless return value for Var_Parse that can be used by Var_Subst
95 * to determine if there was an error in parsing -- easier than returning
96 * a flag, as things outside this module don't give a hoot.
98 char var_Error[] = "";
101 * Similar to var_Error, but returned when the 'err' flag for Var_Parse is
102 * set false. Why not just use a constant? Well, gcc likes to condense
103 * identical string instances...
105 static char varNoError[] = "";
108 * Internally, variables are contained in four different contexts.
109 * 1) the environment. They may not be changed. If an environment
110 * variable is appended-to, the result is placed in the global
112 * 2) the global context. Variables set in the Makefile are located in
113 * the global context. It is the penultimate context searched when
115 * 3) the command-line context. All variables set on the command line
116 * are placed in this context. They are UNALTERABLE once placed here.
117 * 4) the local context. Each target has associated with it a context
118 * list. On this list are located the structures describing such
119 * local variables as $(@) and $(*)
120 * The four contexts are searched in the reverse order from which they are
123 GNode *VAR_GLOBAL; /* variables from the makefile */
124 GNode *VAR_CMD; /* variables defined on the command-line */
126 static Lst allVars; /* List of all variables */
128 #define FIND_CMD 0x1 /* look in VAR_CMD when searching */
129 #define FIND_GLOBAL 0x2 /* look in VAR_GLOBAL as well */
130 #define FIND_ENV 0x4 /* look in the environment also */
133 char *name; /* the variable's name */
134 Buffer val; /* its value */
135 int flags; /* miscellaneous status flags */
136 #define VAR_IN_USE 1 /* Variable's value currently being used.
137 * Used to avoid recursion */
138 #define VAR_FROM_ENV 2 /* Variable comes from the environment */
139 #define VAR_JUNK 4 /* Variable is a junk variable that
140 * should be destroyed when done with
141 * it. Used by Var_Parse for undefined,
142 * modified variables */
145 /* Var*Pattern flags */
146 #define VAR_SUB_GLOBAL 0x01 /* Apply substitution globally */
147 #define VAR_SUB_ONE 0x02 /* Apply substitution to one word */
148 #define VAR_SUB_MATCHED 0x04 /* There was a match */
149 #define VAR_MATCH_START 0x08 /* Match at start of word */
150 #define VAR_MATCH_END 0x10 /* Match at end of word */
151 #define VAR_NOSUBST 0x20 /* don't expand vars in VarGetPattern */
154 char *lhs; /* String to match */
155 int leftLen; /* Length of string */
156 char *rhs; /* Replacement string (w/ &'s removed) */
157 int rightLen; /* Length of replacement */
169 static int VarCmp(void *, void *);
170 static void VarPossiblyExpand(char **, GNode *);
171 static Var *VarFind(char *, GNode *, int);
172 static void VarAdd(char *, char *, GNode *);
173 static void VarDelete(void *);
174 static Boolean VarHead(char *, Boolean, Buffer, void *);
175 static Boolean VarTail(char *, Boolean, Buffer, void *);
176 static Boolean VarSuffix(char *, Boolean, Buffer, void *);
177 static Boolean VarRoot(char *, Boolean, Buffer, void *);
178 static Boolean VarMatch(char *, Boolean, Buffer, void *);
180 static Boolean VarSYSVMatch(char *, Boolean, Buffer, void *);
182 static Boolean VarNoMatch(char *, Boolean, Buffer, void *);
183 static void VarREError(int, regex_t *, const char *);
184 static Boolean VarRESubstitute(char *, Boolean, Buffer, void *);
185 static Boolean VarSubstitute(char *, Boolean, Buffer, void *);
186 static char *VarGetPattern(GNode *, int, char **, int, int *, int *,
188 static char *VarQuote(char *);
189 static char *VarModify(char *, Boolean (*)(char *, Boolean, Buffer, void *),
191 static int VarPrintVar(void *, void *);
194 *-----------------------------------------------------------------------
196 * See if the given variable matches the named one. Called from
197 * Lst_Find when searching for a variable of a given name.
200 * 0 if they match. non-zero otherwise.
204 *-----------------------------------------------------------------------
207 VarCmp (void *v, void *name)
209 return (strcmp ((char *) name, ((Var *) v)->name));
213 *-----------------------------------------------------------------------
214 * VarPossiblyExpand --
215 * Expand a variable name's embedded variables in the given context.
218 * The contents of name, possibly expanded.
221 * The caller must free the new contents or old contents of name.
222 *-----------------------------------------------------------------------
225 VarPossiblyExpand(char **name, GNode *ctxt)
227 if (strchr(*name, '$') != NULL)
228 *name = Var_Subst(NULL, *name, ctxt, 0);
230 *name = estrdup(*name);
234 *-----------------------------------------------------------------------
236 * Find the given variable in the given context and any other contexts
240 * FIND_GLOBAL set means look in the VAR_GLOBAL context too
241 * FIND_CMD set means to look in the VAR_CMD context too
242 * FIND_ENV set means to look in the environment
245 * A pointer to the structure describing the desired variable or
246 * NULL if the variable does not exist.
250 *-----------------------------------------------------------------------
253 VarFind (char *name, GNode *ctxt, int flags)
255 Boolean localCheckEnvFirst;
260 * If the variable name begins with a '.', it could very well be one of
261 * the local ones. We check the name against all the local variables
262 * and substitute the short version in for 'name' if it matches one of
265 if (*name == '.' && isupper((unsigned char) name[1]))
268 if (!strcmp(name, ".ALLSRC"))
270 if (!strcmp(name, ".ARCHIVE"))
274 if (!strcmp(name, ".IMPSRC"))
278 if (!strcmp(name, ".MEMBER"))
282 if (!strcmp(name, ".OODATE"))
286 if (!strcmp(name, ".PREFIX"))
290 if (!strcmp(name, ".TARGET"))
296 * Note whether this is one of the specific variables we were told through
297 * the -E flag to use environment-variable-override for.
299 if (Lst_Find (envFirstVars, (void *)name,
300 (int (*)(void *, void *)) strcmp) != NULL)
302 localCheckEnvFirst = TRUE;
304 localCheckEnvFirst = FALSE;
308 * First look for the variable in the given context. If it's not there,
309 * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order,
310 * depending on the FIND_* flags in 'flags'
312 var = Lst_Find (ctxt->context, (void *)name, VarCmp);
314 if ((var == NULL) && (flags & FIND_CMD) && (ctxt != VAR_CMD)) {
315 var = Lst_Find (VAR_CMD->context, (void *)name, VarCmp);
317 if ((var == NULL) && (flags & FIND_GLOBAL) && (ctxt != VAR_GLOBAL) &&
318 !checkEnvFirst && !localCheckEnvFirst)
320 var = Lst_Find (VAR_GLOBAL->context, (void *)name, VarCmp);
322 if ((var == NULL) && (flags & FIND_ENV)) {
325 if ((env = getenv (name)) != NULL) {
328 v = (Var *) emalloc(sizeof(Var));
329 v->name = estrdup(name);
333 v->val = Buf_Init(len);
334 Buf_AddBytes(v->val, len, (Byte *)env);
336 v->flags = VAR_FROM_ENV;
338 } else if ((checkEnvFirst || localCheckEnvFirst) &&
339 (flags & FIND_GLOBAL) && (ctxt != VAR_GLOBAL))
341 var = Lst_Find (VAR_GLOBAL->context, (void *)name, VarCmp);
343 return ((Var *) NULL);
345 return ((Var *)Lst_Datum(var));
350 } else if (var == NULL) {
351 return ((Var *) NULL);
353 return ((Var *) Lst_Datum (var));
358 *-----------------------------------------------------------------------
360 * Add a new variable of name name and value val to the given context.
366 * The new variable is placed at the front of the given context
367 * The name and val arguments are duplicated so they may
369 *-----------------------------------------------------------------------
372 VarAdd (char *name, char *val, GNode *ctxt)
377 v = (Var *) emalloc (sizeof (Var));
379 v->name = estrdup (name);
381 len = val ? strlen(val) : 0;
382 v->val = Buf_Init(len+1);
383 Buf_AddBytes(v->val, len, (Byte *)val);
387 (void) Lst_AtFront (ctxt->context, (void *)v);
388 (void) Lst_AtEnd (allVars, (void *) v);
389 DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, name, val));
394 *-----------------------------------------------------------------------
396 * Delete a variable and all the space associated with it.
403 *-----------------------------------------------------------------------
410 Buf_Destroy(v->val, TRUE);
417 *-----------------------------------------------------------------------
419 * Remove a variable from a context.
425 * The Var structure is removed and freed.
427 *-----------------------------------------------------------------------
430 Var_Delete(char *name, GNode *ctxt)
434 DEBUGF(VAR, ("%s:delete %s\n", ctxt->name, name));
435 ln = Lst_Find(ctxt->context, (void *)name, VarCmp);
439 v = (Var *)Lst_Datum(ln);
440 Lst_Remove(ctxt->context, ln);
441 ln = Lst_Member(allVars, v);
442 Lst_Remove(allVars, ln);
443 VarDelete((void *) v);
448 *-----------------------------------------------------------------------
450 * Set the variable name to the value val in the given context.
456 * If the variable doesn't yet exist, a new record is created for it.
457 * Else the old value is freed and the new one stuck in its place
460 * The variable is searched for only in its context before being
461 * created in that context. I.e. if the context is VAR_GLOBAL,
462 * only VAR_GLOBAL->context is searched. Likewise if it is VAR_CMD, only
463 * VAR_CMD->context is searched. This is done to avoid the literally
464 * thousands of unnecessary strcmp's that used to be done to
465 * set, say, $(@) or $(<).
466 *-----------------------------------------------------------------------
469 Var_Set (char *name, char *val, GNode *ctxt)
474 * We only look for a variable in the given context since anything set
475 * here will override anything in a lower context, so there's not much
476 * point in searching them all just to save a bit of memory...
478 VarPossiblyExpand(&name, ctxt);
479 v = VarFind (name, ctxt, 0);
480 if (v == (Var *) NULL) {
481 VarAdd (name, val, ctxt);
483 Buf_Discard(v->val, Buf_Size(v->val));
484 Buf_AddBytes(v->val, strlen(val), (Byte *)val);
486 DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, name, val));
489 * Any variables given on the command line are automatically exported
490 * to the environment (as per POSIX standard)
492 if (ctxt == VAR_CMD) {
493 setenv(name, val, 1);
499 *-----------------------------------------------------------------------
501 * The variable of the given name has the given value appended to it in
508 * If the variable doesn't exist, it is created. Else the strings
509 * are concatenated (with a space in between).
512 * Only if the variable is being sought in the global context is the
513 * environment searched.
514 * XXX: Knows its calling circumstances in that if called with ctxt
515 * an actual target, it will only search that context since only
516 * a local variable could be being appended to. This is actually
517 * a big win and must be tolerated.
518 *-----------------------------------------------------------------------
521 Var_Append (char *name, char *val, GNode *ctxt)
525 VarPossiblyExpand(&name, ctxt);
526 v = VarFind (name, ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0);
528 if (v == (Var *) NULL) {
529 VarAdd (name, val, ctxt);
531 Buf_AddByte(v->val, (Byte)' ');
532 Buf_AddBytes(v->val, strlen(val), (Byte *)val);
534 DEBUGF(VAR, ("%s:%s = %s\n", ctxt->name, name,
535 (char *) Buf_GetAll(v->val, (int *)NULL)));
537 if (v->flags & VAR_FROM_ENV) {
539 * If the original variable came from the environment, we
540 * have to install it in the global context (we could place
541 * it in the environment, but then we should provide a way to
542 * export other variables...)
544 v->flags &= ~VAR_FROM_ENV;
545 Lst_AtFront(ctxt->context, (void *)v);
552 *-----------------------------------------------------------------------
554 * See if the given variable exists.
557 * TRUE if it does, FALSE if it doesn't
562 *-----------------------------------------------------------------------
565 Var_Exists(char *name, GNode *ctxt)
569 VarPossiblyExpand(&name, ctxt);
570 v = VarFind(name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV);
573 if (v == (Var *)NULL) {
575 } else if (v->flags & VAR_FROM_ENV) {
577 Buf_Destroy(v->val, TRUE);
584 *-----------------------------------------------------------------------
586 * Return the value of the named variable in the given context
589 * The value if the variable exists, NULL if it doesn't
593 *-----------------------------------------------------------------------
596 Var_Value (char *name, GNode *ctxt, char **frp)
600 VarPossiblyExpand(&name, ctxt);
601 v = VarFind (name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
604 if (v != (Var *) NULL) {
605 char *p = ((char *)Buf_GetAll(v->val, (int *)NULL));
606 if (v->flags & VAR_FROM_ENV) {
607 Buf_Destroy(v->val, FALSE);
613 return ((char *) NULL);
618 *-----------------------------------------------------------------------
620 * Remove the tail of the given word and place the result in the given
624 * TRUE if characters were added to the buffer (a space needs to be
625 * added to the buffer before the next word).
628 * The trimmed word is added to the buffer.
630 *-----------------------------------------------------------------------
633 VarHead (char *word, Boolean addSpace, Buffer buf, void *dummy __unused)
637 slash = strrchr (word, '/');
638 if (slash != (char *)NULL) {
640 Buf_AddByte (buf, (Byte)' ');
643 Buf_AddBytes (buf, strlen (word), (Byte *)word);
648 * If no directory part, give . (q.v. the POSIX standard)
651 Buf_AddBytes(buf, 2, (Byte *)" .");
653 Buf_AddByte(buf, (Byte)'.');
660 *-----------------------------------------------------------------------
662 * Remove the head of the given word and place the result in the given
666 * TRUE if characters were added to the buffer (a space needs to be
667 * added to the buffer before the next word).
670 * The trimmed word is added to the buffer.
672 *-----------------------------------------------------------------------
675 VarTail (char *word, Boolean addSpace, Buffer buf, void *dummy __unused)
680 Buf_AddByte (buf, (Byte)' ');
683 slash = strrchr (word, '/');
684 if (slash != (char *)NULL) {
686 Buf_AddBytes (buf, strlen(slash), (Byte *)slash);
689 Buf_AddBytes (buf, strlen(word), (Byte *)word);
695 *-----------------------------------------------------------------------
697 * Place the suffix of the given word in the given buffer.
700 * TRUE if characters were added to the buffer (a space needs to be
701 * added to the buffer before the next word).
704 * The suffix from the word is placed in the buffer.
706 *-----------------------------------------------------------------------
709 VarSuffix (char *word, Boolean addSpace, Buffer buf, void *dummy __unused)
713 dot = strrchr (word, '.');
714 if (dot != (char *)NULL) {
716 Buf_AddByte (buf, (Byte)' ');
719 Buf_AddBytes (buf, strlen (dot), (Byte *)dot);
727 *-----------------------------------------------------------------------
729 * Remove the suffix of the given word and place the result in the
733 * TRUE if characters were added to the buffer (a space needs to be
734 * added to the buffer before the next word).
737 * The trimmed word is added to the buffer.
739 *-----------------------------------------------------------------------
742 VarRoot (char *word, Boolean addSpace, Buffer buf, void *dummy __unused)
747 Buf_AddByte (buf, (Byte)' ');
750 dot = strrchr (word, '.');
751 if (dot != (char *)NULL) {
753 Buf_AddBytes (buf, strlen (word), (Byte *)word);
756 Buf_AddBytes (buf, strlen(word), (Byte *)word);
762 *-----------------------------------------------------------------------
764 * Place the word in the buffer if it matches the given pattern.
765 * Callback function for VarModify to implement the :M modifier.
766 * A space will be added if requested. A pattern is supplied
767 * which the word must match.
770 * TRUE if a space should be placed in the buffer before the next
774 * The word may be copied to the buffer.
776 *-----------------------------------------------------------------------
779 VarMatch (char *word, Boolean addSpace, Buffer buf, void *pattern)
781 if (Str_Match(word, (char *) pattern)) {
783 Buf_AddByte(buf, (Byte)' ');
786 Buf_AddBytes(buf, strlen(word), (Byte *)word);
793 *-----------------------------------------------------------------------
795 * Place the word in the buffer if it matches the given pattern.
796 * Callback function for VarModify to implement the System V %
797 * modifiers. A space is added if requested.
800 * TRUE if a space should be placed in the buffer before the next
804 * The word may be copied to the buffer.
806 *-----------------------------------------------------------------------
809 VarSYSVMatch (char *word, Boolean addSpace, Buffer buf, void *patp)
813 VarPattern *pat = (VarPattern *) patp;
816 Buf_AddByte(buf, (Byte)' ');
820 if ((ptr = Str_SYSVMatch(word, pat->lhs, &len)) != NULL)
821 Str_SYSVSubst(buf, pat->rhs, ptr, len);
823 Buf_AddBytes(buf, strlen(word), (Byte *) word);
831 *-----------------------------------------------------------------------
833 * Place the word in the buffer if it doesn't match the given pattern.
834 * Callback function for VarModify to implement the :N modifier. A
835 * space is added if requested.
838 * TRUE if a space should be placed in the buffer before the next
842 * The word may be copied to the buffer.
844 *-----------------------------------------------------------------------
847 VarNoMatch (char *word, Boolean addSpace, Buffer buf, void *pattern)
849 if (!Str_Match(word, (char *) pattern)) {
851 Buf_AddByte(buf, (Byte)' ');
854 Buf_AddBytes(buf, strlen(word), (Byte *)word);
861 *-----------------------------------------------------------------------
863 * Perform a string-substitution on the given word, placing the
864 * result in the passed buffer. A space is added if requested.
867 * TRUE if a space is needed before more characters are added.
872 *-----------------------------------------------------------------------
875 VarSubstitute (char *word, Boolean addSpace, Buffer buf, void *patternp)
877 int wordLen; /* Length of word */
878 char *cp; /* General pointer */
879 VarPattern *pattern = (VarPattern *) patternp;
881 wordLen = strlen(word);
882 if (1) { /* substitute in each word of the variable */
884 * Break substitution down into simple anchored cases
885 * and if none of them fits, perform the general substitution case.
887 if ((pattern->flags & VAR_MATCH_START) &&
888 (strncmp(word, pattern->lhs, pattern->leftLen) == 0)) {
890 * Anchored at start and beginning of word matches pattern
892 if ((pattern->flags & VAR_MATCH_END) &&
893 (wordLen == pattern->leftLen)) {
895 * Also anchored at end and matches to the end (word
896 * is same length as pattern) add space and rhs only
897 * if rhs is non-null.
899 if (pattern->rightLen != 0) {
901 Buf_AddByte(buf, (Byte)' ');
904 Buf_AddBytes(buf, pattern->rightLen,
905 (Byte *)pattern->rhs);
907 } else if (pattern->flags & VAR_MATCH_END) {
909 * Doesn't match to end -- copy word wholesale
914 * Matches at start but need to copy in trailing characters
916 if ((pattern->rightLen + wordLen - pattern->leftLen) != 0){
918 Buf_AddByte(buf, (Byte)' ');
922 Buf_AddBytes(buf, pattern->rightLen, (Byte *)pattern->rhs);
923 Buf_AddBytes(buf, wordLen - pattern->leftLen,
924 (Byte *)(word + pattern->leftLen));
926 } else if (pattern->flags & VAR_MATCH_START) {
928 * Had to match at start of word and didn't -- copy whole word.
931 } else if (pattern->flags & VAR_MATCH_END) {
933 * Anchored at end, Find only place match could occur (leftLen
934 * characters from the end of the word) and see if it does. Note
935 * that because the $ will be left at the end of the lhs, we have
938 cp = word + (wordLen - pattern->leftLen);
940 (strncmp(cp, pattern->lhs, pattern->leftLen) == 0)) {
942 * Match found. If we will place characters in the buffer,
943 * add a space before hand as indicated by addSpace, then
944 * stuff in the initial, unmatched part of the word followed
945 * by the right-hand-side.
947 if (((cp - word) + pattern->rightLen) != 0) {
949 Buf_AddByte(buf, (Byte)' ');
953 Buf_AddBytes(buf, cp - word, (Byte *)word);
954 Buf_AddBytes(buf, pattern->rightLen, (Byte *)pattern->rhs);
957 * Had to match at end and didn't. Copy entire word.
963 * Pattern is unanchored: search for the pattern in the word using
964 * String_FindSubstring, copying unmatched portions and the
965 * right-hand-side for each match found, handling non-global
966 * substitutions correctly, etc. When the loop is done, any
967 * remaining part of the word (word and wordLen are adjusted
968 * accordingly through the loop) is copied straight into the
970 * addSpace is set FALSE as soon as a space is added to the
977 origSize = Buf_Size(buf);
979 cp = Str_FindSubstring(word, pattern->lhs);
980 if (cp != (char *)NULL) {
981 if (addSpace && (((cp - word) + pattern->rightLen) != 0)){
982 Buf_AddByte(buf, (Byte)' ');
985 Buf_AddBytes(buf, cp-word, (Byte *)word);
986 Buf_AddBytes(buf, pattern->rightLen, (Byte *)pattern->rhs);
987 wordLen -= (cp - word) + pattern->leftLen;
988 word = cp + pattern->leftLen;
989 if (wordLen == 0 || (pattern->flags & VAR_SUB_GLOBAL) == 0){
998 Buf_AddByte(buf, (Byte)' ');
1000 Buf_AddBytes(buf, wordLen, (Byte *)word);
1003 * If added characters to the buffer, need to add a space
1004 * before we add any more. If we didn't add any, just return
1005 * the previous value of addSpace.
1007 return ((Buf_Size(buf) != origSize) || addSpace);
1010 * Common code for anchored substitutions:
1011 * addSpace was set TRUE if characters were added to the buffer.
1017 Buf_AddByte(buf, (Byte)' ');
1019 Buf_AddBytes(buf, wordLen, (Byte *)word);
1024 *-----------------------------------------------------------------------
1026 * Print the error caused by a regcomp or regexec call.
1032 * An error gets printed.
1034 *-----------------------------------------------------------------------
1037 VarREError(int err, regex_t *pat, const char *str)
1042 errlen = regerror(err, pat, 0, 0);
1043 errbuf = emalloc(errlen);
1044 regerror(err, pat, errbuf, errlen);
1045 Error("%s: %s", str, errbuf);
1051 *-----------------------------------------------------------------------
1052 * VarRESubstitute --
1053 * Perform a regex substitution on the given word, placing the
1054 * result in the passed buffer. A space is added if requested.
1057 * TRUE if a space is needed before more characters are added.
1062 *-----------------------------------------------------------------------
1065 VarRESubstitute(char *word, Boolean addSpace, Buffer buf, void *patternp)
1074 #define MAYBE_ADD_SPACE() \
1075 if (addSpace && !added) \
1076 Buf_AddByte(buf, ' '); \
1083 if ((pat->flags & (VAR_SUB_ONE|VAR_SUB_MATCHED)) ==
1084 (VAR_SUB_ONE|VAR_SUB_MATCHED))
1088 xrv = regexec(&pat->re, wp, pat->nsub, pat->matches, flags);
1093 pat->flags |= VAR_SUB_MATCHED;
1094 if (pat->matches[0].rm_so > 0) {
1096 Buf_AddBytes(buf, pat->matches[0].rm_so, wp);
1099 for (rp = pat->replace; *rp; rp++) {
1100 if ((*rp == '\\') && ((rp[1] == '&') || (rp[1] == '\\'))) {
1102 Buf_AddByte(buf,rp[1]);
1105 else if ((*rp == '&') ||
1106 ((*rp == '\\') && isdigit((unsigned char)rp[1]))) {
1124 if (n > pat->nsub) {
1125 Error("No subexpression %s", &errstr[0]);
1128 } else if ((pat->matches[n].rm_so == -1) &&
1129 (pat->matches[n].rm_eo == -1)) {
1130 Error("No match for subexpression %s", &errstr[0]);
1134 subbuf = wp + pat->matches[n].rm_so;
1135 sublen = pat->matches[n].rm_eo - pat->matches[n].rm_so;
1140 Buf_AddBytes(buf, sublen, subbuf);
1144 Buf_AddByte(buf, *rp);
1147 wp += pat->matches[0].rm_eo;
1148 if (pat->flags & VAR_SUB_GLOBAL) {
1149 flags |= REG_NOTBOL;
1150 if (pat->matches[0].rm_so == 0 && pat->matches[0].rm_eo == 0) {
1152 Buf_AddByte(buf, *wp);
1161 Buf_AddBytes(buf, strlen(wp), wp);
1165 VarREError(xrv, &pat->re, "Unexpected regex error");
1170 Buf_AddBytes(buf,strlen(wp),wp);
1174 return(addSpace||added);
1179 *-----------------------------------------------------------------------
1181 * Modify each of the words of the passed string using the given
1182 * function. Used to implement all modifiers.
1185 * A string of all the words modified appropriately.
1190 *-----------------------------------------------------------------------
1193 VarModify (char *str, Boolean (*modProc)(char *, Boolean, Buffer, void *),
1196 Buffer buf; /* Buffer for the new string */
1197 Boolean addSpace; /* TRUE if need to add a space to the
1198 * buffer before adding the trimmed
1200 char **av; /* word list [first word does not count] */
1206 av = brk_string(str, &ac, FALSE);
1208 for (i = 1; i < ac; i++)
1209 addSpace = (*modProc)(av[i], addSpace, buf, datum);
1211 Buf_AddByte (buf, '\0');
1212 str = (char *)Buf_GetAll (buf, (int *)NULL);
1213 Buf_Destroy (buf, FALSE);
1218 *-----------------------------------------------------------------------
1220 * Pass through the tstr looking for 1) escaped delimiters,
1221 * '$'s and backslashes (place the escaped character in
1222 * uninterpreted) and 2) unescaped $'s that aren't before
1223 * the delimiter (expand the variable substitution unless flags
1224 * has VAR_NOSUBST set).
1225 * Return the expanded string or NULL if the delimiter was missing
1226 * If pattern is specified, handle escaped ampersands, and replace
1227 * unescaped ampersands with the lhs of the pattern.
1230 * A string of all the words modified appropriately.
1231 * If length is specified, return the string length of the buffer
1232 * If flags is specified and the last character of the pattern is a
1233 * $ set the VAR_MATCH_END bit of flags.
1237 *-----------------------------------------------------------------------
1240 VarGetPattern(GNode *ctxt, int err, char **tstr, int delim, int *flags,
1241 int *length, VarPattern *pattern)
1244 Buffer buf = Buf_Init(0);
1249 #define IS_A_MATCH(cp, delim) \
1250 ((cp[0] == '\\') && ((cp[1] == delim) || \
1251 (cp[1] == '\\') || (cp[1] == '$') || (pattern && (cp[1] == '&'))))
1254 * Skim through until the matching delimiter is found;
1255 * pick up variable substitutions on the way. Also allow
1256 * backslashes to quote the delimiter, $, and \, but don't
1257 * touch other backslashes.
1259 for (cp = *tstr; *cp && (*cp != delim); cp++) {
1260 if (IS_A_MATCH(cp, delim)) {
1261 Buf_AddByte(buf, (Byte) cp[1]);
1263 } else if (*cp == '$') {
1264 if (cp[1] == delim) {
1266 Buf_AddByte(buf, (Byte) *cp);
1269 * Unescaped $ at end of pattern => anchor
1272 *flags |= VAR_MATCH_END;
1274 if (flags == NULL || (*flags & VAR_NOSUBST) == 0) {
1280 * If unescaped dollar sign not before the
1281 * delimiter, assume it's a variable
1282 * substitution and recurse.
1284 cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
1285 Buf_AddBytes(buf, strlen(cp2), (Byte *) cp2);
1292 if (*cp2 == '(' || *cp2 == '{') {
1294 * Find the end of this variable reference
1295 * and suck it in without further ado.
1296 * It will be interperated later.
1299 int want = (*cp2 == '(') ? ')' : '}';
1302 for (++cp2; *cp2 != '\0' && depth > 0; ++cp2) {
1303 if (cp2[-1] != '\\') {
1310 Buf_AddBytes(buf, cp2 - cp, (Byte *)cp);
1313 Buf_AddByte(buf, (Byte) *cp);
1317 else if (pattern && *cp == '&')
1318 Buf_AddBytes(buf, pattern->leftLen, (Byte *)pattern->lhs);
1320 Buf_AddByte(buf, (Byte) *cp);
1323 Buf_AddByte(buf, (Byte) '\0');
1332 cp = (char *) Buf_GetAll(buf, length);
1333 *length -= 1; /* Don't count the NULL */
1334 Buf_Destroy(buf, FALSE);
1341 *-----------------------------------------------------------------------
1343 * Quote shell meta-characters in the string
1351 *-----------------------------------------------------------------------
1358 /* This should cover most shells :-( */
1359 static char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~";
1361 buf = Buf_Init (MAKE_BSIZE);
1362 for (; *str; str++) {
1363 if (strchr(meta, *str) != NULL)
1364 Buf_AddByte(buf, (Byte)'\\');
1365 Buf_AddByte(buf, (Byte)*str);
1367 Buf_AddByte(buf, (Byte) '\0');
1368 str = (char *)Buf_GetAll (buf, (int *)NULL);
1369 Buf_Destroy (buf, FALSE);
1374 *-----------------------------------------------------------------------
1376 * Given the start of a variable invocation, extract the variable
1377 * name and find its value, then modify it according to the
1381 * The (possibly-modified) value of the variable or var_Error if the
1382 * specification is invalid. The length of the specification is
1383 * placed in *lengthPtr (for invalid specifications, this is just
1385 * A Boolean in *freePtr telling whether the returned string should
1386 * be freed by the caller.
1391 *-----------------------------------------------------------------------
1394 Var_Parse(char *str, GNode *ctxt, Boolean err, int *lengthPtr, Boolean *freePtr)
1396 char *tstr; /* Pointer into str */
1397 Var *v; /* Variable in invocation */
1398 char *cp; /* Secondary pointer into str (place marker
1400 Boolean haveModifier;/* TRUE if have modifiers for the variable */
1401 char endc; /* Ending character when variable in parens
1403 char startc=0; /* Starting character when variable in parens
1405 int cnt; /* Used to count brace pairs when variable in
1406 * in parens or braces */
1409 Boolean dynamic; /* TRUE if the variable is local and we're
1410 * expanding it in a non-local context. This
1411 * is done to support dynamic sources. The
1412 * result is just the invocation, unaltered */
1413 int vlen; /* length of variable name, after embedded variable
1420 if (str[1] != '(' && str[1] != '{') {
1422 * If it's not bounded by braces of some sort, life is much simpler.
1423 * We just need to check for the first character and return the
1424 * value if it exists.
1431 v = VarFind (name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
1432 if (v == (Var *)NULL) {
1435 if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
1437 * If substituting a local variable in a non-local context,
1438 * assume it's for dynamic source stuff. We have to handle
1439 * this specially and return the longhand for the variable
1440 * with the dollar sign escaped so it makes it back to the
1441 * caller. Only four of the local variables are treated
1442 * specially as they are the only four that will be set
1443 * when dynamic sources are expanded.
1445 /* XXX: It looks like $% and $! are reversed here */
1448 return("$(.TARGET)");
1450 return("$(.ARCHIVE)");
1452 return("$(.PREFIX)");
1454 return("$(.MEMBER)");
1462 return (err ? var_Error : varNoError);
1464 haveModifier = FALSE;
1469 /* build up expanded variable name in this buffer */
1470 Buffer buf = Buf_Init(MAKE_BSIZE);
1473 endc = startc == '(' ? ')' : '}';
1476 * Skip to the end character or a colon, whichever comes first,
1477 * replacing embedded variables as we go.
1479 for (tstr = str + 2; *tstr != '\0' && *tstr != endc && *tstr != ':'; tstr++)
1483 char* rval = Var_Parse(tstr, ctxt, err, &rlen, &rfree);
1485 if (rval == var_Error) {
1486 Fatal("Error expanding embedded variable.");
1487 } else if (rval != NULL) {
1488 Buf_AddBytes(buf, strlen(rval), (Byte *) rval);
1494 Buf_AddByte(buf, (Byte) *tstr);
1496 if (*tstr == '\0') {
1498 * If we never did find the end character, return NULL
1499 * right now, setting the length to be the distance to
1500 * the end of the string, since that's what make does.
1502 *lengthPtr = tstr - str;
1506 haveModifier = (*tstr == ':');
1509 Buf_AddByte(buf, (Byte) '\0');
1510 str = Buf_GetAll(buf, NULL);
1513 v = VarFind (str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
1514 if ((v == (Var *)NULL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
1515 (vlen == 2) && (str[1] == 'F' || str[1] == 'D'))
1518 * Check for bogus D and F forms of local variables since we're
1519 * in a local context and the name is the right length.
1533 * Well, it's local -- go look for it.
1537 v = VarFind(vname, ctxt, 0);
1539 if (v != (Var *)NULL && !haveModifier) {
1541 * No need for nested expansion or anything, as we're
1542 * the only one who sets these things and we sure don't
1543 * put nested invocations in them...
1545 val = (char *)Buf_GetAll(v->val, (int *)NULL);
1547 if (str[1] == 'D') {
1548 val = VarModify(val, VarHead, (void *)0);
1550 val = VarModify(val, VarTail, (void *)0);
1553 * Resulting string is dynamically allocated, so
1554 * tell caller to free it.
1557 *lengthPtr = tstr-start+1;
1559 Buf_Destroy(buf, TRUE);
1569 if (v == (Var *)NULL) {
1571 (((vlen == 2) && (str[1] == 'F' ||
1572 str[1] == 'D')))) &&
1573 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
1576 * If substituting a local variable in a non-local context,
1577 * assume it's for dynamic source stuff. We have to handle
1578 * this specially and return the longhand for the variable
1579 * with the dollar sign escaped so it makes it back to the
1580 * caller. Only four of the local variables are treated
1581 * specially as they are the only four that will be set
1582 * when dynamic sources are expanded.
1594 } else if ((vlen > 2) && (str[0] == '.') &&
1595 isupper((unsigned char) str[1]) &&
1596 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
1601 if ((strncmp(str, ".TARGET", len) == 0) ||
1602 (strncmp(str, ".ARCHIVE", len) == 0) ||
1603 (strncmp(str, ".PREFIX", len) == 0) ||
1604 (strncmp(str, ".MEMBER", len) == 0))
1610 if (!haveModifier) {
1612 * No modifiers -- have specification length so we can return
1615 *lengthPtr = tstr - start + 1;
1618 str = emalloc(*lengthPtr + 1);
1619 strncpy(str, start, *lengthPtr);
1620 str[*lengthPtr] = '\0';
1622 Buf_Destroy(buf, TRUE);
1625 Buf_Destroy(buf, TRUE);
1626 return (err ? var_Error : varNoError);
1630 * Still need to get to the end of the variable specification,
1631 * so kludge up a Var structure for the modifications
1633 v = (Var *) emalloc(sizeof(Var));
1635 v->val = Buf_Init(1);
1636 v->flags = VAR_JUNK;
1639 Buf_Destroy(buf, TRUE);
1642 if (v->flags & VAR_IN_USE) {
1643 Fatal("Variable %s is recursive.", v->name);
1646 v->flags |= VAR_IN_USE;
1649 * Before doing any modification, we have to make sure the value
1650 * has been fully expanded. If it looks like recursion might be
1651 * necessary (there's a dollar sign somewhere in the variable's value)
1652 * we just call Var_Subst to do any other substitutions that are
1653 * necessary. Note that the value returned by Var_Subst will have
1654 * been dynamically-allocated, so it will need freeing when we
1657 str = (char *)Buf_GetAll(v->val, (int *)NULL);
1658 if (strchr (str, '$') != (char *)NULL) {
1659 str = Var_Subst(NULL, str, ctxt, err);
1663 v->flags &= ~VAR_IN_USE;
1666 * Now we need to apply any modifiers the user wants applied.
1668 * :M<pattern> words which match the given <pattern>.
1669 * <pattern> is of the standard file
1671 * :S<d><pat1><d><pat2><d>[g]
1672 * Substitute <pat2> for <pat1> in the value
1673 * :C<d><pat1><d><pat2><d>[g]
1674 * Substitute <pat2> for regex <pat1> in the value
1675 * :H Substitute the head of each word
1676 * :T Substitute the tail of each word
1677 * :E Substitute the extension (minus '.') of
1679 * :R Substitute the root of each word
1680 * (pathname minus the suffix).
1681 * :lhs=rhs Like :S, but the rhs goes to the end of
1683 * :U Converts variable to upper-case.
1684 * :L Converts variable to lower-case.
1686 if ((str != (char *)NULL) && haveModifier) {
1688 * Skip initial colon while putting it back.
1691 while (*tstr != endc) {
1692 char *newStr; /* New value to return */
1693 char termc; /* Character which terminated scan */
1695 DEBUGF(VAR, ("Applying :%c to \"%s\"\n", *tstr, str));
1698 if (tstr[1] == endc || tstr[1] == ':') {
1700 buf = Buf_Init(MAKE_BSIZE);
1701 for (cp = str; *cp ; cp++)
1702 Buf_AddByte(buf, (Byte) toupper(*cp));
1704 Buf_AddByte(buf, (Byte) '\0');
1705 newStr = (char *) Buf_GetAll(buf, (int *) NULL);
1706 Buf_Destroy(buf, FALSE);
1714 if (tstr[1] == endc || tstr[1] == ':') {
1716 buf = Buf_Init(MAKE_BSIZE);
1717 for (cp = str; *cp ; cp++)
1718 Buf_AddByte(buf, (Byte) tolower(*cp));
1720 Buf_AddByte(buf, (Byte) '\0');
1721 newStr = (char *) Buf_GetAll(buf, (int *) NULL);
1722 Buf_Destroy(buf, FALSE);
1738 *cp != '\0' && *cp != ':' && *cp != endc;
1741 if (*cp == '\\' && (cp[1] == ':' || cp[1] == endc)){
1750 * Need to compress the \:'s out of the pattern, so
1751 * allocate enough room to hold the uncompressed
1752 * pattern (note that cp started at tstr+1, so
1753 * cp - tstr takes the null byte into account) and
1754 * compress the pattern into the space.
1756 pattern = emalloc(cp - tstr);
1757 for (cp2 = pattern, cp = tstr + 1;
1761 if ((*cp == '\\') &&
1762 (cp[1] == ':' || cp[1] == endc)) {
1771 if (*tstr == 'M' || *tstr == 'm') {
1772 newStr = VarModify(str, VarMatch, (void *)pattern);
1774 newStr = VarModify(str, VarNoMatch,
1786 Buffer buf; /* Buffer for patterns */
1793 * If pattern begins with '^', it is anchored to the
1794 * start of the word -- skip over it and flag pattern.
1797 pattern.flags |= VAR_MATCH_START;
1804 * Pass through the lhs looking for 1) escaped delimiters,
1805 * '$'s and backslashes (place the escaped character in
1806 * uninterpreted) and 2) unescaped $'s that aren't before
1807 * the delimiter (expand the variable substitution).
1808 * The result is left in the Buffer buf.
1810 for (cp = tstr; *cp != '\0' && *cp != del; cp++) {
1811 if ((*cp == '\\') &&
1816 Buf_AddByte(buf, (Byte)cp[1]);
1818 } else if (*cp == '$') {
1821 * If unescaped dollar sign not before the
1822 * delimiter, assume it's a variable
1823 * substitution and recurse.
1829 cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
1830 Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2);
1837 * Unescaped $ at end of pattern => anchor
1840 pattern.flags |= VAR_MATCH_END;
1843 Buf_AddByte(buf, (Byte)*cp);
1847 Buf_AddByte(buf, (Byte)'\0');
1850 * If lhs didn't end with the delimiter, complain and
1854 *lengthPtr = cp - start + 1;
1858 Buf_Destroy(buf, TRUE);
1859 Error("Unclosed substitution for %s (%c missing)",
1865 * Fetch pattern and destroy buffer, but preserve the data
1866 * in it, since that's our lhs. Note that Buf_GetAll
1867 * will return the actual number of bytes, which includes
1868 * the null byte, so we have to decrement the length by
1871 pattern.lhs = (char *)Buf_GetAll(buf, &pattern.leftLen);
1873 Buf_Destroy(buf, FALSE);
1876 * Now comes the replacement string. Three things need to
1877 * be done here: 1) need to compress escaped delimiters and
1878 * ampersands and 2) need to replace unescaped ampersands
1879 * with the l.h.s. (since this isn't regexp, we can do
1880 * it right here) and 3) expand any variable substitutions.
1885 for (cp = tstr; *cp != '\0' && *cp != del; cp++) {
1886 if ((*cp == '\\') &&
1892 Buf_AddByte(buf, (Byte)cp[1]);
1894 } else if ((*cp == '$') && (cp[1] != del)) {
1899 cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
1900 Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2);
1905 } else if (*cp == '&') {
1906 Buf_AddBytes(buf, pattern.leftLen,
1907 (Byte *)pattern.lhs);
1909 Buf_AddByte(buf, (Byte)*cp);
1913 Buf_AddByte(buf, (Byte)'\0');
1916 * If didn't end in delimiter character, complain
1919 *lengthPtr = cp - start + 1;
1923 Buf_Destroy(buf, TRUE);
1924 Error("Unclosed substitution for %s (%c missing)",
1929 pattern.rhs = (char *)Buf_GetAll(buf, &pattern.rightLen);
1931 Buf_Destroy(buf, FALSE);
1934 * Check for global substitution. If 'g' after the final
1935 * delimiter, substitution is global and is marked that
1940 pattern.flags |= VAR_SUB_GLOBAL;
1945 newStr = VarModify(str, VarSubstitute,
1948 * Free the two strings.
1956 VarREPattern pattern;
1966 if ((re = VarGetPattern(ctxt, err, &cp, delim, NULL,
1967 NULL, NULL)) == NULL) {
1968 /* was: goto cleanup */
1969 *lengthPtr = cp - start + 1;
1973 Error("Unclosed substitution for %s (%c missing)",
1978 if ((pattern.replace = VarGetPattern(ctxt, err, &cp,
1979 delim, NULL, NULL, NULL)) == NULL){
1982 /* was: goto cleanup */
1983 *lengthPtr = cp - start + 1;
1987 Error("Unclosed substitution for %s (%c missing)",
1995 pattern.flags |= VAR_SUB_GLOBAL;
1998 pattern.flags |= VAR_SUB_ONE;
2008 error = regcomp(&pattern.re, re, REG_EXTENDED);
2011 *lengthPtr = cp - start + 1;
2012 VarREError(error, &pattern.re, "RE substitution error");
2013 free(pattern.replace);
2017 pattern.nsub = pattern.re.re_nsub + 1;
2018 if (pattern.nsub < 1)
2020 if (pattern.nsub > 10)
2022 pattern.matches = emalloc(pattern.nsub *
2023 sizeof(regmatch_t));
2024 newStr = VarModify(str, VarRESubstitute,
2026 regfree(&pattern.re);
2027 free(pattern.replace);
2028 free(pattern.matches);
2032 if (tstr[1] == endc || tstr[1] == ':') {
2033 newStr = VarQuote (str);
2040 if (tstr[1] == endc || tstr[1] == ':') {
2041 newStr = VarModify (str, VarTail, (void *)0);
2048 if (tstr[1] == endc || tstr[1] == ':') {
2049 newStr = VarModify (str, VarHead, (void *)0);
2056 if (tstr[1] == endc || tstr[1] == ':') {
2057 newStr = VarModify (str, VarSuffix, (void *)0);
2064 if (tstr[1] == endc || tstr[1] == ':') {
2065 newStr = VarModify (str, VarRoot, (void *)0);
2073 if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) {
2075 newStr = Cmd_Exec (str, &error);
2088 * This can either be a bogus modifier or a System-V
2089 * substitution command.
2097 * First we make a pass through the string trying
2098 * to verify it is a SYSV-make-style translation:
2099 * it must be: <string1>=<string2>)
2103 while (*cp != '\0' && cnt) {
2106 /* continue looking for endc */
2108 else if (*cp == endc)
2110 else if (*cp == startc)
2115 if (*cp == endc && eqFound) {
2118 * Now we break this sucker into the lhs and
2119 * rhs. We must null terminate them of course.
2121 for (cp = tstr; *cp != '='; cp++)
2124 pattern.leftLen = cp - tstr;
2132 else if (*cp == startc)
2137 pattern.rightLen = cp - pattern.rhs;
2141 * SYSV modifications happen through the whole
2142 * string. Note the pattern is anchored at the end.
2144 newStr = VarModify(str, VarSYSVMatch,
2148 * Restore the nulled characters
2150 pattern.lhs[pattern.leftLen] = '=';
2151 pattern.rhs[pattern.rightLen] = endc;
2156 Error ("Unknown modifier '%c'\n", *tstr);
2158 *cp != ':' && *cp != endc && *cp != '\0';
2166 DEBUGF(VAR, ("Result is \"%s\"\n", newStr));
2172 if (str != var_Error) {
2177 if (termc == '\0') {
2178 Error("Unclosed variable specification for %s", v->name);
2179 } else if (termc == ':') {
2186 *lengthPtr = tstr - start + 1;
2188 *lengthPtr = tstr - start + 1;
2192 if (v->flags & VAR_FROM_ENV) {
2193 Boolean destroy = FALSE;
2195 if (str != (char *)Buf_GetAll(v->val, (int *)NULL)) {
2199 * Returning the value unmodified, so tell the caller to free
2204 Buf_Destroy(v->val, destroy);
2206 } else if (v->flags & VAR_JUNK) {
2208 * Perform any free'ing needed and set *freePtr to FALSE so the caller
2209 * doesn't try to free a static pointer.
2215 Buf_Destroy(v->val, TRUE);
2218 str = emalloc(*lengthPtr + 1);
2219 strncpy(str, start, *lengthPtr);
2220 str[*lengthPtr] = '\0';
2223 str = err ? var_Error : varNoError;
2230 *-----------------------------------------------------------------------
2232 * Substitute for all variables in the given string in the given context
2233 * If undefErr is TRUE, Parse_Error will be called when an undefined
2234 * variable is encountered.
2237 * The resulting string.
2240 * None. The old string must be freed by the caller
2241 *-----------------------------------------------------------------------
2244 Var_Subst (char *var, char *str, GNode *ctxt, Boolean undefErr)
2246 Buffer buf; /* Buffer for forming things */
2247 char *val; /* Value to substitute for a variable */
2248 int length; /* Length of the variable invocation */
2249 Boolean doFree; /* Set true if val should be freed */
2250 static Boolean errorReported; /* Set true if an error has already
2251 * been reported to prevent a plethora
2252 * of messages when recursing */
2254 buf = Buf_Init (MAKE_BSIZE);
2255 errorReported = FALSE;
2258 if (var == NULL && (*str == '$') && (str[1] == '$')) {
2260 * A dollar sign may be escaped either with another dollar sign.
2261 * In such a case, we skip over the escape character and store the
2262 * dollar sign into the buffer directly.
2265 Buf_AddByte(buf, (Byte)*str);
2267 } else if (*str != '$') {
2269 * Skip as many characters as possible -- either to the end of
2270 * the string or to the next dollar sign (variable invocation).
2274 for (cp = str++; *str != '$' && *str != '\0'; str++)
2276 Buf_AddBytes(buf, str - cp, (Byte *)cp);
2281 if (str[1] != '(' && str[1] != '{') {
2282 if (str[1] != *var) {
2283 Buf_AddBytes(buf, 2, (Byte *) str);
2295 * Scan up to the end of the variable name.
2297 for (p = &str[2]; *p &&
2298 *p != ':' && *p != ')' && *p != '}'; p++)
2302 * A variable inside the variable. We cannot expand
2303 * the external variable yet, so we try again with
2307 Buf_AddBytes(buf, p - str, (Byte *) str);
2312 if (strncmp(var, str + 2, p - str - 2) != 0 ||
2313 var[p - str - 2] != '\0') {
2315 * Not the variable we want to expand, scan
2316 * until the next variable
2318 for (;*p != '$' && *p != '\0'; p++)
2320 Buf_AddBytes(buf, p - str, (Byte *) str);
2333 val = Var_Parse (str, ctxt, undefErr, &length, &doFree);
2336 * When we come down here, val should either point to the
2337 * value of this variable, suitably modified, or be NULL.
2338 * Length should be the total length of the potential
2339 * variable invocation (from $ to end character...)
2341 if (val == var_Error || val == varNoError) {
2343 * If performing old-time variable substitution, skip over
2344 * the variable and continue with the substitution. Otherwise,
2345 * store the dollar sign and advance str so we continue with
2350 } else if (undefErr) {
2352 * If variable is undefined, complain and skip the
2353 * variable. The complaint will stop us from doing anything
2354 * when the file is parsed.
2356 if (!errorReported) {
2357 Parse_Error (PARSE_FATAL,
2358 "Undefined variable \"%.*s\"",length,str);
2361 errorReported = TRUE;
2363 Buf_AddByte (buf, (Byte)*str);
2368 * We've now got a variable structure to store in. But first,
2369 * advance the string pointer.
2374 * Copy all the characters from the variable value straight
2375 * into the new string.
2377 Buf_AddBytes (buf, strlen (val), (Byte *)val);
2385 Buf_AddByte (buf, '\0');
2386 str = (char *)Buf_GetAll (buf, (int *)NULL);
2387 Buf_Destroy (buf, FALSE);
2392 *-----------------------------------------------------------------------
2394 * Return the tail from each of a list of words. Used to set the
2395 * System V local variables.
2398 * The resulting string.
2403 *-----------------------------------------------------------------------
2406 Var_GetTail(char *file)
2408 return(VarModify(file, VarTail, (void *)0));
2412 *-----------------------------------------------------------------------
2414 * Find the leading components of a (list of) filename(s).
2415 * XXX: VarHead does not replace foo by ., as (sun) System V make
2419 * The leading components.
2424 *-----------------------------------------------------------------------
2427 Var_GetHead(char *file)
2429 return(VarModify(file, VarHead, (void *)0));
2433 *-----------------------------------------------------------------------
2435 * Initialize the module
2441 * The VAR_CMD and VAR_GLOBAL contexts are created
2442 *-----------------------------------------------------------------------
2447 VAR_GLOBAL = Targ_NewGN ("Global");
2448 VAR_CMD = Targ_NewGN ("Command");
2449 allVars = Lst_Init(FALSE);
2457 Lst_Destroy(allVars, VarDelete);
2461 /****************** PRINT DEBUGGING INFO *****************/
2463 VarPrintVar (void *vp, void *dummy __unused)
2465 Var *v = (Var *) vp;
2466 printf ("%-16s = %s\n", v->name, (char *) Buf_GetAll(v->val, (int *)NULL));
2471 *-----------------------------------------------------------------------
2473 * print all variables in a context
2474 *-----------------------------------------------------------------------
2477 Var_Dump (GNode *ctxt)
2479 Lst_ForEach (ctxt->context, VarPrintVar, (void *) 0);