diff options
author | sjg <sjg@FreeBSD.org> | 2015-10-23 17:38:01 +0000 |
---|---|---|
committer | sjg <sjg@FreeBSD.org> | 2015-10-23 17:38:01 +0000 |
commit | a1cf517b9773cdac110ae2e070a8b6a211054302 (patch) | |
tree | 90f609aa8fbb06b6220e1227adcc383d6ee1e5c4 /contrib/bmake/var.c | |
parent | 495cadb99fd3b99f7ac1a08451c84940d3fb747a (diff) | |
parent | fc737f02d4dbedb056bf90a3107fd7c5af012f0f (diff) | |
download | FreeBSD-src-a1cf517b9773cdac110ae2e070a8b6a211054302.zip FreeBSD-src-a1cf517b9773cdac110ae2e070a8b6a211054302.tar.gz |
Merge bmake 20151020
Diffstat (limited to 'contrib/bmake/var.c')
-rw-r--r-- | contrib/bmake/var.c | 229 |
1 files changed, 121 insertions, 108 deletions
diff --git a/contrib/bmake/var.c b/contrib/bmake/var.c index e15c301..6fd3825 100644 --- a/contrib/bmake/var.c +++ b/contrib/bmake/var.c @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.192 2015/05/05 21:51:09 sjg Exp $ */ +/* $NetBSD: var.c,v 1.199 2015/10/20 21:30:57 sjg Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: var.c,v 1.192 2015/05/05 21:51:09 sjg Exp $"; +static char rcsid[] = "$NetBSD: var.c,v 1.199 2015/10/20 21:30:57 sjg Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: var.c,v 1.192 2015/05/05 21:51:09 sjg Exp $"); +__RCSID("$NetBSD: var.c,v 1.199 2015/10/20 21:30:57 sjg Exp $"); #endif #endif /* not lint */ #endif @@ -138,6 +138,7 @@ __RCSID("$NetBSD: var.c,v 1.192 2015/05/05 21:51:09 sjg Exp $"); #include "buf.h" #include "dir.h" #include "job.h" +#include "metachar.h" extern int makelevel; /* @@ -541,7 +542,7 @@ Var_Delete(const char *name, GNode *ctxt) char *cp; if (strchr(name, '$')) { - cp = Var_Subst(NULL, name, VAR_GLOBAL, 0); + cp = Var_Subst(NULL, name, VAR_GLOBAL, FALSE, TRUE); } else { cp = (char *)name; } @@ -632,7 +633,7 @@ Var_Export1(const char *name, int parent) } n = snprintf(tmp, sizeof(tmp), "${%s}", name); if (n < (int)sizeof(tmp)) { - val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); + val = Var_Subst(NULL, tmp, VAR_GLOBAL, FALSE, TRUE); setenv(name, val, 1); free(val); } @@ -700,7 +701,7 @@ Var_ExportVars(void) int ac; int i; - val = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); + val = Var_Subst(NULL, tmp, VAR_GLOBAL, FALSE, TRUE); av = brk_string(val, &ac, FALSE, &as); for (i = 0; i < ac; i++) { Var_Export1(av[i], 0); @@ -738,7 +739,7 @@ Var_Export(char *str, int isExport) } else { track = VAR_EXPORT_PARENT; } - val = Var_Subst(NULL, str, VAR_GLOBAL, 0); + val = Var_Subst(NULL, str, VAR_GLOBAL, FALSE, TRUE); av = brk_string(val, &ac, FALSE, &as); for (i = 0; i < ac; i++) { name = av[i]; @@ -826,7 +827,7 @@ Var_UnExport(char *str) /* Using .MAKE.EXPORTED */ n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}"); if (n < (int)sizeof(tmp)) { - vlist = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); + vlist = Var_Subst(NULL, tmp, VAR_GLOBAL, FALSE, TRUE); } } if (vlist) { @@ -856,7 +857,7 @@ Var_UnExport(char *str) n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":N%s}", v->name); if (n < (int)sizeof(tmp)) { - cp = Var_Subst(NULL, tmp, VAR_GLOBAL, 0); + cp = Var_Subst(NULL, tmp, VAR_GLOBAL, FALSE, TRUE); Var_Set(MAKE_EXPORTED, cp, VAR_GLOBAL, 0); free(cp); } @@ -911,7 +912,7 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags) * point in searching them all just to save a bit of memory... */ if (strchr(name, '$') != NULL) { - expanded_name = Var_Subst(NULL, name, ctxt, 0); + expanded_name = Var_Subst(NULL, name, ctxt, FALSE, TRUE); if (expanded_name[0] == 0) { if (DEBUG(VAR)) { fprintf(debug_file, "Var_Set(\"%s\", \"%s\", ...) " @@ -982,8 +983,7 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags) out: - if (expanded_name != NULL) - free(expanded_name); + free(expanded_name); if (v != NULL) VarFreeEnv(v, TRUE); } @@ -1023,7 +1023,7 @@ Var_Append(const char *name, const char *val, GNode *ctxt) char *expanded_name = NULL; if (strchr(name, '$') != NULL) { - expanded_name = Var_Subst(NULL, name, ctxt, 0); + expanded_name = Var_Subst(NULL, name, ctxt, FALSE, TRUE); if (expanded_name[0] == 0) { if (DEBUG(VAR)) { fprintf(debug_file, "Var_Append(\"%s\", \"%s\", ...) " @@ -1061,8 +1061,7 @@ Var_Append(const char *name, const char *val, GNode *ctxt) Hash_SetValue(h, v); } } - if (expanded_name != NULL) - free(expanded_name); + free(expanded_name); } /*- @@ -1089,12 +1088,10 @@ Var_Exists(const char *name, GNode *ctxt) char *cp; if ((cp = strchr(name, '$')) != NULL) { - cp = Var_Subst(NULL, name, ctxt, FALSE); + cp = Var_Subst(NULL, name, ctxt, FALSE, TRUE); } v = VarFind(cp ? cp : name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV); - if (cp != NULL) { - free(cp); - } + free(cp); if (v == NULL) { return(FALSE); } else { @@ -1389,7 +1386,7 @@ VarSYSVMatch(GNode *ctx, Var_Parse_State *vpstate, addSpace = TRUE; if ((ptr = Str_SYSVMatch(word, pat->lhs, &len)) != NULL) { - varexp = Var_Subst(NULL, pat->rhs, ctx, 0); + varexp = Var_Subst(NULL, pat->rhs, ctx, FALSE, TRUE); Str_SYSVSubst(buf, varexp, ptr, len); free(varexp); } else { @@ -1809,7 +1806,7 @@ VarLoopExpand(GNode *ctx MAKE_ATTR_UNUSED, if (word && *word) { Var_Set(loop->tvar, word, loop->ctxt, VAR_NO_EXPORT); - s = Var_Subst(NULL, loop->str, loop->ctxt, loop->errnum); + s = Var_Subst(NULL, loop->str, loop->ctxt, loop->errnum, TRUE); if (s != NULL && *s != '\0') { if (addSpace && *s != '\n') Buf_AddByte(buf, ' '); @@ -2190,10 +2187,9 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED, * delimiter, assume it's a variable * substitution and recurse. */ - cp2 = Var_Parse(cp, ctxt, errnum, &len, &freeIt); + cp2 = Var_Parse(cp, ctxt, errnum, TRUE, &len, &freeIt); Buf_AddBytes(&buf, strlen(cp2), cp2); - if (freeIt) - free(freeIt); + free(freeIt); cp += len - 1; } else { const char *cp2 = &cp[1]; @@ -2246,7 +2242,7 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED, /*- *----------------------------------------------------------------------- * VarQuote -- - * Quote shell meta-characters in the string + * Quote shell meta-characters and space characters in the string * * Results: * The quoted string @@ -2261,29 +2257,25 @@ VarQuote(char *str) { Buffer buf; - /* This should cover most shells :-( */ - static const char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~"; const char *newline; - size_t len, nlen; + size_t nlen; if ((newline = Shell_GetNewline()) == NULL) newline = "\\\n"; nlen = strlen(newline); Buf_Init(&buf, 0); - while (*str != '\0') { - if ((len = strcspn(str, meta)) != 0) { - Buf_AddBytes(&buf, len, str); - str += len; - } else if (*str == '\n') { + + for (; *str != '\0'; str++) { + if (*str == '\n') { Buf_AddBytes(&buf, nlen, newline); - ++str; - } else { - Buf_AddByte(&buf, '\\'); - Buf_AddByte(&buf, *str); - ++str; + continue; } + if (isspace((unsigned char)*str) || ismeta((unsigned char)*str)) + Buf_AddByte(&buf, '\\'); + Buf_AddByte(&buf, *str); } + str = Buf_Destroy(&buf, FALSE); if (DEBUG(VAR)) fprintf(debug_file, "QuoteMeta: [%s]\n", str); @@ -2468,7 +2460,7 @@ VarStrftime(const char *fmt, int zulu) static char * ApplyModifiers(char *nstr, const char *tstr, int startc, int endc, - Var *v, GNode *ctxt, Boolean errnum, + Var *v, GNode *ctxt, Boolean errnum, Boolean wantit, int *lengthPtr, void **freePtr) { const char *start; @@ -2499,7 +2491,7 @@ ApplyModifiers(char *nstr, const char *tstr, int rlen; int c; - rval = Var_Parse(tstr, ctxt, errnum, &rlen, &freeIt); + rval = Var_Parse(tstr, ctxt, errnum, wantit, &rlen, &freeIt); /* * If we have not parsed up to endc or ':', @@ -2509,8 +2501,7 @@ ApplyModifiers(char *nstr, const char *tstr, (c = tstr[rlen]) != '\0' && c != ':' && c != endc) { - if (freeIt) - free(freeIt); + free(freeIt); goto apply_mods; } @@ -2526,17 +2517,15 @@ ApplyModifiers(char *nstr, const char *tstr, nstr = ApplyModifiers(nstr, rval, 0, 0, - v, ctxt, errnum, &used, freePtr); + v, ctxt, errnum, wantit, &used, freePtr); if (nstr == var_Error || (nstr == varNoError && errnum == 0) || strlen(rval) != (size_t) used) { - if (freeIt) - free(freeIt); + free(freeIt); goto out; /* error already reported */ } } - if (freeIt) - free(freeIt); + free(freeIt); if (*tstr == ':') tstr++; else if (!*tstr && endc) { @@ -2565,6 +2554,7 @@ ApplyModifiers(char *nstr, const char *tstr, char *sv_name; VarPattern pattern; int how; + int flags; if (v->name[0] == 0) goto bad_modifier; @@ -2600,8 +2590,9 @@ ApplyModifiers(char *nstr, const char *tstr, delim = startc == PROPEN ? PRCLOSE : BRCLOSE; pattern.flags = 0; + flags = (wantit) ? 0 : VAR_NOSUBST; pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum, - &cp, delim, NULL, + &cp, delim, &flags, &pattern.rightLen, NULL); if (v->flags & VAR_JUNK) { @@ -2615,26 +2606,27 @@ ApplyModifiers(char *nstr, const char *tstr, termc = *--cp; delim = '\0'; - switch (how) { - case '+': - Var_Append(v->name, pattern.rhs, v_ctxt); - break; - case '!': - newStr = Cmd_Exec(pattern.rhs, &emsg); - if (emsg) - Error(emsg, nstr); - else - Var_Set(v->name, newStr, v_ctxt, 0); - if (newStr) + if (wantit) { + switch (how) { + case '+': + Var_Append(v->name, pattern.rhs, v_ctxt); + break; + case '!': + newStr = Cmd_Exec(pattern.rhs, &emsg); + if (emsg) + Error(emsg, nstr); + else + Var_Set(v->name, newStr, v_ctxt, 0); free(newStr); - break; - case '?': - if ((v->flags & VAR_JUNK) == 0) break; - /* FALLTHROUGH */ - default: - Var_Set(v->name, pattern.rhs, v_ctxt, 0); - break; + case '?': + if ((v->flags & VAR_JUNK) == 0) + break; + /* FALLTHROUGH */ + default: + Var_Set(v->name, pattern.rhs, v_ctxt, 0); + break; + } } free(UNCONST(pattern.rhs)); newStr = varNoError; @@ -2676,8 +2668,15 @@ ApplyModifiers(char *nstr, const char *tstr, case 'U': { Buffer buf; /* Buffer for patterns */ - int wantit; /* want data in buffer */ + int wantit_; /* want data in buffer */ + if (wantit) { + if (*tstr == 'U') + wantit_ = ((v->flags & VAR_JUNK) != 0); + else + wantit_ = ((v->flags & VAR_JUNK) == 0); + } else + wantit_ = wantit; /* * Pass through tstr looking for 1) escaped delimiters, * '$'s and backslashes (place the escaped character in @@ -2706,10 +2705,9 @@ ApplyModifiers(char *nstr, const char *tstr, int len; void *freeIt; - cp2 = Var_Parse(cp, ctxt, errnum, &len, &freeIt); + cp2 = Var_Parse(cp, ctxt, errnum, wantit_, &len, &freeIt); Buf_AddBytes(&buf, strlen(cp2), cp2); - if (freeIt) - free(freeIt); + free(freeIt); cp += len - 1; } else { Buf_AddByte(&buf, *cp); @@ -2718,13 +2716,9 @@ ApplyModifiers(char *nstr, const char *tstr, termc = *cp; - if (*tstr == 'U') - wantit = ((v->flags & VAR_JUNK) != 0); - else - wantit = ((v->flags & VAR_JUNK) == 0); if ((v->flags & VAR_JUNK) != 0) v->flags |= VAR_KEEP; - if (wantit) { + if (wantit_) { newStr = Buf_Destroy(&buf, FALSE); } else { newStr = nstr; @@ -2769,14 +2763,17 @@ ApplyModifiers(char *nstr, const char *tstr, pattern.flags = 0; delim = '!'; - + emsg = NULL; cp = ++tstr; if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum, &cp, delim, NULL, &pattern.rightLen, NULL)) == NULL) goto cleanup; - newStr = Cmd_Exec(pattern.rhs, &emsg); + if (wantit) + newStr = Cmd_Exec(pattern.rhs, &emsg); + else + newStr = varNoError; free(UNCONST(pattern.rhs)); if (emsg) Error(emsg, nstr); @@ -3152,7 +3149,7 @@ ApplyModifiers(char *nstr, const char *tstr, * expand it. */ cp2 = pattern; - pattern = Var_Subst(NULL, cp2, ctxt, errnum); + pattern = Var_Subst(NULL, cp2, ctxt, errnum, TRUE); free(cp2); } if (DEBUG(VAR)) @@ -3238,15 +3235,32 @@ ApplyModifiers(char *nstr, const char *tstr, { VarPattern pattern; Boolean value; - + int cond_rc; + int lhs_flags, rhs_flags; + /* find ':', and then substitute accordingly */ - + if (wantit) { + cond_rc = Cond_EvalExpression(NULL, v->name, &value, 0, FALSE); + if (cond_rc == COND_INVALID) { + lhs_flags = rhs_flags = VAR_NOSUBST; + } else if (value) { + lhs_flags = 0; + rhs_flags = VAR_NOSUBST; + } else { + lhs_flags = VAR_NOSUBST; + rhs_flags = 0; + } + } else { + /* we are just consuming and discarding */ + cond_rc = value = 0; + lhs_flags = rhs_flags = VAR_NOSUBST; + } pattern.flags = 0; cp = ++tstr; delim = ':'; if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, errnum, - &cp, delim, NULL, + &cp, delim, &lhs_flags, &pattern.leftLen, NULL)) == NULL) goto cleanup; @@ -3254,15 +3268,14 @@ ApplyModifiers(char *nstr, const char *tstr, /* BROPEN or PROPEN */ delim = endc; if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, errnum, - &cp, delim, NULL, + &cp, delim, &rhs_flags, &pattern.rightLen, NULL)) == NULL) goto cleanup; termc = *--cp; delim = '\0'; - if (Cond_EvalExpression(NULL, v->name, &value, 0, FALSE) - == COND_INVALID) { + if (cond_rc == COND_INVALID) { Error("Bad conditional expression `%s' in %s?%s:%s", v->name, v->name, pattern.lhs, pattern.rhs); goto cleanup; @@ -3424,9 +3437,12 @@ ApplyModifiers(char *nstr, const char *tstr, case 's': if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) { const char *emsg; - newStr = Cmd_Exec(nstr, &emsg); - if (emsg) - Error(emsg, nstr); + if (wantit) { + newStr = Cmd_Exec(nstr, &emsg); + if (emsg) + Error(emsg, nstr); + } else + newStr = varNoError; cp = tstr + 2; termc = *cp; break; @@ -3547,10 +3563,8 @@ ApplyModifiers(char *nstr, const char *tstr, if (delim != '\0') Error("Unclosed substitution for %s (%c missing)", v->name, delim); - if (*freePtr) { - free(*freePtr); - *freePtr = NULL; - } + free(*freePtr); + *freePtr = NULL; return (var_Error); } @@ -3565,6 +3579,7 @@ ApplyModifiers(char *nstr, const char *tstr, * str The string to parse * ctxt The context for the variable * errnum TRUE if undefined variables are an error + * wantit TRUE if we actually want the result * lengthPtr OUT: The length of the specification * freePtr OUT: Non-NULL if caller should free *freePtr * @@ -3583,8 +3598,9 @@ ApplyModifiers(char *nstr, const char *tstr, */ /* coverity[+alloc : arg-*4] */ char * -Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr, - void **freePtr) +Var_Parse(const char *str, GNode *ctxt, + Boolean errnum, Boolean wantit, + int *lengthPtr, void **freePtr) { const char *tstr; /* Pointer into str */ Var *v; /* Variable in invocation */ @@ -3689,12 +3705,11 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr, if (*tstr == '$') { int rlen; void *freeIt; - char *rval = Var_Parse(tstr, ctxt, errnum, &rlen, &freeIt); + char *rval = Var_Parse(tstr, ctxt, errnum, wantit, &rlen, &freeIt); if (rval != NULL) { Buf_AddBytes(&buf, strlen(rval), rval); } - if (freeIt) - free(freeIt); + free(freeIt); tstr += rlen - 1; } else @@ -3837,7 +3852,7 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr, */ nstr = Buf_GetAll(&v->val, NULL); if (strchr(nstr, '$') != NULL) { - nstr = Var_Subst(NULL, nstr, ctxt, errnum); + nstr = Var_Subst(NULL, nstr, ctxt, errnum, wantit); *freePtr = nstr; } @@ -3850,7 +3865,7 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr, extraFree = NULL; if (extramodifiers != NULL) { nstr = ApplyModifiers(nstr, extramodifiers, '(', ')', - v, ctxt, errnum, &used, &extraFree); + v, ctxt, errnum, wantit, &used, &extraFree); } if (haveModifier) { @@ -3858,11 +3873,9 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr, tstr++; nstr = ApplyModifiers(nstr, tstr, startc, endc, - v, ctxt, errnum, &used, freePtr); + v, ctxt, errnum, wantit, &used, freePtr); tstr += used; - if (extraFree) { - free(extraFree); - } + free(extraFree); } else { *freePtr = extraFree; } @@ -3924,6 +3937,7 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr, * str the string which to substitute * ctxt the context wherein to find variables * undefErr TRUE if undefineds are an error + * wantit TRUE if we actually want the result * * Results: * The resulting string. @@ -3933,7 +3947,8 @@ Var_Parse(const char *str, GNode *ctxt, Boolean errnum, int *lengthPtr, *----------------------------------------------------------------------- */ char * -Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr) +Var_Subst(const char *var, const char *str, GNode *ctxt, + Boolean undefErr, Boolean wantit) { Buffer buf; /* Buffer for forming things */ char *val; /* Value to substitute for a variable */ @@ -4031,7 +4046,7 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr) continue; } - val = Var_Parse(str, ctxt, undefErr, &length, &freeIt); + val = Var_Parse(str, ctxt, undefErr, wantit, &length, &freeIt); /* * When we come down here, val should either point to the @@ -4079,10 +4094,8 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, Boolean undefErr) Buf_AddBytes(&buf, length, val); trailingBslash = length > 0 && val[length - 1] == '\\'; } - if (freeIt) { - free(freeIt); - freeIt = NULL; - } + free(freeIt); + freeIt = NULL; } } |