var.c (282740) | var.c (289842) |
---|---|
1/* $NetBSD: var.c,v 1.192 2015/05/05 21:51:09 sjg Exp $ */ | 1/* $NetBSD: var.c,v 1.199 2015/10/20 21:30:57 sjg Exp $ */ |
2 3/* 4 * Copyright (c) 1988, 1989, 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Adam de Boor. 9 * --- 54 unchanged lines hidden (view full) --- 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 */ 70 71#ifndef MAKE_NATIVE | 2 3/* 4 * Copyright (c) 1988, 1989, 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Adam de Boor. 9 * --- 54 unchanged lines hidden (view full) --- 64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * SUCH DAMAGE. 69 */ 70 71#ifndef MAKE_NATIVE |
72static char rcsid[] = "$NetBSD: var.c,v 1.192 2015/05/05 21:51:09 sjg Exp $"; | 72static char rcsid[] = "$NetBSD: var.c,v 1.199 2015/10/20 21:30:57 sjg Exp $"; |
73#else 74#include <sys/cdefs.h> 75#ifndef lint 76#if 0 77static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; 78#else | 73#else 74#include <sys/cdefs.h> 75#ifndef lint 76#if 0 77static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; 78#else |
79__RCSID("$NetBSD: var.c,v 1.192 2015/05/05 21:51:09 sjg Exp $"); | 79__RCSID("$NetBSD: var.c,v 1.199 2015/10/20 21:30:57 sjg Exp $"); |
80#endif 81#endif /* not lint */ 82#endif 83 84/*- 85 * var.c -- 86 * Variable-handling functions 87 * --- 45 unchanged lines hidden (view full) --- 133#include <stdlib.h> 134#include <limits.h> 135#include <time.h> 136 137#include "make.h" 138#include "buf.h" 139#include "dir.h" 140#include "job.h" | 80#endif 81#endif /* not lint */ 82#endif 83 84/*- 85 * var.c -- 86 * Variable-handling functions 87 * --- 45 unchanged lines hidden (view full) --- 133#include <stdlib.h> 134#include <limits.h> 135#include <time.h> 136 137#include "make.h" 138#include "buf.h" 139#include "dir.h" 140#include "job.h" |
141#include "metachar.h" |
|
141 142extern int makelevel; 143/* 144 * This lets us tell if we have replaced the original environ 145 * (which we cannot free). 146 */ 147char **savedEnv = NULL; 148 --- 387 unchanged lines hidden (view full) --- 536 */ 537void 538Var_Delete(const char *name, GNode *ctxt) 539{ 540 Hash_Entry *ln; 541 char *cp; 542 543 if (strchr(name, '$')) { | 142 143extern int makelevel; 144/* 145 * This lets us tell if we have replaced the original environ 146 * (which we cannot free). 147 */ 148char **savedEnv = NULL; 149 --- 387 unchanged lines hidden (view full) --- 537 */ 538void 539Var_Delete(const char *name, GNode *ctxt) 540{ 541 Hash_Entry *ln; 542 char *cp; 543 544 if (strchr(name, '$')) { |
544 cp = Var_Subst(NULL, name, VAR_GLOBAL, 0); | 545 cp = Var_Subst(NULL, name, VAR_GLOBAL, FALSE, TRUE); |
545 } else { 546 cp = (char *)name; 547 } 548 ln = Hash_FindEntry(&ctxt->context, cp); 549 if (DEBUG(VAR)) { 550 fprintf(debug_file, "%s:delete %s%s\n", 551 ctxt->name, cp, ln ? "" : " (not found)"); 552 } --- 74 unchanged lines hidden (view full) --- 627 /* 628 * We recursed while exporting in a child. 629 * This isn't going to end well, just skip it. 630 */ 631 return 0; 632 } 633 n = snprintf(tmp, sizeof(tmp), "${%s}", name); 634 if (n < (int)sizeof(tmp)) { | 546 } else { 547 cp = (char *)name; 548 } 549 ln = Hash_FindEntry(&ctxt->context, cp); 550 if (DEBUG(VAR)) { 551 fprintf(debug_file, "%s:delete %s%s\n", 552 ctxt->name, cp, ln ? "" : " (not found)"); 553 } --- 74 unchanged lines hidden (view full) --- 628 /* 629 * We recursed while exporting in a child. 630 * This isn't going to end well, just skip it. 631 */ 632 return 0; 633 } 634 n = snprintf(tmp, sizeof(tmp), "${%s}", name); 635 if (n < (int)sizeof(tmp)) { |
635 val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); | 636 val = Var_Subst(NULL, tmp, VAR_GLOBAL, FALSE, TRUE); |
636 setenv(name, val, 1); 637 free(val); 638 } 639 } else { 640 if (parent) { 641 v->flags &= ~VAR_REEXPORT; /* once will do */ 642 } 643 if (parent || !(v->flags & VAR_EXPORTED)) { --- 51 unchanged lines hidden (view full) --- 695 */ 696 n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}"); 697 if (n < (int)sizeof(tmp)) { 698 char **av; 699 char *as; 700 int ac; 701 int i; 702 | 637 setenv(name, val, 1); 638 free(val); 639 } 640 } else { 641 if (parent) { 642 v->flags &= ~VAR_REEXPORT; /* once will do */ 643 } 644 if (parent || !(v->flags & VAR_EXPORTED)) { --- 51 unchanged lines hidden (view full) --- 696 */ 697 n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}"); 698 if (n < (int)sizeof(tmp)) { 699 char **av; 700 char *as; 701 int ac; 702 int i; 703 |
703 val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); | 704 val = Var_Subst(NULL, tmp, VAR_GLOBAL, FALSE, TRUE); |
704 av = brk_string(val, &ac, FALSE, &as); 705 for (i = 0; i < ac; i++) { 706 Var_Export1(av[i], 0); 707 } 708 free(val); 709 free(as); 710 free(av); 711 } --- 21 unchanged lines hidden (view full) --- 733 } 734 735 if (strncmp(str, "-env", 4) == 0) { 736 track = 0; 737 str += 4; 738 } else { 739 track = VAR_EXPORT_PARENT; 740 } | 705 av = brk_string(val, &ac, FALSE, &as); 706 for (i = 0; i < ac; i++) { 707 Var_Export1(av[i], 0); 708 } 709 free(val); 710 free(as); 711 free(av); 712 } --- 21 unchanged lines hidden (view full) --- 734 } 735 736 if (strncmp(str, "-env", 4) == 0) { 737 track = 0; 738 str += 4; 739 } else { 740 track = VAR_EXPORT_PARENT; 741 } |
741 val = Var_Subst(NULL, str, VAR_GLOBAL, 0); | 742 val = Var_Subst(NULL, str, VAR_GLOBAL, FALSE, TRUE); |
742 av = brk_string(val, &ac, FALSE, &as); 743 for (i = 0; i < ac; i++) { 744 name = av[i]; 745 if (!name[1]) { 746 /* 747 * A single char. 748 * If it is one of the vars that should only appear in 749 * local context, skip it, else we can get Var_Subst --- 71 unchanged lines hidden (view full) --- 821 vlist = str; 822 } 823 } 824 825 if (!vlist) { 826 /* Using .MAKE.EXPORTED */ 827 n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}"); 828 if (n < (int)sizeof(tmp)) { | 743 av = brk_string(val, &ac, FALSE, &as); 744 for (i = 0; i < ac; i++) { 745 name = av[i]; 746 if (!name[1]) { 747 /* 748 * A single char. 749 * If it is one of the vars that should only appear in 750 * local context, skip it, else we can get Var_Subst --- 71 unchanged lines hidden (view full) --- 822 vlist = str; 823 } 824 } 825 826 if (!vlist) { 827 /* Using .MAKE.EXPORTED */ 828 n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}"); 829 if (n < (int)sizeof(tmp)) { |
829 vlist = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); | 830 vlist = Var_Subst(NULL, tmp, VAR_GLOBAL, FALSE, TRUE); |
830 } 831 } 832 if (vlist) { 833 Var *v; 834 char **av; 835 char *as; 836 int ac; 837 int i; --- 13 unchanged lines hidden (view full) --- 851 * remove each one from .MAKE.EXPORTED. 852 * If we are removing them all, 853 * just delete .MAKE.EXPORTED below. 854 */ 855 if (vlist == str) { 856 n = snprintf(tmp, sizeof(tmp), 857 "${" MAKE_EXPORTED ":N%s}", v->name); 858 if (n < (int)sizeof(tmp)) { | 831 } 832 } 833 if (vlist) { 834 Var *v; 835 char **av; 836 char *as; 837 int ac; 838 int i; --- 13 unchanged lines hidden (view full) --- 852 * remove each one from .MAKE.EXPORTED. 853 * If we are removing them all, 854 * just delete .MAKE.EXPORTED below. 855 */ 856 if (vlist == str) { 857 n = snprintf(tmp, sizeof(tmp), 858 "${" MAKE_EXPORTED ":N%s}", v->name); 859 if (n < (int)sizeof(tmp)) { |
859 cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); | 860 cp = Var_Subst(NULL, tmp, VAR_GLOBAL, FALSE, TRUE); |
860 Var_Set(MAKE_EXPORTED, cp, VAR_GLOBAL, 0); 861 free(cp); 862 } 863 } 864 } 865 free(as); 866 free(av); 867 if (vlist != str) { --- 38 unchanged lines hidden (view full) --- 906 char *expanded_name = NULL; 907 908 /* 909 * We only look for a variable in the given context since anything set 910 * here will override anything in a lower context, so there's not much 911 * point in searching them all just to save a bit of memory... 912 */ 913 if (strchr(name, '$') != NULL) { | 861 Var_Set(MAKE_EXPORTED, cp, VAR_GLOBAL, 0); 862 free(cp); 863 } 864 } 865 } 866 free(as); 867 free(av); 868 if (vlist != str) { --- 38 unchanged lines hidden (view full) --- 907 char *expanded_name = NULL; 908 909 /* 910 * We only look for a variable in the given context since anything set 911 * here will override anything in a lower context, so there's not much 912 * point in searching them all just to save a bit of memory... 913 */ 914 if (strchr(name, '$') != NULL) { |
914 expanded_name = Var_Subst(NULL, name, ctxt, 0); | 915 expanded_name = Var_Subst(NULL, name, ctxt, FALSE, TRUE); |
915 if (expanded_name[0] == 0) { 916 if (DEBUG(VAR)) { 917 fprintf(debug_file, "Var_Set(\"%s\", \"%s\", ...) " 918 "name expands to empty string - ignored\n", 919 name, val); 920 } 921 free(expanded_name); 922 return; --- 54 unchanged lines hidden (view full) --- 977 if (varNoExportEnv != TRUE) 978 setenv(name, val, 1); 979 980 Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL); 981 } 982 983 984 out: | 916 if (expanded_name[0] == 0) { 917 if (DEBUG(VAR)) { 918 fprintf(debug_file, "Var_Set(\"%s\", \"%s\", ...) " 919 "name expands to empty string - ignored\n", 920 name, val); 921 } 922 free(expanded_name); 923 return; --- 54 unchanged lines hidden (view full) --- 978 if (varNoExportEnv != TRUE) 979 setenv(name, val, 1); 980 981 Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL); 982 } 983 984 985 out: |
985 if (expanded_name != NULL) 986 free(expanded_name); | 986 free(expanded_name); |
987 if (v != NULL) 988 VarFreeEnv(v, TRUE); 989} 990 991/*- 992 *----------------------------------------------------------------------- 993 * Var_Append -- 994 * The variable of the given name has the given value appended to it in --- 23 unchanged lines hidden (view full) --- 1018void 1019Var_Append(const char *name, const char *val, GNode *ctxt) 1020{ 1021 Var *v; 1022 Hash_Entry *h; 1023 char *expanded_name = NULL; 1024 1025 if (strchr(name, '$') != NULL) { | 987 if (v != NULL) 988 VarFreeEnv(v, TRUE); 989} 990 991/*- 992 *----------------------------------------------------------------------- 993 * Var_Append -- 994 * The variable of the given name has the given value appended to it in --- 23 unchanged lines hidden (view full) --- 1018void 1019Var_Append(const char *name, const char *val, GNode *ctxt) 1020{ 1021 Var *v; 1022 Hash_Entry *h; 1023 char *expanded_name = NULL; 1024 1025 if (strchr(name, '$') != NULL) { |
1026 expanded_name = Var_Subst(NULL, name, ctxt, 0); | 1026 expanded_name = Var_Subst(NULL, name, ctxt, FALSE, TRUE); |
1027 if (expanded_name[0] == 0) { 1028 if (DEBUG(VAR)) { 1029 fprintf(debug_file, "Var_Append(\"%s\", \"%s\", ...) " 1030 "name expands to empty string - ignored\n", 1031 name, val); 1032 } 1033 free(expanded_name); 1034 return; --- 21 unchanged lines hidden (view full) --- 1056 * it in the environment, but then we should provide a way to 1057 * export other variables...) 1058 */ 1059 v->flags &= ~VAR_FROM_ENV; 1060 h = Hash_CreateEntry(&ctxt->context, name, NULL); 1061 Hash_SetValue(h, v); 1062 } 1063 } | 1027 if (expanded_name[0] == 0) { 1028 if (DEBUG(VAR)) { 1029 fprintf(debug_file, "Var_Append(\"%s\", \"%s\", ...) " 1030 "name expands to empty string - ignored\n", 1031 name, val); 1032 } 1033 free(expanded_name); 1034 return; --- 21 unchanged lines hidden (view full) --- 1056 * it in the environment, but then we should provide a way to 1057 * export other variables...) 1058 */ 1059 v->flags &= ~VAR_FROM_ENV; 1060 h = Hash_CreateEntry(&ctxt->context, name, NULL); 1061 Hash_SetValue(h, v); 1062 } 1063 } |
1064 if (expanded_name != NULL) 1065 free(expanded_name); | 1064 free(expanded_name); |
1066} 1067 1068/*- 1069 *----------------------------------------------------------------------- 1070 * Var_Exists -- 1071 * See if the given variable exists. 1072 * 1073 * Input: --- 10 unchanged lines hidden (view full) --- 1084 */ 1085Boolean 1086Var_Exists(const char *name, GNode *ctxt) 1087{ 1088 Var *v; 1089 char *cp; 1090 1091 if ((cp = strchr(name, '$')) != NULL) { | 1065} 1066 1067/*- 1068 *----------------------------------------------------------------------- 1069 * Var_Exists -- 1070 * See if the given variable exists. 1071 * 1072 * Input: --- 10 unchanged lines hidden (view full) --- 1083 */ 1084Boolean 1085Var_Exists(const char *name, GNode *ctxt) 1086{ 1087 Var *v; 1088 char *cp; 1089 1090 if ((cp = strchr(name, '$')) != NULL) { |
1092 cp = Var_Subst(NULL, name, ctxt, FALSE); | 1091 cp = Var_Subst(NULL, name, ctxt, FALSE, TRUE); |
1093 } 1094 v = VarFind(cp ? cp : name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV); | 1092 } 1093 v = VarFind(cp ? cp : name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV); |
1095 if (cp != NULL) { 1096 free(cp); 1097 } | 1094 free(cp); |
1098 if (v == NULL) { 1099 return(FALSE); 1100 } else { 1101 (void)VarFreeEnv(v, TRUE); 1102 } 1103 return(TRUE); 1104} 1105 --- 278 unchanged lines hidden (view full) --- 1384 char *varexp; 1385 1386 if (addSpace && vpstate->varSpace) 1387 Buf_AddByte(buf, vpstate->varSpace); 1388 1389 addSpace = TRUE; 1390 1391 if ((ptr = Str_SYSVMatch(word, pat->lhs, &len)) != NULL) { | 1095 if (v == NULL) { 1096 return(FALSE); 1097 } else { 1098 (void)VarFreeEnv(v, TRUE); 1099 } 1100 return(TRUE); 1101} 1102 --- 278 unchanged lines hidden (view full) --- 1381 char *varexp; 1382 1383 if (addSpace && vpstate->varSpace) 1384 Buf_AddByte(buf, vpstate->varSpace); 1385 1386 addSpace = TRUE; 1387 1388 if ((ptr = Str_SYSVMatch(word, pat->lhs, &len)) != NULL) { |
1392 varexp = Var_Subst(NULL, pat->rhs, ctx, 0); | 1389 varexp = Var_Subst(NULL, pat->rhs, ctx, FALSE, TRUE); |
1393 Str_SYSVSubst(buf, varexp, ptr, len); 1394 free(varexp); 1395 } else { 1396 Buf_AddBytes(buf, strlen(word), word); 1397 } 1398 1399 return(addSpace); 1400} --- 403 unchanged lines hidden (view full) --- 1804 void *loopp) 1805{ 1806 VarLoop_t *loop = (VarLoop_t *)loopp; 1807 char *s; 1808 int slen; 1809 1810 if (word && *word) { 1811 Var_Set(loop->tvar, word, loop->ctxt, VAR_NO_EXPORT); | 1390 Str_SYSVSubst(buf, varexp, ptr, len); 1391 free(varexp); 1392 } else { 1393 Buf_AddBytes(buf, strlen(word), word); 1394 } 1395 1396 return(addSpace); 1397} --- 403 unchanged lines hidden (view full) --- 1801 void *loopp) 1802{ 1803 VarLoop_t *loop = (VarLoop_t *)loopp; 1804 char *s; 1805 int slen; 1806 1807 if (word && *word) { 1808 Var_Set(loop->tvar, word, loop->ctxt, VAR_NO_EXPORT); |
1812 s = Var_Subst(NULL, loop->str, loop->ctxt, loop->errnum); | 1809 s = Var_Subst(NULL, loop->str, loop->ctxt, loop->errnum, TRUE); |
1813 if (s != NULL && *s != '\0') { 1814 if (addSpace && *s != '\n') 1815 Buf_AddByte(buf, ' '); 1816 Buf_AddBytes(buf, (slen = strlen(s)), s); 1817 addSpace = (slen > 0 && s[slen - 1] != '\n'); 1818 free(s); 1819 } 1820 } --- 364 unchanged lines hidden (view full) --- 2185 int len; 2186 void *freeIt; 2187 2188 /* 2189 * If unescaped dollar sign not before the 2190 * delimiter, assume it's a variable 2191 * substitution and recurse. 2192 */ | 1810 if (s != NULL && *s != '\0') { 1811 if (addSpace && *s != '\n') 1812 Buf_AddByte(buf, ' '); 1813 Buf_AddBytes(buf, (slen = strlen(s)), s); 1814 addSpace = (slen > 0 && s[slen - 1] != '\n'); 1815 free(s); 1816 } 1817 } --- 364 unchanged lines hidden (view full) --- 2182 int len; 2183 void *freeIt; 2184 2185 /* 2186 * If unescaped dollar sign not before the 2187 * delimiter, assume it's a variable 2188 * substitution and recurse. 2189 */ |
2193 cp2 = Var_Parse(cp, ctxt, errnum, &len, &freeIt); | 2190 cp2 = Var_Parse(cp, ctxt, errnum, TRUE, &len, &freeIt); |
2194 Buf_AddBytes(&buf, strlen(cp2), cp2); | 2191 Buf_AddBytes(&buf, strlen(cp2), cp2); |
2195 if (freeIt) 2196 free(freeIt); | 2192 free(freeIt); |
2197 cp += len - 1; 2198 } else { 2199 const char *cp2 = &cp[1]; 2200 2201 if (*cp2 == PROPEN || *cp2 == BROPEN) { 2202 /* 2203 * Find the end of this variable reference 2204 * and suck it in without further ado. --- 36 unchanged lines hidden (view full) --- 2241 if (DEBUG(VAR)) 2242 fprintf(debug_file, "Modifier pattern: \"%s\"\n", rstr); 2243 return rstr; 2244} 2245 2246/*- 2247 *----------------------------------------------------------------------- 2248 * VarQuote -- | 2193 cp += len - 1; 2194 } else { 2195 const char *cp2 = &cp[1]; 2196 2197 if (*cp2 == PROPEN || *cp2 == BROPEN) { 2198 /* 2199 * Find the end of this variable reference 2200 * and suck it in without further ado. --- 36 unchanged lines hidden (view full) --- 2237 if (DEBUG(VAR)) 2238 fprintf(debug_file, "Modifier pattern: \"%s\"\n", rstr); 2239 return rstr; 2240} 2241 2242/*- 2243 *----------------------------------------------------------------------- 2244 * VarQuote -- |
2249 * Quote shell meta-characters in the string | 2245 * Quote shell meta-characters and space characters in the string |
2250 * 2251 * Results: 2252 * The quoted string 2253 * 2254 * Side Effects: 2255 * None. 2256 * 2257 *----------------------------------------------------------------------- 2258 */ 2259static char * 2260VarQuote(char *str) 2261{ 2262 2263 Buffer buf; | 2246 * 2247 * Results: 2248 * The quoted string 2249 * 2250 * Side Effects: 2251 * None. 2252 * 2253 *----------------------------------------------------------------------- 2254 */ 2255static char * 2256VarQuote(char *str) 2257{ 2258 2259 Buffer buf; |
2264 /* This should cover most shells :-( */ 2265 static const char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~"; | |
2266 const char *newline; | 2260 const char *newline; |
2267 size_t len, nlen; | 2261 size_t nlen; |
2268 2269 if ((newline = Shell_GetNewline()) == NULL) 2270 newline = "\\\n"; 2271 nlen = strlen(newline); 2272 2273 Buf_Init(&buf, 0); | 2262 2263 if ((newline = Shell_GetNewline()) == NULL) 2264 newline = "\\\n"; 2265 nlen = strlen(newline); 2266 2267 Buf_Init(&buf, 0); |
2274 while (*str != '\0') { 2275 if ((len = strcspn(str, meta)) != 0) { 2276 Buf_AddBytes(&buf, len, str); 2277 str += len; 2278 } else if (*str == '\n') { | 2268 2269 for (; *str != '\0'; str++) { 2270 if (*str == '\n') { |
2279 Buf_AddBytes(&buf, nlen, newline); | 2271 Buf_AddBytes(&buf, nlen, newline); |
2280 ++str; 2281 } else { 2282 Buf_AddByte(&buf, '\\'); 2283 Buf_AddByte(&buf, *str); 2284 ++str; | 2272 continue; |
2285 } | 2273 } |
2274 if (isspace((unsigned char)*str) || ismeta((unsigned char)*str)) 2275 Buf_AddByte(&buf, '\\'); 2276 Buf_AddByte(&buf, *str); |
|
2286 } | 2277 } |
2278 |
|
2287 str = Buf_Destroy(&buf, FALSE); 2288 if (DEBUG(VAR)) 2289 fprintf(debug_file, "QuoteMeta: [%s]\n", str); 2290 return str; 2291} 2292 2293/*- 2294 *----------------------------------------------------------------------- --- 168 unchanged lines hidden (view full) --- 2463 2464/* we now have some modifiers with long names */ 2465#define STRMOD_MATCH(s, want, n) \ 2466 (strncmp(s, want, n) == 0 && (s[n] == endc || s[n] == ':')) 2467 2468static char * 2469ApplyModifiers(char *nstr, const char *tstr, 2470 int startc, int endc, | 2279 str = Buf_Destroy(&buf, FALSE); 2280 if (DEBUG(VAR)) 2281 fprintf(debug_file, "QuoteMeta: [%s]\n", str); 2282 return str; 2283} 2284 2285/*- 2286 *----------------------------------------------------------------------- --- 168 unchanged lines hidden (view full) --- 2455 2456/* we now have some modifiers with long names */ 2457#define STRMOD_MATCH(s, want, n) \ 2458 (strncmp(s, want, n) == 0 && (s[n] == endc || s[n] == ':')) 2459 2460static char * 2461ApplyModifiers(char *nstr, const char *tstr, 2462 int startc, int endc, |
2471 Var *v, GNode *ctxt, Boolean errnum, | 2463 Var *v, GNode *ctxt, Boolean errnum, Boolean wantit, |
2472 int *lengthPtr, void **freePtr) 2473{ 2474 const char *start; 2475 const char *cp; /* Secondary pointer into str (place marker 2476 * for tstr) */ 2477 char *newStr; /* New value to return */ 2478 char termc; /* Character which terminated scan */ 2479 int cnt; /* Used to count brace pairs when variable in --- 14 unchanged lines hidden (view full) --- 2494 /* 2495 * We may have some complex modifiers in a variable. 2496 */ 2497 void *freeIt; 2498 char *rval; 2499 int rlen; 2500 int c; 2501 | 2464 int *lengthPtr, void **freePtr) 2465{ 2466 const char *start; 2467 const char *cp; /* Secondary pointer into str (place marker 2468 * for tstr) */ 2469 char *newStr; /* New value to return */ 2470 char termc; /* Character which terminated scan */ 2471 int cnt; /* Used to count brace pairs when variable in --- 14 unchanged lines hidden (view full) --- 2486 /* 2487 * We may have some complex modifiers in a variable. 2488 */ 2489 void *freeIt; 2490 char *rval; 2491 int rlen; 2492 int c; 2493 |
2502 rval = Var_Parse(tstr, ctxt, errnum, &rlen, &freeIt); | 2494 rval = Var_Parse(tstr, ctxt, errnum, wantit, &rlen, &freeIt); |
2503 2504 /* 2505 * If we have not parsed up to endc or ':', 2506 * we are not interested. 2507 */ 2508 if (rval != NULL && *rval && 2509 (c = tstr[rlen]) != '\0' && 2510 c != ':' && 2511 c != endc) { | 2495 2496 /* 2497 * If we have not parsed up to endc or ':', 2498 * we are not interested. 2499 */ 2500 if (rval != NULL && *rval && 2501 (c = tstr[rlen]) != '\0' && 2502 c != ':' && 2503 c != endc) { |
2512 if (freeIt) 2513 free(freeIt); | 2504 free(freeIt); |
2514 goto apply_mods; 2515 } 2516 2517 if (DEBUG(VAR)) { 2518 fprintf(debug_file, "Got '%s' from '%.*s'%.*s\n", 2519 rval, rlen, tstr, rlen, tstr + rlen); 2520 } 2521 2522 tstr += rlen; 2523 2524 if (rval != NULL && *rval) { 2525 int used; 2526 2527 nstr = ApplyModifiers(nstr, rval, 2528 0, 0, | 2505 goto apply_mods; 2506 } 2507 2508 if (DEBUG(VAR)) { 2509 fprintf(debug_file, "Got '%s' from '%.*s'%.*s\n", 2510 rval, rlen, tstr, rlen, tstr + rlen); 2511 } 2512 2513 tstr += rlen; 2514 2515 if (rval != NULL && *rval) { 2516 int used; 2517 2518 nstr = ApplyModifiers(nstr, rval, 2519 0, 0, |
2529 v, ctxt, errnum, &used, freePtr); | 2520 v, ctxt, errnum, wantit, &used, freePtr); |
2530 if (nstr == var_Error 2531 || (nstr == varNoError && errnum == 0) 2532 || strlen(rval) != (size_t) used) { | 2521 if (nstr == var_Error 2522 || (nstr == varNoError && errnum == 0) 2523 || strlen(rval) != (size_t) used) { |
2533 if (freeIt) 2534 free(freeIt); | 2524 free(freeIt); |
2535 goto out; /* error already reported */ 2536 } 2537 } | 2525 goto out; /* error already reported */ 2526 } 2527 } |
2538 if (freeIt) 2539 free(freeIt); | 2528 free(freeIt); |
2540 if (*tstr == ':') 2541 tstr++; 2542 else if (!*tstr && endc) { 2543 Error("Unclosed variable specification after complex modifier (expecting '%c') for %s", endc, v->name); 2544 goto out; 2545 } 2546 continue; 2547 } --- 12 unchanged lines hidden (view full) --- 2560 /* 2561 * "::=", "::!=", "::+=", or "::?=" 2562 */ 2563 GNode *v_ctxt; /* context where v belongs */ 2564 const char *emsg; 2565 char *sv_name; 2566 VarPattern pattern; 2567 int how; | 2529 if (*tstr == ':') 2530 tstr++; 2531 else if (!*tstr && endc) { 2532 Error("Unclosed variable specification after complex modifier (expecting '%c') for %s", endc, v->name); 2533 goto out; 2534 } 2535 continue; 2536 } --- 12 unchanged lines hidden (view full) --- 2549 /* 2550 * "::=", "::!=", "::+=", or "::?=" 2551 */ 2552 GNode *v_ctxt; /* context where v belongs */ 2553 const char *emsg; 2554 char *sv_name; 2555 VarPattern pattern; 2556 int how; |
2557 int flags; |
|
2568 2569 if (v->name[0] == 0) 2570 goto bad_modifier; 2571 2572 v_ctxt = ctxt; 2573 sv_name = NULL; 2574 ++tstr; 2575 if (v->flags & VAR_JUNK) { --- 19 unchanged lines hidden (view full) --- 2595 break; 2596 default: 2597 cp = ++tstr; 2598 break; 2599 } 2600 delim = startc == PROPEN ? PRCLOSE : BRCLOSE; 2601 pattern.flags = 0; 2602 | 2558 2559 if (v->name[0] == 0) 2560 goto bad_modifier; 2561 2562 v_ctxt = ctxt; 2563 sv_name = NULL; 2564 ++tstr; 2565 if (v->flags & VAR_JUNK) { --- 19 unchanged lines hidden (view full) --- 2585 break; 2586 default: 2587 cp = ++tstr; 2588 break; 2589 } 2590 delim = startc == PROPEN ? PRCLOSE : BRCLOSE; 2591 pattern.flags = 0; 2592 |
2593 flags = (wantit) ? 0 : VAR_NOSUBST; |
|
2603 pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum, | 2594 pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum, |
2604 &cp, delim, NULL, | 2595 &cp, delim, &flags, |
2605 &pattern.rightLen, 2606 NULL); 2607 if (v->flags & VAR_JUNK) { 2608 /* restore original name */ 2609 free(v->name); 2610 v->name = sv_name; 2611 } 2612 if (pattern.rhs == NULL) 2613 goto cleanup; 2614 2615 termc = *--cp; 2616 delim = '\0'; 2617 | 2596 &pattern.rightLen, 2597 NULL); 2598 if (v->flags & VAR_JUNK) { 2599 /* restore original name */ 2600 free(v->name); 2601 v->name = sv_name; 2602 } 2603 if (pattern.rhs == NULL) 2604 goto cleanup; 2605 2606 termc = *--cp; 2607 delim = '\0'; 2608 |
2618 switch (how) { 2619 case '+': 2620 Var_Append(v->name, pattern.rhs, v_ctxt); 2621 break; 2622 case '!': 2623 newStr = Cmd_Exec(pattern.rhs, &emsg); 2624 if (emsg) 2625 Error(emsg, nstr); 2626 else 2627 Var_Set(v->name, newStr, v_ctxt, 0); 2628 if (newStr) | 2609 if (wantit) { 2610 switch (how) { 2611 case '+': 2612 Var_Append(v->name, pattern.rhs, v_ctxt); 2613 break; 2614 case '!': 2615 newStr = Cmd_Exec(pattern.rhs, &emsg); 2616 if (emsg) 2617 Error(emsg, nstr); 2618 else 2619 Var_Set(v->name, newStr, v_ctxt, 0); |
2629 free(newStr); | 2620 free(newStr); |
2630 break; 2631 case '?': 2632 if ((v->flags & VAR_JUNK) == 0) | |
2633 break; | 2621 break; |
2634 /* FALLTHROUGH */ 2635 default: 2636 Var_Set(v->name, pattern.rhs, v_ctxt, 0); 2637 break; | 2622 case '?': 2623 if ((v->flags & VAR_JUNK) == 0) 2624 break; 2625 /* FALLTHROUGH */ 2626 default: 2627 Var_Set(v->name, pattern.rhs, v_ctxt, 0); 2628 break; 2629 } |
2638 } 2639 free(UNCONST(pattern.rhs)); 2640 newStr = varNoError; 2641 break; 2642 } 2643 goto default_case; /* "::<unrecognised>" */ 2644 } 2645 case '@': --- 25 unchanged lines hidden (view full) --- 2671 free(loop.tvar); 2672 free(loop.str); 2673 break; 2674 } 2675 case 'D': 2676 case 'U': 2677 { 2678 Buffer buf; /* Buffer for patterns */ | 2630 } 2631 free(UNCONST(pattern.rhs)); 2632 newStr = varNoError; 2633 break; 2634 } 2635 goto default_case; /* "::<unrecognised>" */ 2636 } 2637 case '@': --- 25 unchanged lines hidden (view full) --- 2663 free(loop.tvar); 2664 free(loop.str); 2665 break; 2666 } 2667 case 'D': 2668 case 'U': 2669 { 2670 Buffer buf; /* Buffer for patterns */ |
2679 int wantit; /* want data in buffer */ | 2671 int wantit_; /* want data in buffer */ |
2680 | 2672 |
2673 if (wantit) { 2674 if (*tstr == 'U') 2675 wantit_ = ((v->flags & VAR_JUNK) != 0); 2676 else 2677 wantit_ = ((v->flags & VAR_JUNK) == 0); 2678 } else 2679 wantit_ = wantit; |
|
2681 /* 2682 * Pass through tstr looking for 1) escaped delimiters, 2683 * '$'s and backslashes (place the escaped character in 2684 * uninterpreted) and 2) unescaped $'s that aren't before 2685 * the delimiter (expand the variable substitution). 2686 * The result is left in the Buffer buf. 2687 */ 2688 Buf_Init(&buf, 0); --- 12 unchanged lines hidden (view full) --- 2701 /* 2702 * If unescaped dollar sign, assume it's a 2703 * variable substitution and recurse. 2704 */ 2705 char *cp2; 2706 int len; 2707 void *freeIt; 2708 | 2680 /* 2681 * Pass through tstr looking for 1) escaped delimiters, 2682 * '$'s and backslashes (place the escaped character in 2683 * uninterpreted) and 2) unescaped $'s that aren't before 2684 * the delimiter (expand the variable substitution). 2685 * The result is left in the Buffer buf. 2686 */ 2687 Buf_Init(&buf, 0); --- 12 unchanged lines hidden (view full) --- 2700 /* 2701 * If unescaped dollar sign, assume it's a 2702 * variable substitution and recurse. 2703 */ 2704 char *cp2; 2705 int len; 2706 void *freeIt; 2707 |
2709 cp2 = Var_Parse(cp, ctxt, errnum, &len, &freeIt); | 2708 cp2 = Var_Parse(cp, ctxt, errnum, wantit_, &len, &freeIt); |
2710 Buf_AddBytes(&buf, strlen(cp2), cp2); | 2709 Buf_AddBytes(&buf, strlen(cp2), cp2); |
2711 if (freeIt) 2712 free(freeIt); | 2710 free(freeIt); |
2713 cp += len - 1; 2714 } else { 2715 Buf_AddByte(&buf, *cp); 2716 } 2717 } 2718 2719 termc = *cp; 2720 | 2711 cp += len - 1; 2712 } else { 2713 Buf_AddByte(&buf, *cp); 2714 } 2715 } 2716 2717 termc = *cp; 2718 |
2721 if (*tstr == 'U') 2722 wantit = ((v->flags & VAR_JUNK) != 0); 2723 else 2724 wantit = ((v->flags & VAR_JUNK) == 0); | |
2725 if ((v->flags & VAR_JUNK) != 0) 2726 v->flags |= VAR_KEEP; | 2719 if ((v->flags & VAR_JUNK) != 0) 2720 v->flags |= VAR_KEEP; |
2727 if (wantit) { | 2721 if (wantit_) { |
2728 newStr = Buf_Destroy(&buf, FALSE); 2729 } else { 2730 newStr = nstr; 2731 Buf_Destroy(&buf, TRUE); 2732 } 2733 break; 2734 } 2735 case 'L': --- 28 unchanged lines hidden (view full) --- 2764 } 2765 case '!': 2766 { 2767 const char *emsg; 2768 VarPattern pattern; 2769 pattern.flags = 0; 2770 2771 delim = '!'; | 2722 newStr = Buf_Destroy(&buf, FALSE); 2723 } else { 2724 newStr = nstr; 2725 Buf_Destroy(&buf, TRUE); 2726 } 2727 break; 2728 } 2729 case 'L': --- 28 unchanged lines hidden (view full) --- 2758 } 2759 case '!': 2760 { 2761 const char *emsg; 2762 VarPattern pattern; 2763 pattern.flags = 0; 2764 2765 delim = '!'; |
2772 | 2766 emsg = NULL; |
2773 cp = ++tstr; 2774 if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum, 2775 &cp, delim, 2776 NULL, &pattern.rightLen, 2777 NULL)) == NULL) 2778 goto cleanup; | 2767 cp = ++tstr; 2768 if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum, 2769 &cp, delim, 2770 NULL, &pattern.rightLen, 2771 NULL)) == NULL) 2772 goto cleanup; |
2779 newStr = Cmd_Exec(pattern.rhs, &emsg); | 2773 if (wantit) 2774 newStr = Cmd_Exec(pattern.rhs, &emsg); 2775 else 2776 newStr = varNoError; |
2780 free(UNCONST(pattern.rhs)); 2781 if (emsg) 2782 Error(emsg, nstr); 2783 termc = *cp; 2784 delim = '\0'; 2785 if (v->flags & VAR_JUNK) { 2786 v->flags |= VAR_KEEP; 2787 } --- 359 unchanged lines hidden (view full) --- 3147 pattern = bmake_strndup(tstr+1, endpat - (tstr + 1)); 3148 } 3149 if (needSubst) { 3150 /* 3151 * pattern contains embedded '$', so use Var_Subst to 3152 * expand it. 3153 */ 3154 cp2 = pattern; | 2777 free(UNCONST(pattern.rhs)); 2778 if (emsg) 2779 Error(emsg, nstr); 2780 termc = *cp; 2781 delim = '\0'; 2782 if (v->flags & VAR_JUNK) { 2783 v->flags |= VAR_KEEP; 2784 } --- 359 unchanged lines hidden (view full) --- 3144 pattern = bmake_strndup(tstr+1, endpat - (tstr + 1)); 3145 } 3146 if (needSubst) { 3147 /* 3148 * pattern contains embedded '$', so use Var_Subst to 3149 * expand it. 3150 */ 3151 cp2 = pattern; |
3155 pattern = Var_Subst(NULL, cp2, ctxt, errnum); | 3152 pattern = Var_Subst(NULL, cp2, ctxt, errnum, TRUE); |
3156 free(cp2); 3157 } 3158 if (DEBUG(VAR)) 3159 fprintf(debug_file, "Pattern[%s] for [%s] is [%s]\n", 3160 v->name, nstr, pattern); 3161 if (*tstr == 'M') { 3162 newStr = VarModify(ctxt, &parsestate, nstr, VarMatch, 3163 pattern); --- 69 unchanged lines hidden (view full) --- 3233 free(UNCONST(pattern.rhs)); 3234 delim = '\0'; 3235 break; 3236 } 3237 case '?': 3238 { 3239 VarPattern pattern; 3240 Boolean value; | 3153 free(cp2); 3154 } 3155 if (DEBUG(VAR)) 3156 fprintf(debug_file, "Pattern[%s] for [%s] is [%s]\n", 3157 v->name, nstr, pattern); 3158 if (*tstr == 'M') { 3159 newStr = VarModify(ctxt, &parsestate, nstr, VarMatch, 3160 pattern); --- 69 unchanged lines hidden (view full) --- 3230 free(UNCONST(pattern.rhs)); 3231 delim = '\0'; 3232 break; 3233 } 3234 case '?': 3235 { 3236 VarPattern pattern; 3237 Boolean value; |
3241 | 3238 int cond_rc; 3239 int lhs_flags, rhs_flags; 3240 |
3242 /* find ':', and then substitute accordingly */ | 3241 /* find ':', and then substitute accordingly */ |
3243 | 3242 if (wantit) { 3243 cond_rc = Cond_EvalExpression(NULL, v->name, &value, 0, FALSE); 3244 if (cond_rc == COND_INVALID) { 3245 lhs_flags = rhs_flags = VAR_NOSUBST; 3246 } else if (value) { 3247 lhs_flags = 0; 3248 rhs_flags = VAR_NOSUBST; 3249 } else { 3250 lhs_flags = VAR_NOSUBST; 3251 rhs_flags = 0; 3252 } 3253 } else { 3254 /* we are just consuming and discarding */ 3255 cond_rc = value = 0; 3256 lhs_flags = rhs_flags = VAR_NOSUBST; 3257 } |
3244 pattern.flags = 0; 3245 3246 cp = ++tstr; 3247 delim = ':'; 3248 if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, errnum, | 3258 pattern.flags = 0; 3259 3260 cp = ++tstr; 3261 delim = ':'; 3262 if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, errnum, |
3249 &cp, delim, NULL, | 3263 &cp, delim, &lhs_flags, |
3250 &pattern.leftLen, 3251 NULL)) == NULL) 3252 goto cleanup; 3253 3254 /* BROPEN or PROPEN */ 3255 delim = endc; 3256 if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum, | 3264 &pattern.leftLen, 3265 NULL)) == NULL) 3266 goto cleanup; 3267 3268 /* BROPEN or PROPEN */ 3269 delim = endc; 3270 if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum, |
3257 &cp, delim, NULL, | 3271 &cp, delim, &rhs_flags, |
3258 &pattern.rightLen, 3259 NULL)) == NULL) 3260 goto cleanup; 3261 3262 termc = *--cp; 3263 delim = '\0'; | 3272 &pattern.rightLen, 3273 NULL)) == NULL) 3274 goto cleanup; 3275 3276 termc = *--cp; 3277 delim = '\0'; |
3264 if (Cond_EvalExpression(NULL, v->name, &value, 0, FALSE) 3265 == COND_INVALID) { | 3278 if (cond_rc == COND_INVALID) { |
3266 Error("Bad conditional expression `%s' in %s?%s:%s", 3267 v->name, v->name, pattern.lhs, pattern.rhs); 3268 goto cleanup; 3269 } 3270 3271 if (value) { 3272 newStr = UNCONST(pattern.lhs); 3273 free(UNCONST(pattern.rhs)); --- 145 unchanged lines hidden (view full) --- 3419 termc = *cp; 3420 break; 3421 } 3422 goto default_case; 3423#ifdef SUNSHCMD 3424 case 's': 3425 if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) { 3426 const char *emsg; | 3279 Error("Bad conditional expression `%s' in %s?%s:%s", 3280 v->name, v->name, pattern.lhs, pattern.rhs); 3281 goto cleanup; 3282 } 3283 3284 if (value) { 3285 newStr = UNCONST(pattern.lhs); 3286 free(UNCONST(pattern.rhs)); --- 145 unchanged lines hidden (view full) --- 3432 termc = *cp; 3433 break; 3434 } 3435 goto default_case; 3436#ifdef SUNSHCMD 3437 case 's': 3438 if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) { 3439 const char *emsg; |
3427 newStr = Cmd_Exec(nstr, &emsg); 3428 if (emsg) 3429 Error(emsg, nstr); | 3440 if (wantit) { 3441 newStr = Cmd_Exec(nstr, &emsg); 3442 if (emsg) 3443 Error(emsg, nstr); 3444 } else 3445 newStr = varNoError; |
3430 cp = tstr + 2; 3431 termc = *cp; 3432 break; 3433 } 3434 goto default_case; 3435#endif 3436 default: 3437 default_case: --- 104 unchanged lines hidden (view full) --- 3542 Error("Bad modifier `:%.*s' for %s", (int)strcspn(tstr, ":)}"), tstr, 3543 v->name); 3544 3545 cleanup: 3546 *lengthPtr = cp - start; 3547 if (delim != '\0') 3548 Error("Unclosed substitution for %s (%c missing)", 3549 v->name, delim); | 3446 cp = tstr + 2; 3447 termc = *cp; 3448 break; 3449 } 3450 goto default_case; 3451#endif 3452 default: 3453 default_case: --- 104 unchanged lines hidden (view full) --- 3558 Error("Bad modifier `:%.*s' for %s", (int)strcspn(tstr, ":)}"), tstr, 3559 v->name); 3560 3561 cleanup: 3562 *lengthPtr = cp - start; 3563 if (delim != '\0') 3564 Error("Unclosed substitution for %s (%c missing)", 3565 v->name, delim); |
3550 if (*freePtr) { 3551 free(*freePtr); 3552 *freePtr = NULL; 3553 } | 3566 free(*freePtr); 3567 *freePtr = NULL; |
3554 return (var_Error); 3555} 3556 3557/*- 3558 *----------------------------------------------------------------------- 3559 * Var_Parse -- 3560 * Given the start of a variable invocation, extract the variable 3561 * name and find its value, then modify it according to the 3562 * specification. 3563 * 3564 * Input: 3565 * str The string to parse 3566 * ctxt The context for the variable 3567 * errnum TRUE if undefined variables are an error | 3568 return (var_Error); 3569} 3570 3571/*- 3572 *----------------------------------------------------------------------- 3573 * Var_Parse -- 3574 * Given the start of a variable invocation, extract the variable 3575 * name and find its value, then modify it according to the 3576 * specification. 3577 * 3578 * Input: 3579 * str The string to parse 3580 * ctxt The context for the variable 3581 * errnum TRUE if undefined variables are an error |
3582 * wantit TRUE if we actually want the result |
|
3568 * lengthPtr OUT: The length of the specification 3569 * freePtr OUT: Non-NULL if caller should free *freePtr 3570 * 3571 * Results: 3572 * The (possibly-modified) value of the variable or var_Error if the 3573 * specification is invalid. The length of the specification is 3574 * placed in *lengthPtr (for invalid specifications, this is just 3575 * 2...?). 3576 * If *freePtr is non-NULL then it's a pointer that the caller 3577 * should pass to free() to free memory used by the result. 3578 * 3579 * Side Effects: 3580 * None. 3581 * 3582 *----------------------------------------------------------------------- 3583 */ 3584/* coverity[+alloc : arg-*4] */ 3585char * | 3583 * lengthPtr OUT: The length of the specification 3584 * freePtr OUT: Non-NULL if caller should free *freePtr 3585 * 3586 * Results: 3587 * The (possibly-modified) value of the variable or var_Error if the 3588 * specification is invalid. The length of the specification is 3589 * placed in *lengthPtr (for invalid specifications, this is just 3590 * 2...?). 3591 * If *freePtr is non-NULL then it's a pointer that the caller 3592 * should pass to free() to free memory used by the result. 3593 * 3594 * Side Effects: 3595 * None. 3596 * 3597 *----------------------------------------------------------------------- 3598 */ 3599/* coverity[+alloc : arg-*4] */ 3600char * |
3586Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr, 3587 void **freePtr) | 3601Var_Parse(const char *str, GNode *ctxt, 3602 Boolean errnum, Boolean wantit, 3603 int *lengthPtr, void **freePtr) |
3588{ 3589 const char *tstr; /* Pointer into str */ 3590 Var *v; /* Variable in invocation */ 3591 Boolean haveModifier;/* TRUE if have modifiers for the variable */ 3592 char endc; /* Ending character when variable in parens 3593 * or braces */ 3594 char startc; /* Starting character when variable in parens 3595 * or braces */ --- 88 unchanged lines hidden (view full) --- 3684 break; 3685 } 3686 /* 3687 * A variable inside a variable, expand 3688 */ 3689 if (*tstr == '$') { 3690 int rlen; 3691 void *freeIt; | 3604{ 3605 const char *tstr; /* Pointer into str */ 3606 Var *v; /* Variable in invocation */ 3607 Boolean haveModifier;/* TRUE if have modifiers for the variable */ 3608 char endc; /* Ending character when variable in parens 3609 * or braces */ 3610 char startc; /* Starting character when variable in parens 3611 * or braces */ --- 88 unchanged lines hidden (view full) --- 3700 break; 3701 } 3702 /* 3703 * A variable inside a variable, expand 3704 */ 3705 if (*tstr == '$') { 3706 int rlen; 3707 void *freeIt; |
3692 char *rval = Var_Parse(tstr, ctxt, errnum, &rlen, &freeIt); | 3708 char *rval = Var_Parse(tstr, ctxt, errnum, wantit, &rlen, &freeIt); |
3693 if (rval != NULL) { 3694 Buf_AddBytes(&buf, strlen(rval), rval); 3695 } | 3709 if (rval != NULL) { 3710 Buf_AddBytes(&buf, strlen(rval), rval); 3711 } |
3696 if (freeIt) 3697 free(freeIt); | 3712 free(freeIt); |
3698 tstr += rlen - 1; 3699 } 3700 else 3701 Buf_AddByte(&buf, *tstr); 3702 } 3703 if (*tstr == ':') { 3704 haveModifier = TRUE; 3705 } else if (*tstr == endc) { --- 126 unchanged lines hidden (view full) --- 3832 * necessary (there's a dollar sign somewhere in the variable's value) 3833 * we just call Var_Subst to do any other substitutions that are 3834 * necessary. Note that the value returned by Var_Subst will have 3835 * been dynamically-allocated, so it will need freeing when we 3836 * return. 3837 */ 3838 nstr = Buf_GetAll(&v->val, NULL); 3839 if (strchr(nstr, '$') != NULL) { | 3713 tstr += rlen - 1; 3714 } 3715 else 3716 Buf_AddByte(&buf, *tstr); 3717 } 3718 if (*tstr == ':') { 3719 haveModifier = TRUE; 3720 } else if (*tstr == endc) { --- 126 unchanged lines hidden (view full) --- 3847 * necessary (there's a dollar sign somewhere in the variable's value) 3848 * we just call Var_Subst to do any other substitutions that are 3849 * necessary. Note that the value returned by Var_Subst will have 3850 * been dynamically-allocated, so it will need freeing when we 3851 * return. 3852 */ 3853 nstr = Buf_GetAll(&v->val, NULL); 3854 if (strchr(nstr, '$') != NULL) { |
3840 nstr = Var_Subst(NULL, nstr, ctxt, errnum); | 3855 nstr = Var_Subst(NULL, nstr, ctxt, errnum, wantit); |
3841 *freePtr = nstr; 3842 } 3843 3844 v->flags &= ~VAR_IN_USE; 3845 3846 if ((nstr != NULL) && (haveModifier || extramodifiers != NULL)) { 3847 void *extraFree; 3848 int used; 3849 3850 extraFree = NULL; 3851 if (extramodifiers != NULL) { 3852 nstr = ApplyModifiers(nstr, extramodifiers, '(', ')', | 3856 *freePtr = nstr; 3857 } 3858 3859 v->flags &= ~VAR_IN_USE; 3860 3861 if ((nstr != NULL) && (haveModifier || extramodifiers != NULL)) { 3862 void *extraFree; 3863 int used; 3864 3865 extraFree = NULL; 3866 if (extramodifiers != NULL) { 3867 nstr = ApplyModifiers(nstr, extramodifiers, '(', ')', |
3853 v, ctxt, errnum, &used, &extraFree); | 3868 v, ctxt, errnum, wantit, &used, &extraFree); |
3854 } 3855 3856 if (haveModifier) { 3857 /* Skip initial colon. */ 3858 tstr++; 3859 3860 nstr = ApplyModifiers(nstr, tstr, startc, endc, | 3869 } 3870 3871 if (haveModifier) { 3872 /* Skip initial colon. */ 3873 tstr++; 3874 3875 nstr = ApplyModifiers(nstr, tstr, startc, endc, |
3861 v, ctxt, errnum, &used, freePtr); | 3876 v, ctxt, errnum, wantit, &used, freePtr); |
3862 tstr += used; | 3877 tstr += used; |
3863 if (extraFree) { 3864 free(extraFree); 3865 } | 3878 free(extraFree); |
3866 } else { 3867 *freePtr = extraFree; 3868 } 3869 } 3870 if (*tstr) { 3871 *lengthPtr = tstr - start + 1; 3872 } else { 3873 *lengthPtr = tstr - start; --- 45 unchanged lines hidden (view full) --- 3919 * If undefErr is TRUE, Parse_Error will be called when an undefined 3920 * variable is encountered. 3921 * 3922 * Input: 3923 * var Named variable || NULL for all 3924 * str the string which to substitute 3925 * ctxt the context wherein to find variables 3926 * undefErr TRUE if undefineds are an error | 3879 } else { 3880 *freePtr = extraFree; 3881 } 3882 } 3883 if (*tstr) { 3884 *lengthPtr = tstr - start + 1; 3885 } else { 3886 *lengthPtr = tstr - start; --- 45 unchanged lines hidden (view full) --- 3932 * If undefErr is TRUE, Parse_Error will be called when an undefined 3933 * variable is encountered. 3934 * 3935 * Input: 3936 * var Named variable || NULL for all 3937 * str the string which to substitute 3938 * ctxt the context wherein to find variables 3939 * undefErr TRUE if undefineds are an error |
3940 * wantit TRUE if we actually want the result |
|
3927 * 3928 * Results: 3929 * The resulting string. 3930 * 3931 * Side Effects: 3932 * None. The old string must be freed by the caller 3933 *----------------------------------------------------------------------- 3934 */ 3935char * | 3941 * 3942 * Results: 3943 * The resulting string. 3944 * 3945 * Side Effects: 3946 * None. The old string must be freed by the caller 3947 *----------------------------------------------------------------------- 3948 */ 3949char * |
3936Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr) | 3950Var_Subst(const char *var, const char *str, GNode *ctxt, 3951 Boolean undefErr, Boolean wantit) |
3937{ 3938 Buffer buf; /* Buffer for forming things */ 3939 char *val; /* Value to substitute for a variable */ 3940 int length; /* Length of the variable invocation */ 3941 Boolean trailingBslash; /* variable ends in \ */ 3942 void *freeIt = NULL; /* Set if it should be freed */ 3943 static Boolean errorReported; /* Set true if an error has already 3944 * been reported to prevent a plethora --- 81 unchanged lines hidden (view full) --- 4026 expand = TRUE; 4027 break; 4028 } 4029 } 4030 if (!expand) 4031 continue; 4032 } 4033 | 3952{ 3953 Buffer buf; /* Buffer for forming things */ 3954 char *val; /* Value to substitute for a variable */ 3955 int length; /* Length of the variable invocation */ 3956 Boolean trailingBslash; /* variable ends in \ */ 3957 void *freeIt = NULL; /* Set if it should be freed */ 3958 static Boolean errorReported; /* Set true if an error has already 3959 * been reported to prevent a plethora --- 81 unchanged lines hidden (view full) --- 4041 expand = TRUE; 4042 break; 4043 } 4044 } 4045 if (!expand) 4046 continue; 4047 } 4048 |
4034 val = Var_Parse(str, ctxt, undefErr, &length, &freeIt); | 4049 val = Var_Parse(str, ctxt, undefErr, wantit, &length, &freeIt); |
4035 4036 /* 4037 * When we come down here, val should either point to the 4038 * value of this variable, suitably modified, or be NULL. 4039 * Length should be the total length of the potential 4040 * variable invocation (from $ to end character...) 4041 */ 4042 if (val == var_Error || val == varNoError) { --- 31 unchanged lines hidden (view full) --- 4074 /* 4075 * Copy all the characters from the variable value straight 4076 * into the new string. 4077 */ 4078 length = strlen(val); 4079 Buf_AddBytes(&buf, length, val); 4080 trailingBslash = length > 0 && val[length - 1] == '\\'; 4081 } | 4050 4051 /* 4052 * When we come down here, val should either point to the 4053 * value of this variable, suitably modified, or be NULL. 4054 * Length should be the total length of the potential 4055 * variable invocation (from $ to end character...) 4056 */ 4057 if (val == var_Error || val == varNoError) { --- 31 unchanged lines hidden (view full) --- 4089 /* 4090 * Copy all the characters from the variable value straight 4091 * into the new string. 4092 */ 4093 length = strlen(val); 4094 Buf_AddBytes(&buf, length, val); 4095 trailingBslash = length > 0 && val[length - 1] == '\\'; 4096 } |
4082 if (freeIt) { 4083 free(freeIt); 4084 freeIt = NULL; 4085 } | 4097 free(freeIt); 4098 freeIt = NULL; |
4086 } 4087 } 4088 4089 return Buf_DestroyCompact(&buf); 4090} 4091 4092/*- 4093 *----------------------------------------------------------------------- --- 101 unchanged lines hidden --- | 4099 } 4100 } 4101 4102 return Buf_DestroyCompact(&buf); 4103} 4104 4105/*- 4106 *----------------------------------------------------------------------- --- 101 unchanged lines hidden --- |