Convert Var_Parse to a wrapper function.

Reduce the number of arguments passed between these functions by
creating a special-purpose struct.

Patch:		7.120,7.121

Submitted by:	Max Okumoto <okumoto@ucsd.edu>
This commit is contained in:
harti 2005-03-18 15:34:07 +00:00
parent 5b2a5b84de
commit f00fcf68ef

View File

@ -100,6 +100,16 @@ __FBSDID("$FreeBSD$");
#include "util.h" #include "util.h"
#include "var.h" #include "var.h"
/**
*
*/
typedef struct VarParser {
const char *const input; /* pointer to input string */
GNode *ctxt;
Boolean err;
} VarParser;
static char *VarParse(const char [], VarParser *, size_t *, Boolean *);
/* /*
* This is a harmless return value for Var_Parse that can be used by Var_Subst * This is a harmless return value for Var_Parse that can be used by Var_Subst
* to determine if there was an error in parsing -- easier than returning * to determine if there was an error in parsing -- easier than returning
@ -689,7 +699,7 @@ SortIncreasing(const void *l, const void *r)
*----------------------------------------------------------------------- *-----------------------------------------------------------------------
*/ */
static char * static char *
VarGetPattern(GNode *ctxt, int err, const char **tstr, int delim, int *flags, VarGetPattern(VarParser *vp, const char **tstr, int delim, int *flags,
size_t *length, VarPattern *pattern) size_t *length, VarPattern *pattern)
{ {
const char *cp; const char *cp;
@ -735,7 +745,7 @@ VarGetPattern(GNode *ctxt, int err, const char **tstr, int delim, int *flags,
* substitution and recurse. * substitution and recurse.
*/ */
len = 0; len = 0;
cp2 = Var_Parse(cp, ctxt, err, &len, &freeIt); cp2 = Var_Parse(cp, vp->ctxt, vp->err, &len, &freeIt);
Buf_Append(buf, cp2); Buf_Append(buf, cp2);
if (freeIt) if (freeIt)
free(cp2); free(cp2);
@ -849,11 +859,11 @@ VarREError(int err, regex_t *pat, const char *str)
free(errbuf); free(errbuf);
} }
/* /**
* Make sure this variable is fully expanded. * Make sure this variable is fully expanded.
*/ */
static char * static char *
VarExpand(Var *v, GNode *ctxt, Boolean err) VarExpand(Var *v, VarParser *vp)
{ {
char *value; char *value;
char *result; char *result;
@ -881,7 +891,7 @@ VarExpand(Var *v, GNode *ctxt, Boolean err)
} else { } else {
Buffer *buf; Buffer *buf;
buf = Var_Subst(NULL, value, ctxt, err); buf = Var_Subst(NULL, value, vp->ctxt, vp->err);
result = Buf_GetAll(buf, NULL); result = Buf_GetAll(buf, NULL);
Buf_Destroy(buf, FALSE); Buf_Destroy(buf, FALSE);
} }
@ -939,7 +949,7 @@ modifier_M(const char mod[], const char value[], char endc, size_t *consumed)
} }
static char * static char *
modifier_S(const char mod[], const char value[], Var *v, GNode *ctxt, Boolean err, size_t *consumed) modifier_S(const char mod[], const char value[], Var *v, VarParser *vp, size_t *consumed)
{ {
VarPattern pattern; VarPattern pattern;
Buffer *buf; /* Buffer for patterns */ Buffer *buf; /* Buffer for patterns */
@ -1004,7 +1014,7 @@ modifier_S(const char mod[], const char value[], Var *v, GNode *ctxt, Boolean er
Boolean freeIt; Boolean freeIt;
len = 0; len = 0;
cp2 = Var_Parse(cur, ctxt, err, &len, &freeIt); cp2 = Var_Parse(cur, vp->ctxt, vp->err, &len, &freeIt);
cur += len; cur += len;
Buf_Append(buf, cp2); Buf_Append(buf, cp2);
if (freeIt) { if (freeIt) {
@ -1061,7 +1071,7 @@ modifier_S(const char mod[], const char value[], Var *v, GNode *ctxt, Boolean er
Boolean freeIt; Boolean freeIt;
len = 0; len = 0;
cp2 = Var_Parse(cur, ctxt, err, &len, &freeIt); cp2 = Var_Parse(cur, vp->ctxt, vp->err, &len, &freeIt);
cur += len; cur += len;
Buf_Append(buf, cp2); Buf_Append(buf, cp2);
if (freeIt) { if (freeIt) {
@ -1145,13 +1155,13 @@ modifier_S(const char mod[], const char value[], Var *v, GNode *ctxt, Boolean er
static char * static char *
ParseModifier(const char input[], const char tstr[], ParseModifier(const char input[], const char tstr[],
char startc, char endc, Boolean dynamic, Var *v, char startc, char endc, Boolean dynamic, Var *v,
GNode *ctxt, Boolean err, size_t *lengthPtr, Boolean *freePtr) VarParser *vp, size_t *lengthPtr, Boolean *freePtr)
{ {
char *value; char *value;
const char *cp; const char *cp;
size_t used; size_t used;
value = VarExpand(v, ctxt, err); value = VarExpand(v, vp);
*freePtr = TRUE; *freePtr = TRUE;
tstr++; tstr++;
@ -1174,7 +1184,7 @@ ParseModifier(const char input[], const char tstr[],
readonly = TRUE; /* tstr isn't modified here */ readonly = TRUE; /* tstr isn't modified here */
newStr = modifier_S(tstr, value, v, ctxt, err, &consumed); newStr = modifier_S(tstr, value, v, vp, &consumed);
tstr += consumed; tstr += consumed;
break; break;
case 'C': case 'C':
@ -1190,7 +1200,7 @@ ParseModifier(const char input[], const char tstr[],
cp = tstr; cp = tstr;
if ((re = VarGetPattern(ctxt, err, &cp, delim, NULL, if ((re = VarGetPattern(vp, &cp, delim, NULL,
NULL, NULL)) == NULL) { NULL, NULL)) == NULL) {
*lengthPtr = cp - input + 1; *lengthPtr = cp - input + 1;
if (*freePtr) if (*freePtr)
@ -1201,7 +1211,7 @@ ParseModifier(const char input[], const char tstr[],
return (var_Error); return (var_Error);
} }
if ((pattern.replace = VarGetPattern(ctxt, err, &cp, if ((pattern.replace = VarGetPattern(vp, &cp,
delim, NULL, NULL, NULL)) == NULL){ delim, NULL, NULL, NULL)) == NULL){
free(re); free(re);
@ -1393,8 +1403,8 @@ ParseModifier(const char input[], const char tstr[],
cp = tstr; cp = tstr;
delim = '='; delim = '=';
if ((pattern.lhs = VarGetPattern(ctxt, if ((pattern.lhs = VarGetPattern(vp,
err, &cp, delim, &pattern.flags, &pattern.leftLen, &cp, delim, &pattern.flags, &pattern.leftLen,
NULL)) == NULL) { NULL)) == NULL) {
/* was: goto cleanup */ /* was: goto cleanup */
*lengthPtr = cp - input + 1; *lengthPtr = cp - input + 1;
@ -1407,8 +1417,8 @@ ParseModifier(const char input[], const char tstr[],
} }
delim = endc; delim = endc;
if ((pattern.rhs = VarGetPattern(ctxt, if ((pattern.rhs = VarGetPattern(vp,
err, &cp, delim, NULL, &pattern.rightLen, &cp, delim, NULL, &pattern.rightLen,
&pattern)) == NULL) { &pattern)) == NULL) {
/* was: goto cleanup */ /* was: goto cleanup */
*lengthPtr = cp - input + 1; *lengthPtr = cp - input + 1;
@ -1504,7 +1514,7 @@ ParseModifier(const char input[], const char tstr[],
VarDestroy(v, TRUE); VarDestroy(v, TRUE);
*freePtr = FALSE; *freePtr = FALSE;
return (err ? var_Error : varNoError); return (vp->err ? var_Error : varNoError);
} }
} else { } else {
return (value); return (value);
@ -1512,7 +1522,7 @@ ParseModifier(const char input[], const char tstr[],
} }
static char * static char *
ParseRestModifier(const char input[], const char ptr[], char startc, char endc, Buffer *buf, GNode *ctxt, Boolean err, size_t *lengthPtr, Boolean *freePtr) ParseRestModifier(const char input[], const char ptr[], char startc, char endc, Buffer *buf, VarParser *vp, size_t *lengthPtr, Boolean *freePtr)
{ {
const char *vname; const char *vname;
size_t vlen; size_t vlen;
@ -1526,14 +1536,14 @@ ParseRestModifier(const char input[], const char ptr[], char startc, char endc,
dynamic = FALSE; dynamic = FALSE;
v = VarFind(vname, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD); v = VarFind(vname, vp->ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
if (v != NULL) { if (v != NULL) {
return (ParseModifier(input, ptr, return (ParseModifier(input, ptr,
startc, endc, dynamic, v, startc, endc, dynamic, v,
ctxt, err, lengthPtr, freePtr)); vp, lengthPtr, freePtr));
} }
if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) { if ((vp->ctxt == VAR_CMD) || (vp->ctxt == VAR_GLOBAL)) {
if ((vlen == 1) || if ((vlen == 1) ||
((vlen == 2) && (vname[1] == 'F' || vname[1] == 'D'))) { ((vlen == 2) && (vname[1] == 'F' || vname[1] == 'D'))) {
/* /*
@ -1568,7 +1578,7 @@ ParseRestModifier(const char input[], const char ptr[], char startc, char endc,
v = VarCreate(vname, NULL, VAR_JUNK); v = VarCreate(vname, NULL, VAR_JUNK);
return (ParseModifier(input, ptr, return (ParseModifier(input, ptr,
startc, endc, dynamic, v, startc, endc, dynamic, v,
ctxt, err, lengthPtr, freePtr)); vp, lengthPtr, freePtr));
} else { } else {
/* /*
* Check for D and F forms of local variables since we're in * Check for D and F forms of local variables since we're in
@ -1585,11 +1595,11 @@ ParseRestModifier(const char input[], const char ptr[], char startc, char endc,
name[0] = vname[0]; name[0] = vname[0];
name[1] = '\0'; name[1] = '\0';
v = VarFind(name, ctxt, 0); v = VarFind(name, vp->ctxt, 0);
if (v != NULL) { if (v != NULL) {
return (ParseModifier(input, ptr, return (ParseModifier(input, ptr,
startc, endc, dynamic, v, startc, endc, dynamic, v,
ctxt, err, lengthPtr, freePtr)); vp, lengthPtr, freePtr));
} }
} }
@ -1601,13 +1611,13 @@ ParseRestModifier(const char input[], const char ptr[], char startc, char endc,
v = VarCreate(vname, NULL, VAR_JUNK); v = VarCreate(vname, NULL, VAR_JUNK);
return (ParseModifier(input, ptr, return (ParseModifier(input, ptr,
startc, endc, dynamic, v, startc, endc, dynamic, v,
ctxt, err, lengthPtr, freePtr)); vp, lengthPtr, freePtr));
} }
} }
static char * static char *
ParseRestEnd(const char input[], Buffer *buf, ParseRestEnd(const char input[], Buffer *buf,
GNode *ctxt, Boolean err, size_t *consumed, Boolean *freePtr) VarParser *vp, size_t *consumed, Boolean *freePtr)
{ {
const char *vname; const char *vname;
size_t vlen; size_t vlen;
@ -1616,9 +1626,9 @@ ParseRestEnd(const char input[], Buffer *buf,
vname = Buf_GetAll(buf, &vlen); vname = Buf_GetAll(buf, &vlen);
v = VarFind(vname, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD); v = VarFind(vname, vp->ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
if (v != NULL) { if (v != NULL) {
value = VarExpand(v, ctxt, err); value = VarExpand(v, vp);
if (v->flags & VAR_FROM_ENV) { if (v->flags & VAR_FROM_ENV) {
VarDestroy(v, TRUE); VarDestroy(v, TRUE);
@ -1628,7 +1638,7 @@ ParseRestEnd(const char input[], Buffer *buf,
return (value); return (value);
} }
if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) { if ((vp->ctxt == VAR_CMD) || (vp->ctxt == VAR_GLOBAL)) {
/* /*
* If substituting a local variable in a non-local * If substituting a local variable in a non-local
* context, assume it's for dynamic source stuff. We * context, assume it's for dynamic source stuff. We
@ -1667,7 +1677,7 @@ ParseRestEnd(const char input[], Buffer *buf,
} }
*freePtr = FALSE; *freePtr = FALSE;
return (err ? var_Error : varNoError); return (vp->err ? var_Error : varNoError);
} else { } else {
/* /*
* Check for D and F forms of local variables since we're in * Check for D and F forms of local variables since we're in
@ -1681,7 +1691,7 @@ ParseRestEnd(const char input[], Buffer *buf,
name[0] = vname[0]; name[0] = vname[0];
name[1] = '\0'; name[1] = '\0';
v = VarFind(name, ctxt, 0); v = VarFind(name, vp->ctxt, 0);
if (v != NULL) { if (v != NULL) {
char *val; char *val;
/* /*
@ -1705,7 +1715,7 @@ ParseRestEnd(const char input[], Buffer *buf,
} }
*freePtr = FALSE; *freePtr = FALSE;
return (err ? var_Error : varNoError); return (vp->err ? var_Error : varNoError);
} }
} }
@ -1713,7 +1723,7 @@ ParseRestEnd(const char input[], Buffer *buf,
* Parse a multi letter variable name, and return it's value. * Parse a multi letter variable name, and return it's value.
*/ */
static char * static char *
VarParseLong(const char input[], GNode *ctxt, Boolean err, VarParseLong(const char input[], VarParser *vp,
size_t *consumed, Boolean *freePtr) size_t *consumed, Boolean *freePtr)
{ {
Buffer *buf; Buffer *buf;
@ -1750,7 +1760,7 @@ VarParseLong(const char input[], GNode *ctxt, Boolean err,
} else if (*ptr == ':') { } else if (*ptr == ':') {
result = ParseRestModifier(input - 2, ptr, result = ParseRestModifier(input - 2, ptr,
startc, endc, buf, startc, endc, buf,
ctxt, err, consumed, freePtr); vp, consumed, freePtr);
Buf_Destroy(buf, TRUE); Buf_Destroy(buf, TRUE);
return (result); return (result);
@ -1760,7 +1770,7 @@ VarParseLong(const char input[], GNode *ctxt, Boolean err,
char *rval; char *rval;
rlen = 0; rlen = 0;
rval = Var_Parse(ptr, ctxt, err, &rlen, &rfree); rval = Var_Parse(ptr, vp->ctxt, vp->err, &rlen, &rfree);
if (rval == var_Error) { if (rval == var_Error) {
Fatal("Error expanding embedded variable."); Fatal("Error expanding embedded variable.");
} }
@ -1779,7 +1789,7 @@ VarParseLong(const char input[], GNode *ctxt, Boolean err,
*consumed += 1; /* consume closing paren or brace */ *consumed += 1; /* consume closing paren or brace */
result = ParseRestEnd(input - 2, buf, ctxt, err, consumed, freePtr); result = ParseRestEnd(input - 2, buf, vp, consumed, freePtr);
Buf_Destroy(buf, TRUE); Buf_Destroy(buf, TRUE);
return (result); return (result);
@ -1789,7 +1799,7 @@ VarParseLong(const char input[], GNode *ctxt, Boolean err,
* Parse a single letter variable name, and return it's value. * Parse a single letter variable name, and return it's value.
*/ */
static char * static char *
VarParseShort(const char input[], GNode *ctxt, Boolean err, VarParseShort(const char input[], VarParser *vp,
size_t *consumed, Boolean *freeResult) size_t *consumed, Boolean *freeResult)
{ {
char vname[2]; char vname[2];
@ -1801,9 +1811,9 @@ VarParseShort(const char input[], GNode *ctxt, Boolean err,
*consumed += 1; /* consume single letter */ *consumed += 1; /* consume single letter */
v = VarFind(vname, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD); v = VarFind(vname, vp->ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
if (v != NULL) { if (v != NULL) {
value = VarExpand(v, ctxt, err); value = VarExpand(v, vp);
if (v->flags & VAR_FROM_ENV) { if (v->flags & VAR_FROM_ENV) {
VarDestroy(v, TRUE); VarDestroy(v, TRUE);
@ -1821,7 +1831,7 @@ VarParseShort(const char input[], GNode *ctxt, Boolean err,
* variables are treated specially as they are the only four that * variables are treated specially as they are the only four that
* will be set when dynamic sources are expanded. * will be set when dynamic sources are expanded.
*/ */
if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) { if ((vp->ctxt == VAR_CMD) || (vp->ctxt == VAR_GLOBAL)) {
/* XXX: It looks like $% and $! are reversed here */ /* XXX: It looks like $% and $! are reversed here */
switch (vname[0]) { switch (vname[0]) {
@ -1839,7 +1849,7 @@ VarParseShort(const char input[], GNode *ctxt, Boolean err,
return (estrdup("$(.MEMBER)")); return (estrdup("$(.MEMBER)"));
default: default:
*freeResult = FALSE; *freeResult = FALSE;
return (err ? var_Error : varNoError); return (vp->err ? var_Error : varNoError);
} }
} }
@ -1847,7 +1857,30 @@ VarParseShort(const char input[], GNode *ctxt, Boolean err,
* Variable name was not found. * Variable name was not found.
*/ */
*freeResult = FALSE; *freeResult = FALSE;
return (err ? var_Error : varNoError); return (vp->err ? var_Error : varNoError);
}
static char *
VarParse(const char input[], VarParser *vp, size_t *consumed, Boolean *freeResult)
{
/* assert(input[0] == '$'); */
*consumed += 1; /* consume '$' */
input += 1;
if (input[0] == '\0') {
/* Error, there is only a dollar sign in the input string. */
*freeResult = FALSE;
return (vp->err ? var_Error : varNoError);
} else if (input[0] == OPEN_PAREN || input[0] == OPEN_BRACE) {
/* multi letter variable name */
return (VarParseLong(input, vp, consumed, freeResult));
} else {
/* single letter variable name */
return (VarParseShort(input, vp, consumed, freeResult));
}
} }
/*- /*-
@ -1878,24 +1911,13 @@ char *
Var_Parse(const char input[], GNode *ctxt, Boolean err, Var_Parse(const char input[], GNode *ctxt, Boolean err,
size_t *consumed, Boolean *freeResult) size_t *consumed, Boolean *freeResult)
{ {
/* assert(input[0] == '$'); */ VarParser vp = {
input,
ctxt,
err
};
*consumed += 1; /* consume '$' */ return VarParse(input, &vp, consumed, freeResult);
input += 1;
if (input[0] == '\0') {
/* Error, there is only a dollar sign in the input string. */
*freeResult = FALSE;
return (err ? var_Error : varNoError);
} else if (input[0] == OPEN_PAREN || input[0] == OPEN_BRACE) {
/* multi letter variable name */
return (VarParseLong(input, ctxt, err, consumed, freeResult));
} else {
/* single letter variable name */
return (VarParseShort(input, ctxt, err, consumed, freeResult));
}
} }
/*- /*-