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:
parent
3eea66586b
commit
cffe7fcdef
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=143955
@ -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
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user