1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-13 10:02:38 +00:00

Remove a temporary variable. Rename pattern to patt to be consistent.

Remove unreachable code for VAR_NOSUBST - it was never set.
Replace redundant code with calls to VarGetPattern().

Patch:		7.143-7.145

Submitted by:	Max Okumoto <okumoto@ucsd.edu>
This commit is contained in:
Hartmut Brandt 2005-03-22 07:38:46 +00:00
parent 3eea66586b
commit cffe7fcdef
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=143955
2 changed files with 93 additions and 218 deletions

View File

@ -677,8 +677,7 @@ SortIncreasing(const void *l, const void *r)
* Pass through the tstr looking for 1) escaped delimiters,
* '$'s and backslashes (place the escaped character in
* uninterpreted) and 2) unescaped $'s that aren't before
* the delimiter (expand the variable substitution unless flags
* has VAR_NOSUBST set).
* the delimiter (expand the variable substitution).
* Return the expanded string or NULL if the delimiter was missing
* If pattern is specified, handle escaped ampersands, and replace
* unescaped ampersands with the lhs of the pattern.
@ -694,108 +693,80 @@ SortIncreasing(const void *l, const void *r)
*-----------------------------------------------------------------------
*/
static char *
VarGetPattern(VarParser *vp, const char **tstr, int delim, int *flags,
size_t *length, VarPattern *pattern)
VarGetPattern(VarParser *vp, int delim, int *flags,
size_t *length, VarPattern *patt)
{
const char *cp;
Buffer *buf = Buf_Init(0);
size_t junk;
Buffer *buf;
if (length == NULL)
length = &junk;
#define IS_A_MATCH(cp, delim) \
((cp[0] == '\\') && ((cp[1] == delim) || \
(cp[1] == '\\') || (cp[1] == '$') || (pattern && (cp[1] == '&'))))
buf = Buf_Init(0);
/*
* Skim through until the matching delimiter is found; pick up
* variable substitutions on the way. Also allow backslashes to quote
* the delimiter, $, and \, but don't touch other backslashes.
*/
for (cp = *tstr; *cp && (*cp != delim); cp++) {
if (IS_A_MATCH(cp, delim)) {
Buf_AddByte(buf, (Byte)cp[1]);
cp++;
} else if (*cp == '$') {
if (cp[1] == delim) {
if (flags == NULL)
Buf_AddByte(buf, (Byte)*cp);
else
while (*vp->ptr != '\0') {
if (*vp->ptr == delim) {
char *result;
result = (char *)Buf_GetAll(buf, length);
Buf_Destroy(buf, FALSE);
return (result);
} else if ((vp->ptr[0] == '\\') &&
((vp->ptr[1] == delim) ||
(vp->ptr[1] == '\\') ||
(vp->ptr[1] == '$') ||
(vp->ptr[1] == '&' && patt != NULL))) {
vp->ptr++; /* consume backslash */
Buf_AddByte(buf, (Byte)vp->ptr[0]);
vp->ptr++;
} else if (vp->ptr[0] == '$') {
if (vp->ptr[1] == delim) {
if (flags == NULL) {
Buf_AddByte(buf, (Byte)vp->ptr[0]);
vp->ptr++;
} else {
/*
* Unescaped $ at end of pattern =>
* anchor pattern at end.
* Unescaped $ at end of patt =>
* anchor patt at end.
*/
*flags |= VAR_MATCH_END;
} else {
if (flags == NULL ||
(*flags & VAR_NOSUBST) == 0) {
char *cp2;
size_t len;
Boolean freeIt;
/*
* If unescaped dollar sign not
* before the delimiter, assume it's
* a variable substitution and
* recurse.
*/
len = 0;
cp2 = Var_Parse(cp, vp->ctxt, vp->err, &len, &freeIt);
Buf_Append(buf, cp2);
if (freeIt)
free(cp2);
cp += len - 1;
} else {
const char *cp2 = &cp[1];
if (*cp2 == OPEN_PAREN ||
*cp2 == OPEN_BRACE) {
/*
* Find the end of this
* variable reference and
* suck it in without further
* ado. It will be
* interperated later.
*/
int have = *cp2;
int want = (*cp2 == OPEN_PAREN) ? CLOSE_PAREN : CLOSE_BRACE;
int depth = 1;
for (++cp2; *cp2 != '\0' && depth > 0; ++cp2) {
if (cp2[-1] != '\\') {
if (*cp2 == have)
++depth;
if (*cp2 == want)
--depth;
}
}
Buf_AppendRange(buf, cp, cp2);
cp = --cp2;
} else
Buf_AddByte(buf, (Byte)*cp);
vp->ptr++;
}
} else {
char *cp;
size_t len;
Boolean freeIt;
/*
* If unescaped dollar sign not
* before the delimiter, assume it's
* a variable substitution and
* recurse.
*/
len = 0;
cp = Var_Parse(vp->ptr, vp->ctxt, vp->err, &len, &freeIt);
Buf_Append(buf, cp);
if (freeIt)
free(cp);
vp->ptr += len;
}
} else if (pattern && *cp == '&')
Buf_AddBytes(buf, pattern->leftLen, (Byte *) pattern->lhs);
else
Buf_AddByte(buf, (Byte)*cp);
} else if (vp->ptr[0] == '&' && patt != NULL) {
Buf_AddBytes(buf, patt->leftLen, (Byte *)patt->lhs);
vp->ptr++;
} else {
Buf_AddByte(buf, (Byte)vp->ptr[0]);
vp->ptr++;
}
}
Buf_AddByte(buf, (Byte)'\0');
if (*cp != delim) {
*tstr = cp;
if (length != NULL) {
*length = 0;
return (NULL);
} else {
char *result;
*tstr = ++cp;
result = (char *)Buf_GetAll(buf, length);
*length -= 1; /* Don't count the NULL */
Buf_Destroy(buf, FALSE);
return (result);
}
Buf_Destroy(buf, TRUE);
return (NULL);
}
/*-
@ -951,13 +922,11 @@ modifier_M(VarParser *vp, const char value[], char endc)
static char *
modifier_S(VarParser *vp, const char value[], Var *v)
{
VarPattern pattern;
Buffer *buf; /* Buffer for patterns */
VarPattern patt;
char delim;
char *newValue;
pattern.flags = 0;
buf = Buf_Init(0);
patt.flags = 0;
vp->ptr++; /* consume 'S' */
@ -969,134 +938,38 @@ modifier_S(VarParser *vp, const char value[], Var *v)
* word -- skip over it and flag pattern.
*/
if (*vp->ptr == '^') {
pattern.flags |= VAR_MATCH_START;
patt.flags |= VAR_MATCH_START;
vp->ptr++;
}
/*
* Pass through the lhs looking for 1) escaped delimiters, '$'s and
* backslashes (place the escaped character in uninterpreted) and 2)
* unescaped $'s that aren't before the delimiter (expand the
* variable substitution). The result is left in the Buffer buf.
*/
while (vp->ptr[0] != delim) {
if (vp->ptr[0] == '\0') {
/*
* LHS didn't end with the delim, complain and exit.
*/
Fatal("Unclosed substitution for %s (%c missing)",
v->name, delim);
} else if ((vp->ptr[0] == '\\') &&
((vp->ptr[1] == delim) ||
(vp->ptr[1] == '$') ||
(vp->ptr[1] == '\\'))) {
vp->ptr++; /* consume backslash */
Buf_AddByte(buf, (Byte)vp->ptr[0]);
vp->ptr++;
} else if (vp->ptr[0] == '$') {
if (vp->ptr[1] == delim) {
/*
* Unescaped $ at end of pattern => anchor
* pattern at end.
*/
pattern.flags |= VAR_MATCH_END;
vp->ptr++;
} else {
/*
* If unescaped dollar sign not before the
* delimiter, assume it's a variable
* substitution and recurse.
*/
char *cp2;
size_t len;
Boolean freeIt;
len = 0;
cp2 = Var_Parse(vp->ptr, vp->ctxt, vp->err, &len, &freeIt);
vp->ptr += len;
Buf_Append(buf, cp2);
if (freeIt) {
free(cp2);
}
}
} else {
Buf_AddByte(buf, (Byte)vp->ptr[0]);
vp->ptr++;
}
patt.lhs = VarGetPattern(vp, delim, &patt.flags, &patt.leftLen, NULL);
if (patt.lhs == NULL) {
/*
* LHS didn't end with the delim, complain and exit.
*/
Fatal("Unclosed substitution for %s (%c missing)",
v->name, delim);
}
vp->ptr++; /* consume 2nd delim */
/*
* Fetch pattern and destroy buffer, but preserve the data in it,
* since that's our lhs.
*/
pattern.lhs = (char *)Buf_GetAll(buf, &pattern.leftLen);
Buf_Destroy(buf, FALSE);
/*
* Now comes the replacement string. Three things need to be done
* here: 1) need to compress escaped delimiters and ampersands and 2)
* need to replace unescaped ampersands with the l.h.s. (since this
* isn't regexp, we can do it right here) and 3) expand any variable
* substitutions.
*/
buf = Buf_Init(0);
while (vp->ptr[0] != delim) {
if (vp->ptr[0] == '\0') {
/*
* Didn't end with delim character, complain
*/
Fatal("Unclosed substitution for %s (%c missing)",
v->name, delim);
} else if ((vp->ptr[0] == '\\') &&
((vp->ptr[1] == delim) ||
(vp->ptr[1] == '&') ||
(vp->ptr[1] == '\\') ||
(vp->ptr[1] == '$'))) {
vp->ptr++; /* skip backslash */
Buf_AddByte(buf, (Byte)vp->ptr[0]);
vp->ptr++;
} else if (vp->ptr[0] == '$') {
if (vp->ptr[1] == delim) {
Buf_AddByte(buf, (Byte)vp->ptr[0]);
vp->ptr++;
} else {
char *cp2;
size_t len;
Boolean freeIt;
len = 0;
cp2 = Var_Parse(vp->ptr, vp->ctxt, vp->err, &len, &freeIt);
vp->ptr += len;
Buf_Append(buf, cp2);
if (freeIt) {
free(cp2);
}
}
} else if (vp->ptr[0] == '&') {
Buf_AddBytes(buf, pattern.leftLen, (Byte *)pattern.lhs);
vp->ptr++;
} else {
Buf_AddByte(buf, (Byte)vp->ptr[0]);
vp->ptr++;
}
patt.rhs = VarGetPattern(vp, delim, NULL, &patt.rightLen, &patt);
if (patt.rhs == NULL) {
/*
* RHS didn't end with the delim, complain and exit.
*/
Fatal("Unclosed substitution for %s (%c missing)",
v->name, delim);
}
vp->ptr++; /* consume last delim */
pattern.rhs = (char *)Buf_GetAll(buf, &pattern.rightLen);
Buf_Destroy(buf, FALSE);
vp->ptr++; /* consume last delim */
/*
* Check for global substitution. If 'g' after the final delimiter,
* substitution is global and is marked that way.
*/
if (vp->ptr[0] == 'g') {
pattern.flags |= VAR_SUB_GLOBAL;
patt.flags |= VAR_SUB_GLOBAL;
vp->ptr++;
}
@ -1107,16 +980,16 @@ modifier_S(VarParser *vp, const char value[], Var *v)
* can only contain the 3 bits we're interested in so we don't have
* to mask unrelated bits. We can test for equality.
*/
if (!pattern.leftLen && pattern.flags == VAR_SUB_GLOBAL)
if (patt.leftLen == 0 && patt.flags == VAR_SUB_GLOBAL)
Fatal("Global substitution of the empty string");
newValue = VarModify(value, VarSubstitute, &pattern);
newValue = VarModify(value, VarSubstitute, &patt);
/*
* Free the two strings.
*/
free(pattern.lhs);
free(pattern.rhs);
free(patt.lhs);
free(patt.rhs);
return (newValue);
}
@ -1138,18 +1011,22 @@ modifier_C(VarParser *vp, char value[], Var *v)
vp->ptr++; /* consume 1st delim */
re = VarGetPattern(vp, &vp->ptr, delim, NULL, NULL, NULL);
re = VarGetPattern(vp, delim, NULL, NULL, NULL);
if (re == NULL) {
Fatal("Unclosed substitution for %s (%c missing)",
v->name, delim);
}
patt.replace = VarGetPattern(vp, &vp->ptr, delim, NULL, NULL, NULL);
vp->ptr++; /* consume 2st delim */
patt.replace = VarGetPattern(vp, delim, NULL, NULL, NULL);
if (patt.replace == NULL) {
Fatal("Unclosed substitution for %s (%c missing)",
v->name, delim);
}
vp->ptr++; /* consume last delim */
switch (*vp->ptr) {
case 'g':
patt.flags |= VAR_SUB_GLOBAL;
@ -1211,9 +1088,9 @@ sysVvarsub(VarParser *vp, char startc, Var *v, const char value[])
* First we make a pass through the string trying to verify it is a
* SYSV-make-style translation: it must be: <string1>=<string2>)
*/
eqFound = FALSE;
cp = vp->ptr;
cnt = 1;
eqFound = FALSE;
while (*cp != '\0' && cnt) {
if (*cp == '=') {
eqFound = TRUE;
@ -1230,19 +1107,18 @@ sysVvarsub(VarParser *vp, char startc, Var *v, const char value[])
/*
* Now we break this sucker into the lhs and rhs.
*/
cp = vp->ptr;
patt.lhs = VarGetPattern(vp, &cp, '=', &patt.flags, &patt.leftLen, NULL);
patt.lhs = VarGetPattern(vp, '=', &patt.flags, &patt.leftLen, NULL);
if (patt.lhs == NULL) {
Fatal("Unclosed substitution for %s (%c missing)",
v->name, '=');
}
patt.rhs = VarGetPattern(vp, &cp, endc, NULL, &patt.rightLen, &patt);
vp->ptr++; /* consume '=' */
patt.rhs = VarGetPattern(vp, endc, NULL, &patt.rightLen, &patt);
if (patt.rhs == NULL) {
Fatal("Unclosed substitution for %s (%c missing)",
v->name, endc);
}
vp->ptr = cp - 1; /* put pointer on top of endc */
/*
* SYSV modifications happen through the whole string. Note

View File

@ -71,7 +71,6 @@ typedef struct Var {
#define VAR_SUB_MATCHED 0x04 /* There was a match */
#define VAR_MATCH_START 0x08 /* Match at start of word */
#define VAR_MATCH_END 0x10 /* Match at end of word */
#define VAR_NOSUBST 0x20 /* don't expand vars in VarGetPattern */
typedef struct {
char *lhs; /* String to match */