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.5 2004/04/19 17:44:53 cpressey 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.
86 #include <sys/types.h>
93 * This is a harmless return value for Var_Parse that can be used by Var_Subst
94 * to determine if there was an error in parsing -- easier than returning
95 * a flag, as things outside this module don't give a hoot.
97 char var_Error[] = "";
100 * Similar to var_Error, but returned when the 'err' flag for Var_Parse is
101 * set false. Why not just use a constant? Well, gcc likes to condense
102 * identical string instances...
104 static char varNoError[] = "";
107 * Internally, variables are contained in four different contexts.
108 * 1) the environment. They may not be changed. If an environment
109 * variable is appended-to, the result is placed in the global
111 * 2) the global context. Variables set in the Makefile are located in
112 * the global context. It is the penultimate context searched when
114 * 3) the command-line context. All variables set on the command line
115 * are placed in this context. They are UNALTERABLE once placed here.
116 * 4) the local context. Each target has associated with it a context
117 * list. On this list are located the structures describing such
118 * local variables as $(@) and $(*)
119 * The four contexts are searched in the reverse order from which they are
122 GNode *VAR_GLOBAL; /* variables from the makefile */
123 GNode *VAR_CMD; /* variables defined on the command-line */
125 static Lst allVars; /* List of all variables */
127 #define FIND_CMD 0x1 /* look in VAR_CMD when searching */
128 #define FIND_GLOBAL 0x2 /* look in VAR_GLOBAL as well */
129 #define FIND_ENV 0x4 /* look in the environment also */
132 char *name; /* the variable's name */
133 Buffer val; /* its value */
134 int flags; /* miscellaneous status flags */
135 #define VAR_IN_USE 1 /* Variable's value currently being used.
136 * Used to avoid recursion */
137 #define VAR_FROM_ENV 2 /* Variable comes from the environment */
138 #define VAR_JUNK 4 /* Variable is a junk variable that
139 * should be destroyed when done with
140 * it. Used by Var_Parse for undefined,
141 * modified variables */
142 #define VAR_TO_ENV 8 /* Place variable in environment */
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(ClientData, ClientData);
170 static Var *VarFind(char *, GNode *, int);
171 static void VarAdd(char *, char *, GNode *);
172 static void VarDelete(ClientData);
173 static Boolean VarHead(char *, Boolean, Buffer, ClientData);
174 static Boolean VarTail(char *, Boolean, Buffer, ClientData);
175 static Boolean VarSuffix(char *, Boolean, Buffer, ClientData);
176 static Boolean VarRoot(char *, Boolean, Buffer, ClientData);
177 static Boolean VarMatch(char *, Boolean, Buffer, ClientData);
179 static Boolean VarSYSVMatch(char *, Boolean, Buffer, ClientData);
181 static Boolean VarNoMatch(char *, Boolean, Buffer, ClientData);
182 static void VarREError(int, regex_t *, const char *);
183 static Boolean VarRESubstitute(char *, Boolean, Buffer, ClientData);
184 static Boolean VarSubstitute(char *, Boolean, Buffer, ClientData);
185 static char *VarGetPattern(GNode *, int, char **, int, int *, int *,
187 static char *VarQuote(char *);
188 static char *VarModify(char *, Boolean (*)(char *, Boolean, Buffer,
191 static int VarPrintVar(ClientData, ClientData);
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 *-----------------------------------------------------------------------
208 ClientData v; /* VAR structure to compare */
209 ClientData name; /* name to look for */
211 return (strcmp ((char *) name, ((Var *) v)->name));
215 *-----------------------------------------------------------------------
217 * Find the given variable in the given context and any other contexts
221 * A pointer to the structure describing the desired variable or
222 * NIL if the variable does not exist.
226 *-----------------------------------------------------------------------
229 VarFind (name, ctxt, flags)
230 char *name; /* name to find */
231 GNode *ctxt; /* context in which to find it */
232 int flags; /* FIND_GLOBAL set means to look in the
233 * VAR_GLOBAL context as well.
234 * FIND_CMD set means to look in the VAR_CMD
236 * FIND_ENV set means to look in the
239 Boolean localCheckEnvFirst;
244 * If the variable name begins with a '.', it could very well be one of
245 * the local ones. We check the name against all the local variables
246 * and substitute the short version in for 'name' if it matches one of
249 if (*name == '.' && isupper((unsigned char) name[1]))
252 if (!strcmp(name, ".ALLSRC"))
254 if (!strcmp(name, ".ARCHIVE"))
258 if (!strcmp(name, ".IMPSRC"))
262 if (!strcmp(name, ".MEMBER"))
266 if (!strcmp(name, ".OODATE"))
270 if (!strcmp(name, ".PREFIX"))
274 if (!strcmp(name, ".TARGET"))
280 * Note whether this is one of the specific variables we were told through
281 * the -E flag to use environment-variable-override for.
283 if (Lst_Find (envFirstVars, (ClientData)name,
284 (int (*)(ClientData, ClientData)) strcmp) != NILLNODE)
286 localCheckEnvFirst = TRUE;
288 localCheckEnvFirst = FALSE;
292 * First look for the variable in the given context. If it's not there,
293 * look for it in VAR_CMD, VAR_GLOBAL and the environment, in that order,
294 * depending on the FIND_* flags in 'flags'
296 var = Lst_Find (ctxt->context, (ClientData)name, VarCmp);
298 if ((var == NILLNODE) && (flags & FIND_CMD) && (ctxt != VAR_CMD)) {
299 var = Lst_Find (VAR_CMD->context, (ClientData)name, VarCmp);
301 if ((var == NILLNODE) && (flags & FIND_GLOBAL) && (ctxt != VAR_GLOBAL) &&
302 !checkEnvFirst && !localCheckEnvFirst)
304 var = Lst_Find (VAR_GLOBAL->context, (ClientData)name, VarCmp);
306 if ((var == NILLNODE) && (flags & FIND_ENV)) {
309 if ((env = getenv (name)) != NULL) {
312 v = (Var *) emalloc(sizeof(Var));
313 v->name = estrdup(name);
317 v->val = Buf_Init(len);
318 Buf_AddBytes(v->val, len, (Byte *)env);
320 v->flags = VAR_FROM_ENV;
322 } else if ((checkEnvFirst || localCheckEnvFirst) &&
323 (flags & FIND_GLOBAL) && (ctxt != VAR_GLOBAL))
325 var = Lst_Find (VAR_GLOBAL->context, (ClientData)name, VarCmp);
326 if (var == NILLNODE) {
327 return ((Var *) NIL);
329 return ((Var *)Lst_Datum(var));
334 } else if (var == NILLNODE) {
335 return ((Var *) NIL);
337 return ((Var *) Lst_Datum (var));
342 *-----------------------------------------------------------------------
344 * Add a new variable of name name and value val to the given context
350 * The new variable is placed at the front of the given context
351 * The name and val arguments are duplicated so they may
353 *-----------------------------------------------------------------------
356 VarAdd (name, val, ctxt)
357 char *name; /* name of variable to add */
358 char *val; /* value to set it to */
359 GNode *ctxt; /* context in which to set it */
364 v = (Var *) emalloc (sizeof (Var));
366 v->name = estrdup (name);
368 len = val ? strlen(val) : 0;
369 v->val = Buf_Init(len+1);
370 Buf_AddBytes(v->val, len, (Byte *)val);
374 (void) Lst_AtFront (ctxt->context, (ClientData)v);
375 (void) Lst_AtEnd (allVars, (ClientData) v);
377 printf("%s:%s = %s\n", ctxt->name, name, val);
383 *-----------------------------------------------------------------------
385 * Delete a variable and all the space associated with it.
392 *-----------------------------------------------------------------------
400 Buf_Destroy(v->val, TRUE);
407 *-----------------------------------------------------------------------
409 * Remove a variable from a context.
415 * The Var structure is removed and freed.
417 *-----------------------------------------------------------------------
420 Var_Delete(name, ctxt)
427 printf("%s:delete %s\n", ctxt->name, name);
429 ln = Lst_Find(ctxt->context, (ClientData)name, VarCmp);
430 if (ln != NILLNODE) {
433 v = (Var *)Lst_Datum(ln);
434 Lst_Remove(ctxt->context, ln);
435 ln = Lst_Member(allVars, v);
436 Lst_Remove(allVars, ln);
437 VarDelete((ClientData) v);
442 *-----------------------------------------------------------------------
444 * Set the variable name to the value val in the given context.
450 * If the variable doesn't yet exist, a new record is created for it.
451 * Else the old value is freed and the new one stuck in its place
454 * The variable is searched for only in its context before being
455 * created in that context. I.e. if the context is VAR_GLOBAL,
456 * only VAR_GLOBAL->context is searched. Likewise if it is VAR_CMD, only
457 * VAR_CMD->context is searched. This is done to avoid the literally
458 * thousands of unnecessary strcmp's that used to be done to
459 * set, say, $(@) or $(<).
460 *-----------------------------------------------------------------------
463 Var_Set (name, val, ctxt)
464 char *name; /* name of variable to set */
465 char *val; /* value to give to the variable */
466 GNode *ctxt; /* context in which to set it */
471 * We only look for a variable in the given context since anything set
472 * here will override anything in a lower context, so there's not much
473 * point in searching them all just to save a bit of memory...
475 v = VarFind (name, ctxt, 0);
476 if (v == (Var *) NIL) {
477 VarAdd (name, val, ctxt);
479 Buf_Discard(v->val, Buf_Size(v->val));
480 Buf_AddBytes(v->val, strlen(val), (Byte *)val);
483 printf("%s:%s = %s\n", ctxt->name, name, val);
487 * Any variables given on the command line are automatically exported
488 * to the environment (as per POSIX standard)
490 if (ctxt == VAR_CMD || (v != (Var *)NIL && (v->flags & VAR_TO_ENV))) {
491 setenv(name, val, 1);
497 * Set the VAR_TO_ENV flag on a variable
500 Var_SetEnv (char *name, GNode *ctxt)
504 v = VarFind(name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV);
506 if ((v->flags & VAR_TO_ENV) == 0) {
507 v->flags |= VAR_TO_ENV;
508 setenv(v->name, Buf_GetAll(v->val, NULL), 1);
511 Error("Cannot set environment flag on non-existant variable %s", name);
516 *-----------------------------------------------------------------------
518 * The variable of the given name has the given value appended to it in
525 * If the variable doesn't exist, it is created. Else the strings
526 * are concatenated (with a space in between).
529 * Only if the variable is being sought in the global context is the
530 * environment searched.
531 * XXX: Knows its calling circumstances in that if called with ctxt
532 * an actual target, it will only search that context since only
533 * a local variable could be being appended to. This is actually
534 * a big win and must be tolerated.
535 *-----------------------------------------------------------------------
538 Var_Append (name, val, ctxt)
539 char *name; /* Name of variable to modify */
540 char *val; /* String to append to it */
541 GNode *ctxt; /* Context in which this should occur */
545 v = VarFind (name, ctxt, (ctxt == VAR_GLOBAL) ? FIND_ENV : 0);
547 if (v == (Var *) NIL) {
548 VarAdd (name, val, ctxt);
550 Buf_AddByte(v->val, (Byte)' ');
551 Buf_AddBytes(v->val, strlen(val), (Byte *)val);
554 printf("%s:%s = %s\n", ctxt->name, name,
555 (char *) Buf_GetAll(v->val, (int *)NULL));
558 if (v->flags & VAR_FROM_ENV) {
560 * If the original variable came from the environment, we
561 * have to install it in the global context (we could place
562 * it in the environment, but then we should provide a way to
563 * export other variables...)
565 v->flags &= ~VAR_FROM_ENV;
566 Lst_AtFront(ctxt->context, (ClientData)v);
572 *-----------------------------------------------------------------------
574 * See if the given variable exists.
577 * TRUE if it does, FALSE if it doesn't
582 *-----------------------------------------------------------------------
585 Var_Exists(name, ctxt)
586 char *name; /* Variable to find */
587 GNode *ctxt; /* Context in which to start search */
591 v = VarFind(name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV);
593 if (v == (Var *)NIL) {
595 } else if (v->flags & VAR_FROM_ENV) {
597 Buf_Destroy(v->val, TRUE);
604 *-----------------------------------------------------------------------
606 * Return the value of the named variable in the given context
609 * The value if the variable exists, NULL if it doesn't
613 *-----------------------------------------------------------------------
616 Var_Value (name, ctxt, frp)
617 char *name; /* name to find */
618 GNode *ctxt; /* context in which to search for it */
623 v = VarFind (name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
625 if (v != (Var *) NIL) {
626 char *p = ((char *)Buf_GetAll(v->val, (int *)NULL));
627 if (v->flags & VAR_FROM_ENV) {
628 Buf_Destroy(v->val, FALSE);
634 return ((char *) NULL);
639 *-----------------------------------------------------------------------
641 * Remove the tail of the given word and place the result in the given
645 * TRUE if characters were added to the buffer (a space needs to be
646 * added to the buffer before the next word).
649 * The trimmed word is added to the buffer.
651 *-----------------------------------------------------------------------
654 VarHead (word, addSpace, buf, dummy)
655 char *word; /* Word to trim */
656 Boolean addSpace; /* True if need to add a space to the buffer
657 * before sticking in the head */
658 Buffer buf; /* Buffer in which to store it */
661 register char *slash;
663 slash = strrchr (word, '/');
664 if (slash != (char *)NULL) {
666 Buf_AddByte (buf, (Byte)' ');
669 Buf_AddBytes (buf, strlen (word), (Byte *)word);
674 * If no directory part, give . (q.v. the POSIX standard)
677 Buf_AddBytes(buf, 2, (Byte *)" .");
679 Buf_AddByte(buf, (Byte)'.');
682 return(dummy ? TRUE : TRUE);
686 *-----------------------------------------------------------------------
688 * Remove the head of the given word and place the result in the given
692 * TRUE if characters were added to the buffer (a space needs to be
693 * added to the buffer before the next word).
696 * The trimmed word is added to the buffer.
698 *-----------------------------------------------------------------------
701 VarTail (word, addSpace, buf, dummy)
702 char *word; /* Word to trim */
703 Boolean addSpace; /* TRUE if need to stick a space in the
704 * buffer before adding the tail */
705 Buffer buf; /* Buffer in which to store it */
708 register char *slash;
711 Buf_AddByte (buf, (Byte)' ');
714 slash = strrchr (word, '/');
715 if (slash != (char *)NULL) {
717 Buf_AddBytes (buf, strlen(slash), (Byte *)slash);
720 Buf_AddBytes (buf, strlen(word), (Byte *)word);
722 return (dummy ? TRUE : TRUE);
726 *-----------------------------------------------------------------------
728 * Place the suffix of the given word in the given buffer.
731 * TRUE if characters were added to the buffer (a space needs to be
732 * added to the buffer before the next word).
735 * The suffix from the word is placed in the buffer.
737 *-----------------------------------------------------------------------
740 VarSuffix (word, addSpace, buf, dummy)
741 char *word; /* Word to trim */
742 Boolean addSpace; /* TRUE if need to add a space before placing
743 * the suffix in the buffer */
744 Buffer buf; /* Buffer in which to store it */
749 dot = strrchr (word, '.');
750 if (dot != (char *)NULL) {
752 Buf_AddByte (buf, (Byte)' ');
755 Buf_AddBytes (buf, strlen (dot), (Byte *)dot);
759 return (dummy ? addSpace : addSpace);
763 *-----------------------------------------------------------------------
765 * Remove the suffix of the given word and place the result in the
769 * TRUE if characters were added to the buffer (a space needs to be
770 * added to the buffer before the next word).
773 * The trimmed word is added to the buffer.
775 *-----------------------------------------------------------------------
778 VarRoot (word, addSpace, buf, dummy)
779 char *word; /* Word to trim */
780 Boolean addSpace; /* TRUE if need to add a space to the buffer
781 * before placing the root in it */
782 Buffer buf; /* Buffer in which to store it */
788 Buf_AddByte (buf, (Byte)' ');
791 dot = strrchr (word, '.');
792 if (dot != (char *)NULL) {
794 Buf_AddBytes (buf, strlen (word), (Byte *)word);
797 Buf_AddBytes (buf, strlen(word), (Byte *)word);
799 return (dummy ? TRUE : TRUE);
803 *-----------------------------------------------------------------------
805 * Place the word in the buffer if it matches the given pattern.
806 * Callback function for VarModify to implement the :M modifier.
809 * TRUE if a space should be placed in the buffer before the next
813 * The word may be copied to the buffer.
815 *-----------------------------------------------------------------------
818 VarMatch (word, addSpace, buf, pattern)
819 char *word; /* Word to examine */
820 Boolean addSpace; /* TRUE if need to add a space to the
821 * buffer before adding the word, if it
823 Buffer buf; /* Buffer in which to store it */
824 ClientData pattern; /* Pattern the word must match */
826 if (Str_Match(word, (char *) pattern)) {
828 Buf_AddByte(buf, (Byte)' ');
831 Buf_AddBytes(buf, strlen(word), (Byte *)word);
838 *-----------------------------------------------------------------------
840 * Place the word in the buffer if it matches the given pattern.
841 * Callback function for VarModify to implement the System V %
845 * TRUE if a space should be placed in the buffer before the next
849 * The word may be copied to the buffer.
851 *-----------------------------------------------------------------------
854 VarSYSVMatch (word, addSpace, buf, patp)
855 char *word; /* Word to examine */
856 Boolean addSpace; /* TRUE if need to add a space to the
857 * buffer before adding the word, if it
859 Buffer buf; /* Buffer in which to store it */
860 ClientData patp; /* Pattern the word must match */
864 VarPattern *pat = (VarPattern *) patp;
867 Buf_AddByte(buf, (Byte)' ');
871 if ((ptr = Str_SYSVMatch(word, pat->lhs, &len)) != NULL)
872 Str_SYSVSubst(buf, pat->rhs, ptr, len);
874 Buf_AddBytes(buf, strlen(word), (Byte *) word);
882 *-----------------------------------------------------------------------
884 * Place the word in the buffer if it doesn't match the given pattern.
885 * Callback function for VarModify to implement the :N modifier.
888 * TRUE if a space should be placed in the buffer before the next
892 * The word may be copied to the buffer.
894 *-----------------------------------------------------------------------
897 VarNoMatch (word, addSpace, buf, pattern)
898 char *word; /* Word to examine */
899 Boolean addSpace; /* TRUE if need to add a space to the
900 * buffer before adding the word, if it
902 Buffer buf; /* Buffer in which to store it */
903 ClientData pattern; /* Pattern the word must match */
905 if (!Str_Match(word, (char *) pattern)) {
907 Buf_AddByte(buf, (Byte)' ');
910 Buf_AddBytes(buf, strlen(word), (Byte *)word);
917 *-----------------------------------------------------------------------
919 * Perform a string-substitution on the given word, placing the
920 * result in the passed buffer.
923 * TRUE if a space is needed before more characters are added.
928 *-----------------------------------------------------------------------
931 VarSubstitute (word, addSpace, buf, patternp)
932 char *word; /* Word to modify */
933 Boolean addSpace; /* True if space should be added before
934 * other characters */
935 Buffer buf; /* Buffer for result */
936 ClientData patternp; /* Pattern for substitution */
938 register int wordLen; /* Length of word */
939 register char *cp; /* General pointer */
940 VarPattern *pattern = (VarPattern *) patternp;
942 wordLen = strlen(word);
943 if (1) { /* substitute in each word of the variable */
945 * Break substitution down into simple anchored cases
946 * and if none of them fits, perform the general substitution case.
948 if ((pattern->flags & VAR_MATCH_START) &&
949 (strncmp(word, pattern->lhs, pattern->leftLen) == 0)) {
951 * Anchored at start and beginning of word matches pattern
953 if ((pattern->flags & VAR_MATCH_END) &&
954 (wordLen == pattern->leftLen)) {
956 * Also anchored at end and matches to the end (word
957 * is same length as pattern) add space and rhs only
958 * if rhs is non-null.
960 if (pattern->rightLen != 0) {
962 Buf_AddByte(buf, (Byte)' ');
965 Buf_AddBytes(buf, pattern->rightLen,
966 (Byte *)pattern->rhs);
968 } else if (pattern->flags & VAR_MATCH_END) {
970 * Doesn't match to end -- copy word wholesale
975 * Matches at start but need to copy in trailing characters
977 if ((pattern->rightLen + wordLen - pattern->leftLen) != 0){
979 Buf_AddByte(buf, (Byte)' ');
983 Buf_AddBytes(buf, pattern->rightLen, (Byte *)pattern->rhs);
984 Buf_AddBytes(buf, wordLen - pattern->leftLen,
985 (Byte *)(word + pattern->leftLen));
987 } else if (pattern->flags & VAR_MATCH_START) {
989 * Had to match at start of word and didn't -- copy whole word.
992 } else if (pattern->flags & VAR_MATCH_END) {
994 * Anchored at end, Find only place match could occur (leftLen
995 * characters from the end of the word) and see if it does. Note
996 * that because the $ will be left at the end of the lhs, we have
999 cp = word + (wordLen - pattern->leftLen);
1001 (strncmp(cp, pattern->lhs, pattern->leftLen) == 0)) {
1003 * Match found. If we will place characters in the buffer,
1004 * add a space before hand as indicated by addSpace, then
1005 * stuff in the initial, unmatched part of the word followed
1006 * by the right-hand-side.
1008 if (((cp - word) + pattern->rightLen) != 0) {
1010 Buf_AddByte(buf, (Byte)' ');
1014 Buf_AddBytes(buf, cp - word, (Byte *)word);
1015 Buf_AddBytes(buf, pattern->rightLen, (Byte *)pattern->rhs);
1018 * Had to match at end and didn't. Copy entire word.
1024 * Pattern is unanchored: search for the pattern in the word using
1025 * String_FindSubstring, copying unmatched portions and the
1026 * right-hand-side for each match found, handling non-global
1027 * substitutions correctly, etc. When the loop is done, any
1028 * remaining part of the word (word and wordLen are adjusted
1029 * accordingly through the loop) is copied straight into the
1031 * addSpace is set FALSE as soon as a space is added to the
1034 register Boolean done;
1038 origSize = Buf_Size(buf);
1040 cp = Str_FindSubstring(word, pattern->lhs);
1041 if (cp != (char *)NULL) {
1042 if (addSpace && (((cp - word) + pattern->rightLen) != 0)){
1043 Buf_AddByte(buf, (Byte)' ');
1046 Buf_AddBytes(buf, cp-word, (Byte *)word);
1047 Buf_AddBytes(buf, pattern->rightLen, (Byte *)pattern->rhs);
1048 wordLen -= (cp - word) + pattern->leftLen;
1049 word = cp + pattern->leftLen;
1050 if (wordLen == 0 || (pattern->flags & VAR_SUB_GLOBAL) == 0){
1059 Buf_AddByte(buf, (Byte)' ');
1061 Buf_AddBytes(buf, wordLen, (Byte *)word);
1064 * If added characters to the buffer, need to add a space
1065 * before we add any more. If we didn't add any, just return
1066 * the previous value of addSpace.
1068 return ((Buf_Size(buf) != origSize) || addSpace);
1071 * Common code for anchored substitutions:
1072 * addSpace was set TRUE if characters were added to the buffer.
1078 Buf_AddByte(buf, (Byte)' ');
1080 Buf_AddBytes(buf, wordLen, (Byte *)word);
1085 *-----------------------------------------------------------------------
1087 * Print the error caused by a regcomp or regexec call.
1093 * An error gets printed.
1095 *-----------------------------------------------------------------------
1098 VarREError(err, pat, str)
1106 errlen = regerror(err, pat, 0, 0);
1107 errbuf = emalloc(errlen);
1108 regerror(err, pat, errbuf, errlen);
1109 Error("%s: %s", str, errbuf);
1115 *-----------------------------------------------------------------------
1116 * VarRESubstitute --
1117 * Perform a regex substitution on the given word, placing the
1118 * result in the passed buffer.
1121 * TRUE if a space is needed before more characters are added.
1126 *-----------------------------------------------------------------------
1129 VarRESubstitute(word, addSpace, buf, patternp)
1133 ClientData patternp;
1142 #define MAYBE_ADD_SPACE() \
1143 if (addSpace && !added) \
1144 Buf_AddByte(buf, ' '); \
1151 if ((pat->flags & (VAR_SUB_ONE|VAR_SUB_MATCHED)) ==
1152 (VAR_SUB_ONE|VAR_SUB_MATCHED))
1156 xrv = regexec(&pat->re, wp, pat->nsub, pat->matches, flags);
1161 pat->flags |= VAR_SUB_MATCHED;
1162 if (pat->matches[0].rm_so > 0) {
1164 Buf_AddBytes(buf, pat->matches[0].rm_so, wp);
1167 for (rp = pat->replace; *rp; rp++) {
1168 if ((*rp == '\\') && ((rp[1] == '&') || (rp[1] == '\\'))) {
1170 Buf_AddByte(buf,rp[1]);
1173 else if ((*rp == '&') ||
1174 ((*rp == '\\') && isdigit((unsigned char)rp[1]))) {
1192 if (n > pat->nsub) {
1193 Error("No subexpression %s", &errstr[0]);
1196 } else if ((pat->matches[n].rm_so == -1) &&
1197 (pat->matches[n].rm_eo == -1)) {
1198 Error("No match for subexpression %s", &errstr[0]);
1202 subbuf = wp + pat->matches[n].rm_so;
1203 sublen = pat->matches[n].rm_eo - pat->matches[n].rm_so;
1208 Buf_AddBytes(buf, sublen, subbuf);
1212 Buf_AddByte(buf, *rp);
1215 wp += pat->matches[0].rm_eo;
1216 if (pat->flags & VAR_SUB_GLOBAL) {
1217 flags |= REG_NOTBOL;
1218 if (pat->matches[0].rm_so == 0 && pat->matches[0].rm_eo == 0) {
1220 Buf_AddByte(buf, *wp);
1229 Buf_AddBytes(buf, strlen(wp), wp);
1233 VarREError(xrv, &pat->re, "Unexpected regex error");
1238 Buf_AddBytes(buf,strlen(wp),wp);
1242 return(addSpace||added);
1247 *-----------------------------------------------------------------------
1249 * Modify each of the words of the passed string using the given
1250 * function. Used to implement all modifiers.
1253 * A string of all the words modified appropriately.
1258 *-----------------------------------------------------------------------
1261 VarModify (str, modProc, datum)
1262 char *str; /* String whose words should be trimmed */
1263 /* Function to use to modify them */
1264 Boolean (*modProc)(char *, Boolean, Buffer, ClientData);
1265 ClientData datum; /* Datum to pass it */
1267 Buffer buf; /* Buffer for the new string */
1268 Boolean addSpace; /* TRUE if need to add a space to the
1269 * buffer before adding the trimmed
1271 char **av; /* word list [first word does not count] */
1277 av = brk_string(str, &ac, FALSE);
1279 for (i = 1; i < ac; i++)
1280 addSpace = (*modProc)(av[i], addSpace, buf, datum);
1282 Buf_AddByte (buf, '\0');
1283 str = (char *)Buf_GetAll (buf, (int *)NULL);
1284 Buf_Destroy (buf, FALSE);
1289 *-----------------------------------------------------------------------
1291 * Pass through the tstr looking for 1) escaped delimiters,
1292 * '$'s and backslashes (place the escaped character in
1293 * uninterpreted) and 2) unescaped $'s that aren't before
1294 * the delimiter (expand the variable substitution unless flags
1295 * has VAR_NOSUBST set).
1296 * Return the expanded string or NULL if the delimiter was missing
1297 * If pattern is specified, handle escaped ampersands, and replace
1298 * unescaped ampersands with the lhs of the pattern.
1301 * A string of all the words modified appropriately.
1302 * If length is specified, return the string length of the buffer
1303 * If flags is specified and the last character of the pattern is a
1304 * $ set the VAR_MATCH_END bit of flags.
1308 *-----------------------------------------------------------------------
1311 VarGetPattern(ctxt, err, tstr, delim, flags, length, pattern)
1318 VarPattern *pattern;
1321 Buffer buf = Buf_Init(0);
1326 #define IS_A_MATCH(cp, delim) \
1327 ((cp[0] == '\\') && ((cp[1] == delim) || \
1328 (cp[1] == '\\') || (cp[1] == '$') || (pattern && (cp[1] == '&'))))
1331 * Skim through until the matching delimiter is found;
1332 * pick up variable substitutions on the way. Also allow
1333 * backslashes to quote the delimiter, $, and \, but don't
1334 * touch other backslashes.
1336 for (cp = *tstr; *cp && (*cp != delim); cp++) {
1337 if (IS_A_MATCH(cp, delim)) {
1338 Buf_AddByte(buf, (Byte) cp[1]);
1340 } else if (*cp == '$') {
1341 if (cp[1] == delim) {
1343 Buf_AddByte(buf, (Byte) *cp);
1346 * Unescaped $ at end of pattern => anchor
1349 *flags |= VAR_MATCH_END;
1351 if (flags == NULL || (*flags & VAR_NOSUBST) == 0) {
1357 * If unescaped dollar sign not before the
1358 * delimiter, assume it's a variable
1359 * substitution and recurse.
1361 cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
1362 Buf_AddBytes(buf, strlen(cp2), (Byte *) cp2);
1369 if (*cp2 == '(' || *cp2 == '{') {
1371 * Find the end of this variable reference
1372 * and suck it in without further ado.
1373 * It will be interperated later.
1376 int want = (*cp2 == '(') ? ')' : '}';
1379 for (++cp2; *cp2 != '\0' && depth > 0; ++cp2) {
1380 if (cp2[-1] != '\\') {
1387 Buf_AddBytes(buf, cp2 - cp, (Byte *)cp);
1390 Buf_AddByte(buf, (Byte) *cp);
1394 else if (pattern && *cp == '&')
1395 Buf_AddBytes(buf, pattern->leftLen, (Byte *)pattern->lhs);
1397 Buf_AddByte(buf, (Byte) *cp);
1400 Buf_AddByte(buf, (Byte) '\0');
1409 cp = (char *) Buf_GetAll(buf, length);
1410 *length -= 1; /* Don't count the NULL */
1411 Buf_Destroy(buf, FALSE);
1418 *-----------------------------------------------------------------------
1420 * Quote shell meta-characters in the string
1428 *-----------------------------------------------------------------------
1436 /* This should cover most shells :-( */
1437 static char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~";
1439 buf = Buf_Init (MAKE_BSIZE);
1440 for (; *str; str++) {
1441 if (strchr(meta, *str) != NULL)
1442 Buf_AddByte(buf, (Byte)'\\');
1443 Buf_AddByte(buf, (Byte)*str);
1445 Buf_AddByte(buf, (Byte) '\0');
1446 str = (char *)Buf_GetAll (buf, (int *)NULL);
1447 Buf_Destroy (buf, FALSE);
1452 *-----------------------------------------------------------------------
1454 * Given the start of a variable invocation, extract the variable
1455 * name and find its value, then modify it according to the
1459 * The (possibly-modified) value of the variable or var_Error if the
1460 * specification is invalid. The length of the specification is
1461 * placed in *lengthPtr (for invalid specifications, this is just
1463 * A Boolean in *freePtr telling whether the returned string should
1464 * be freed by the caller.
1469 *-----------------------------------------------------------------------
1472 Var_Parse (str, ctxt, err, lengthPtr, freePtr)
1473 char *str; /* The string to parse */
1474 GNode *ctxt; /* The context for the variable */
1475 Boolean err; /* TRUE if undefined variables are an error */
1476 int *lengthPtr; /* OUT: The length of the specification */
1477 Boolean *freePtr; /* OUT: TRUE if caller should free result */
1479 register char *tstr; /* Pointer into str */
1480 Var *v; /* Variable in invocation */
1481 char *cp; /* Secondary pointer into str (place marker
1483 Boolean haveModifier;/* TRUE if have modifiers for the variable */
1484 register char endc; /* Ending character when variable in parens
1486 register char startc=0; /* Starting character when variable in parens
1488 int cnt; /* Used to count brace pairs when variable in
1489 * in parens or braces */
1492 Boolean dynamic; /* TRUE if the variable is local and we're
1493 * expanding it in a non-local context. This
1494 * is done to support dynamic sources. The
1495 * result is just the invocation, unaltered */
1496 int vlen; /* length of variable name, after embedded variable
1503 if (str[1] != '(' && str[1] != '{') {
1505 * If it's not bounded by braces of some sort, life is much simpler.
1506 * We just need to check for the first character and return the
1507 * value if it exists.
1514 v = VarFind (name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
1515 if (v == (Var *)NIL) {
1518 if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
1520 * If substituting a local variable in a non-local context,
1521 * assume it's for dynamic source stuff. We have to handle
1522 * this specially and return the longhand for the variable
1523 * with the dollar sign escaped so it makes it back to the
1524 * caller. Only four of the local variables are treated
1525 * specially as they are the only four that will be set
1526 * when dynamic sources are expanded.
1528 /* XXX: It looks like $% and $! are reversed here */
1531 return("$(.TARGET)");
1533 return("$(.ARCHIVE)");
1535 return("$(.PREFIX)");
1537 return("$(.MEMBER)");
1543 return (err ? var_Error : varNoError);
1545 haveModifier = FALSE;
1550 /* build up expanded variable name in this buffer */
1551 Buffer buf = Buf_Init(MAKE_BSIZE);
1554 endc = startc == '(' ? ')' : '}';
1557 * Skip to the end character or a colon, whichever comes first,
1558 * replacing embedded variables as we go.
1560 for (tstr = str + 2; *tstr != '\0' && *tstr != endc && *tstr != ':'; tstr++)
1564 char* rval = Var_Parse(tstr, ctxt, err, &rlen, &rfree);
1566 if (rval == var_Error) {
1567 Fatal("Error expanding embedded variable.");
1568 } else if (rval != NULL) {
1569 Buf_AddBytes(buf, strlen(rval), (Byte *) rval);
1575 Buf_AddByte(buf, (Byte) *tstr);
1577 if (*tstr == '\0') {
1579 * If we never did find the end character, return NULL
1580 * right now, setting the length to be the distance to
1581 * the end of the string, since that's what make does.
1583 *lengthPtr = tstr - str;
1587 haveModifier = (*tstr == ':');
1590 Buf_AddByte(buf, (Byte) '\0');
1591 str = Buf_GetAll(buf, NULL);
1594 v = VarFind (str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
1595 if ((v == (Var *)NIL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
1596 (vlen == 2) && (str[1] == 'F' || str[1] == 'D'))
1599 * Check for bogus D and F forms of local variables since we're
1600 * in a local context and the name is the right length.
1614 * Well, it's local -- go look for it.
1618 v = VarFind(vname, ctxt, 0);
1620 if (v != (Var *)NIL && !haveModifier) {
1622 * No need for nested expansion or anything, as we're
1623 * the only one who sets these things and we sure don't
1624 * put nested invocations in them...
1626 val = (char *)Buf_GetAll(v->val, (int *)NULL);
1628 if (str[1] == 'D') {
1629 val = VarModify(val, VarHead, (ClientData)0);
1631 val = VarModify(val, VarTail, (ClientData)0);
1634 * Resulting string is dynamically allocated, so
1635 * tell caller to free it.
1638 *lengthPtr = tstr-start+1;
1640 Buf_Destroy(buf, TRUE);
1648 if (v == (Var *)NIL) {
1650 (((vlen == 2) && (str[1] == 'F' ||
1651 str[1] == 'D')))) &&
1652 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
1655 * If substituting a local variable in a non-local context,
1656 * assume it's for dynamic source stuff. We have to handle
1657 * this specially and return the longhand for the variable
1658 * with the dollar sign escaped so it makes it back to the
1659 * caller. Only four of the local variables are treated
1660 * specially as they are the only four that will be set
1661 * when dynamic sources are expanded.
1671 } else if ((vlen > 2) && (str[0] == '.') &&
1672 isupper((unsigned char) str[1]) &&
1673 ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
1678 if ((strncmp(str, ".TARGET", len) == 0) ||
1679 (strncmp(str, ".ARCHIVE", len) == 0) ||
1680 (strncmp(str, ".PREFIX", len) == 0) ||
1681 (strncmp(str, ".MEMBER", len) == 0))
1687 if (!haveModifier) {
1689 * No modifiers -- have specification length so we can return
1692 *lengthPtr = tstr - start + 1;
1695 str = emalloc(*lengthPtr + 1);
1696 strncpy(str, start, *lengthPtr);
1697 str[*lengthPtr] = '\0';
1699 Buf_Destroy(buf, TRUE);
1702 Buf_Destroy(buf, TRUE);
1703 return (err ? var_Error : varNoError);
1707 * Still need to get to the end of the variable specification,
1708 * so kludge up a Var structure for the modifications
1710 v = (Var *) emalloc(sizeof(Var));
1712 v->val = Buf_Init(1);
1713 v->flags = VAR_JUNK;
1716 Buf_Destroy(buf, TRUE);
1719 if (v->flags & VAR_IN_USE) {
1720 Fatal("Variable %s is recursive.", v->name);
1723 v->flags |= VAR_IN_USE;
1726 * Before doing any modification, we have to make sure the value
1727 * has been fully expanded. If it looks like recursion might be
1728 * necessary (there's a dollar sign somewhere in the variable's value)
1729 * we just call Var_Subst to do any other substitutions that are
1730 * necessary. Note that the value returned by Var_Subst will have
1731 * been dynamically-allocated, so it will need freeing when we
1734 str = (char *)Buf_GetAll(v->val, (int *)NULL);
1735 if (strchr (str, '$') != (char *)NULL) {
1736 str = Var_Subst(NULL, str, ctxt, err);
1740 v->flags &= ~VAR_IN_USE;
1743 * Now we need to apply any modifiers the user wants applied.
1745 * :M<pattern> words which match the given <pattern>.
1746 * <pattern> is of the standard file
1748 * :S<d><pat1><d><pat2><d>[g]
1749 * Substitute <pat2> for <pat1> in the value
1750 * :C<d><pat1><d><pat2><d>[g]
1751 * Substitute <pat2> for regex <pat1> in the value
1752 * :H Substitute the head of each word
1753 * :T Substitute the tail of each word
1754 * :E Substitute the extension (minus '.') of
1756 * :R Substitute the root of each word
1757 * (pathname minus the suffix).
1758 * :lhs=rhs Like :S, but the rhs goes to the end of
1760 * :U Converts variable to upper-case.
1761 * :L Converts variable to lower-case.
1763 if ((str != (char *)NULL) && haveModifier) {
1765 * Skip initial colon while putting it back.
1768 while (*tstr != endc) {
1769 char *newStr; /* New value to return */
1770 char termc; /* Character which terminated scan */
1773 printf("Applying :%c to \"%s\"\n", *tstr, str);
1777 if (tstr[1] == endc || tstr[1] == ':') {
1779 buf = Buf_Init(MAKE_BSIZE);
1780 for (cp = str; *cp ; cp++)
1781 Buf_AddByte(buf, (Byte) toupper(*cp));
1783 Buf_AddByte(buf, (Byte) '\0');
1784 newStr = (char *) Buf_GetAll(buf, (int *) NULL);
1785 Buf_Destroy(buf, FALSE);
1793 if (tstr[1] == endc || tstr[1] == ':') {
1795 buf = Buf_Init(MAKE_BSIZE);
1796 for (cp = str; *cp ; cp++)
1797 Buf_AddByte(buf, (Byte) tolower(*cp));
1799 Buf_AddByte(buf, (Byte) '\0');
1800 newStr = (char *) Buf_GetAll(buf, (int *) NULL);
1801 Buf_Destroy(buf, FALSE);
1817 *cp != '\0' && *cp != ':' && *cp != endc;
1820 if (*cp == '\\' && (cp[1] == ':' || cp[1] == endc)){
1829 * Need to compress the \:'s out of the pattern, so
1830 * allocate enough room to hold the uncompressed
1831 * pattern (note that cp started at tstr+1, so
1832 * cp - tstr takes the null byte into account) and
1833 * compress the pattern into the space.
1835 pattern = emalloc(cp - tstr);
1836 for (cp2 = pattern, cp = tstr + 1;
1840 if ((*cp == '\\') &&
1841 (cp[1] == ':' || cp[1] == endc)) {
1850 if (*tstr == 'M' || *tstr == 'm') {
1851 newStr = VarModify(str, VarMatch, (ClientData)pattern);
1853 newStr = VarModify(str, VarNoMatch,
1854 (ClientData)pattern);
1864 register char delim;
1865 Buffer buf; /* Buffer for patterns */
1872 * If pattern begins with '^', it is anchored to the
1873 * start of the word -- skip over it and flag pattern.
1876 pattern.flags |= VAR_MATCH_START;
1883 * Pass through the lhs looking for 1) escaped delimiters,
1884 * '$'s and backslashes (place the escaped character in
1885 * uninterpreted) and 2) unescaped $'s that aren't before
1886 * the delimiter (expand the variable substitution).
1887 * The result is left in the Buffer buf.
1889 for (cp = tstr; *cp != '\0' && *cp != delim; cp++) {
1890 if ((*cp == '\\') &&
1891 ((cp[1] == delim) ||
1895 Buf_AddByte(buf, (Byte)cp[1]);
1897 } else if (*cp == '$') {
1898 if (cp[1] != delim) {
1900 * If unescaped dollar sign not before the
1901 * delimiter, assume it's a variable
1902 * substitution and recurse.
1908 cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
1909 Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2);
1916 * Unescaped $ at end of pattern => anchor
1919 pattern.flags |= VAR_MATCH_END;
1922 Buf_AddByte(buf, (Byte)*cp);
1926 Buf_AddByte(buf, (Byte)'\0');
1929 * If lhs didn't end with the delimiter, complain and
1933 *lengthPtr = cp - start + 1;
1937 Buf_Destroy(buf, TRUE);
1938 Error("Unclosed substitution for %s (%c missing)",
1944 * Fetch pattern and destroy buffer, but preserve the data
1945 * in it, since that's our lhs. Note that Buf_GetAll
1946 * will return the actual number of bytes, which includes
1947 * the null byte, so we have to decrement the length by
1950 pattern.lhs = (char *)Buf_GetAll(buf, &pattern.leftLen);
1952 Buf_Destroy(buf, FALSE);
1955 * Now comes the replacement string. Three things need to
1956 * be done here: 1) need to compress escaped delimiters and
1957 * ampersands and 2) need to replace unescaped ampersands
1958 * with the l.h.s. (since this isn't regexp, we can do
1959 * it right here) and 3) expand any variable substitutions.
1964 for (cp = tstr; *cp != '\0' && *cp != delim; cp++) {
1965 if ((*cp == '\\') &&
1966 ((cp[1] == delim) ||
1971 Buf_AddByte(buf, (Byte)cp[1]);
1973 } else if ((*cp == '$') && (cp[1] != delim)) {
1978 cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt);
1979 Buf_AddBytes(buf, strlen(cp2), (Byte *)cp2);
1984 } else if (*cp == '&') {
1985 Buf_AddBytes(buf, pattern.leftLen,
1986 (Byte *)pattern.lhs);
1988 Buf_AddByte(buf, (Byte)*cp);
1992 Buf_AddByte(buf, (Byte)'\0');
1995 * If didn't end in delimiter character, complain
1998 *lengthPtr = cp - start + 1;
2002 Buf_Destroy(buf, TRUE);
2003 Error("Unclosed substitution for %s (%c missing)",
2008 pattern.rhs = (char *)Buf_GetAll(buf, &pattern.rightLen);
2010 Buf_Destroy(buf, FALSE);
2013 * Check for global substitution. If 'g' after the final
2014 * delimiter, substitution is global and is marked that
2019 pattern.flags |= VAR_SUB_GLOBAL;
2024 newStr = VarModify(str, VarSubstitute,
2025 (ClientData)&pattern);
2027 * Free the two strings.
2035 VarREPattern pattern;
2045 if ((re = VarGetPattern(ctxt, err, &cp, delim, NULL,
2046 NULL, NULL)) == NULL) {
2047 /* was: goto cleanup */
2048 *lengthPtr = cp - start + 1;
2052 Error("Unclosed substitution for %s (%c missing)",
2057 if ((pattern.replace = VarGetPattern(ctxt, err, &cp,
2058 delim, NULL, NULL, NULL)) == NULL){
2061 /* was: goto cleanup */
2062 *lengthPtr = cp - start + 1;
2066 Error("Unclosed substitution for %s (%c missing)",
2074 pattern.flags |= VAR_SUB_GLOBAL;
2077 pattern.flags |= VAR_SUB_ONE;
2085 error = regcomp(&pattern.re, re, REG_EXTENDED);
2088 *lengthPtr = cp - start + 1;
2089 VarREError(error, &pattern.re, "RE substitution error");
2090 free(pattern.replace);
2094 pattern.nsub = pattern.re.re_nsub + 1;
2095 if (pattern.nsub < 1)
2097 if (pattern.nsub > 10)
2099 pattern.matches = emalloc(pattern.nsub *
2100 sizeof(regmatch_t));
2101 newStr = VarModify(str, VarRESubstitute,
2102 (ClientData) &pattern);
2103 regfree(&pattern.re);
2104 free(pattern.replace);
2105 free(pattern.matches);
2109 if (tstr[1] == endc || tstr[1] == ':') {
2110 newStr = VarQuote (str);
2117 if (tstr[1] == endc || tstr[1] == ':') {
2118 newStr = VarModify (str, VarTail, (ClientData)0);
2125 if (tstr[1] == endc || tstr[1] == ':') {
2126 newStr = VarModify (str, VarHead, (ClientData)0);
2133 if (tstr[1] == endc || tstr[1] == ':') {
2134 newStr = VarModify (str, VarSuffix, (ClientData)0);
2141 if (tstr[1] == endc || tstr[1] == ':') {
2142 newStr = VarModify (str, VarRoot, (ClientData)0);
2150 if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) {
2152 newStr = Cmd_Exec (str, &err);
2165 * This can either be a bogus modifier or a System-V
2166 * substitution command.
2174 * First we make a pass through the string trying
2175 * to verify it is a SYSV-make-style translation:
2176 * it must be: <string1>=<string2>)
2180 while (*cp != '\0' && cnt) {
2183 /* continue looking for endc */
2185 else if (*cp == endc)
2187 else if (*cp == startc)
2192 if (*cp == endc && eqFound) {
2195 * Now we break this sucker into the lhs and
2196 * rhs. We must null terminate them of course.
2198 for (cp = tstr; *cp != '='; cp++)
2201 pattern.leftLen = cp - tstr;
2209 else if (*cp == startc)
2214 pattern.rightLen = cp - pattern.rhs;
2218 * SYSV modifications happen through the whole
2219 * string. Note the pattern is anchored at the end.
2221 newStr = VarModify(str, VarSYSVMatch,
2222 (ClientData)&pattern);
2225 * Restore the nulled characters
2227 pattern.lhs[pattern.leftLen] = '=';
2228 pattern.rhs[pattern.rightLen] = endc;
2233 Error ("Unknown modifier '%c'\n", *tstr);
2235 *cp != ':' && *cp != endc && *cp != '\0';
2244 printf("Result is \"%s\"\n", newStr);
2251 if (str != var_Error) {
2256 if (termc == '\0') {
2257 Error("Unclosed variable specification for %s", v->name);
2258 } else if (termc == ':') {
2265 *lengthPtr = tstr - start + 1;
2267 *lengthPtr = tstr - start + 1;
2271 if (v->flags & VAR_FROM_ENV) {
2272 Boolean destroy = FALSE;
2274 if (str != (char *)Buf_GetAll(v->val, (int *)NULL)) {
2278 * Returning the value unmodified, so tell the caller to free
2283 Buf_Destroy(v->val, destroy);
2285 } else if (v->flags & VAR_JUNK) {
2287 * Perform any free'ing needed and set *freePtr to FALSE so the caller
2288 * doesn't try to free a static pointer.
2294 Buf_Destroy(v->val, TRUE);
2297 str = emalloc(*lengthPtr + 1);
2298 strncpy(str, start, *lengthPtr);
2299 str[*lengthPtr] = '\0';
2302 str = err ? var_Error : varNoError;
2309 *-----------------------------------------------------------------------
2311 * Substitute for all variables in the given string in the given context
2312 * If undefErr is TRUE, Parse_Error will be called when an undefined
2313 * variable is encountered.
2316 * The resulting string.
2319 * None. The old string must be freed by the caller
2320 *-----------------------------------------------------------------------
2323 Var_Subst (var, str, ctxt, undefErr)
2324 char *var; /* Named variable || NULL for all */
2325 char *str; /* the string in which to substitute */
2326 GNode *ctxt; /* the context wherein to find variables */
2327 Boolean undefErr; /* TRUE if undefineds are an error */
2329 Buffer buf; /* Buffer for forming things */
2330 char *val; /* Value to substitute for a variable */
2331 int length; /* Length of the variable invocation */
2332 Boolean doFree; /* Set true if val should be freed */
2333 static Boolean errorReported; /* Set true if an error has already
2334 * been reported to prevent a plethora
2335 * of messages when recursing */
2337 buf = Buf_Init (MAKE_BSIZE);
2338 errorReported = FALSE;
2341 if (var == NULL && (*str == '$') && (str[1] == '$')) {
2343 * A dollar sign may be escaped either with another dollar sign.
2344 * In such a case, we skip over the escape character and store the
2345 * dollar sign into the buffer directly.
2348 Buf_AddByte(buf, (Byte)*str);
2350 } else if (*str != '$') {
2352 * Skip as many characters as possible -- either to the end of
2353 * the string or to the next dollar sign (variable invocation).
2357 for (cp = str++; *str != '$' && *str != '\0'; str++)
2359 Buf_AddBytes(buf, str - cp, (Byte *)cp);
2364 if (str[1] != '(' && str[1] != '{') {
2365 if (str[1] != *var) {
2366 Buf_AddBytes(buf, 2, (Byte *) str);
2378 * Scan up to the end of the variable name.
2380 for (p = &str[2]; *p &&
2381 *p != ':' && *p != ')' && *p != '}'; p++)
2385 * A variable inside the variable. We cannot expand
2386 * the external variable yet, so we try again with
2390 Buf_AddBytes(buf, p - str, (Byte *) str);
2395 if (strncmp(var, str + 2, p - str - 2) != 0 ||
2396 var[p - str - 2] != '\0') {
2398 * Not the variable we want to expand, scan
2399 * until the next variable
2401 for (;*p != '$' && *p != '\0'; p++)
2403 Buf_AddBytes(buf, p - str, (Byte *) str);
2416 val = Var_Parse (str, ctxt, undefErr, &length, &doFree);
2419 * When we come down here, val should either point to the
2420 * value of this variable, suitably modified, or be NULL.
2421 * Length should be the total length of the potential
2422 * variable invocation (from $ to end character...)
2424 if (val == var_Error || val == varNoError) {
2426 * If performing old-time variable substitution, skip over
2427 * the variable and continue with the substitution. Otherwise,
2428 * store the dollar sign and advance str so we continue with
2433 } else if (undefErr) {
2435 * If variable is undefined, complain and skip the
2436 * variable. The complaint will stop us from doing anything
2437 * when the file is parsed.
2439 if (!errorReported) {
2440 Parse_Error (PARSE_FATAL,
2441 "Undefined variable \"%.*s\"",length,str);
2444 errorReported = TRUE;
2446 Buf_AddByte (buf, (Byte)*str);
2451 * We've now got a variable structure to store in. But first,
2452 * advance the string pointer.
2457 * Copy all the characters from the variable value straight
2458 * into the new string.
2460 Buf_AddBytes (buf, strlen (val), (Byte *)val);
2462 free ((Address)val);
2468 Buf_AddByte (buf, '\0');
2469 str = (char *)Buf_GetAll (buf, (int *)NULL);
2470 Buf_Destroy (buf, FALSE);
2475 *-----------------------------------------------------------------------
2477 * Return the tail from each of a list of words. Used to set the
2478 * System V local variables.
2481 * The resulting string.
2486 *-----------------------------------------------------------------------
2490 char *file; /* Filename to modify */
2492 return(VarModify(file, VarTail, (ClientData)0));
2496 *-----------------------------------------------------------------------
2498 * Find the leading components of a (list of) filename(s).
2499 * XXX: VarHead does not replace foo by ., as (sun) System V make
2503 * The leading components.
2508 *-----------------------------------------------------------------------
2512 char *file; /* Filename to manipulate */
2514 return(VarModify(file, VarHead, (ClientData)0));
2518 *-----------------------------------------------------------------------
2520 * Initialize the module
2526 * The VAR_CMD and VAR_GLOBAL contexts are created
2527 *-----------------------------------------------------------------------
2532 VAR_GLOBAL = Targ_NewGN ("Global");
2533 VAR_CMD = Targ_NewGN ("Command");
2534 allVars = Lst_Init(FALSE);
2542 Lst_Destroy(allVars, VarDelete);
2546 /****************** PRINT DEBUGGING INFO *****************/
2548 VarPrintVar (vp, dummy)
2552 Var *v = (Var *) vp;
2553 printf ("%-16s = %s\n", v->name, (char *) Buf_GetAll(v->val, (int *)NULL));
2554 return (dummy ? 0 : 0);
2558 *-----------------------------------------------------------------------
2560 * print all variables in a context
2561 *-----------------------------------------------------------------------
2567 Lst_ForEach (ctxt->context, VarPrintVar, (ClientData) 0);