1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-15 10:17:20 +00:00

Split out the 'S' modifier into its own function.

Patch:		7.122,7.123

Submitted by:	Max Okumoto <okumoto@ucsd.edu>
This commit is contained in:
Hartmut Brandt 2005-03-18 15:37:31 +00:00
parent 1753011e3f
commit e524dd1162
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=143812

View File

@ -902,7 +902,7 @@ VarExpand(Var *v, VarParser *vp)
}
/**
* Select only those words that match the modifier.
* Select only those words in value that match the modifier.
*/
static char *
modifier_M(const char mod[], const char value[], char endc, size_t *consumed)
@ -948,6 +948,10 @@ modifier_M(const char mod[], const char value[], char endc, size_t *consumed)
return (newValue);
}
/**
* Substitute the replacement string for the pattern. The substitution
* is applied to each word in value.
*/
static char *
modifier_S(const char mod[], const char value[], Var *v, VarParser *vp, size_t *consumed)
{
@ -1127,6 +1131,79 @@ modifier_S(const char mod[], const char value[], Var *v, VarParser *vp, size_t *
return (newValue);
}
static char *
modifier_C(const char mod[], char value[], Var *v, VarParser *vp, size_t *consumed)
{
VarREPattern patt;
int delim;
char *re;
const char *cur;
int error;
char *newValue;
patt.flags = 0;
delim = mod[1]; /* delimiter between sections */
cur = mod + 2;
re = VarGetPattern(vp, &cur, delim, NULL, NULL, NULL);
if (re == NULL) {
Fatal("Unclosed substitution for %s (%c missing)",
v->name, delim);
}
patt.replace = VarGetPattern(vp, &cur, delim, NULL, NULL, NULL);
if (patt.replace == NULL) {
Fatal("Unclosed substitution for %s (%c missing)",
v->name, delim);
}
for (;; cur++) {
switch (*cur) {
case 'g':
patt.flags |= VAR_SUB_GLOBAL;
continue;
case '1':
patt.flags |= VAR_SUB_ONE;
continue;
default:
break;
}
break;
}
error = regcomp(&patt.re, re, REG_EXTENDED);
if (error) {
*consumed = cur - mod;
VarREError(error, &patt.re, "RE substitution error");
free(patt.replace);
free(re);
return (var_Error);
}
patt.nsub = patt.re.re_nsub + 1;
if (patt.nsub < 1)
patt.nsub = 1;
if (patt.nsub > 10)
patt.nsub = 10;
patt.matches = emalloc(patt.nsub * sizeof(regmatch_t));
newValue = VarModify(value, VarRESubstitute, &patt);
regfree(&patt.re);
free(patt.matches);
free(patt.replace);
free(re);
*consumed += (cur - mod);
if (cur[0] == ':') {
*consumed += 1; /* include colin as part of modifier */
}
return (newValue);
}
/*
* Now we need to apply any modifiers the user wants applied.
* These are:
@ -1175,94 +1252,20 @@ ParseModifier(const char input[], const char tstr[],
switch (*tstr) {
case 'N':
case 'M':
readonly = TRUE; /* tstr isn't modified here */
readonly = TRUE;
newStr = modifier_M(tstr, value, endc, &consumed);
tstr += consumed;
break;
case 'S':
readonly = TRUE; /* tstr isn't modified here */
readonly = TRUE;
newStr = modifier_S(tstr, value, v, vp, &consumed);
tstr += consumed;
break;
case 'C':
{
int delim;
VarREPattern pattern;
char *re;
int error;
pattern.flags = 0;
delim = tstr[1];
tstr += 2;
cp = tstr;
if ((re = VarGetPattern(vp, &cp, delim, NULL,
NULL, NULL)) == NULL) {
*lengthPtr = cp - input + 1;
if (*freePtr)
free(value);
if (delim != '\0')
Fatal("Unclosed substitution for %s (%c missing)",
v->name, delim);
return (var_Error);
}
if ((pattern.replace = VarGetPattern(vp, &cp,
delim, NULL, NULL, NULL)) == NULL){
free(re);
/* was: goto cleanup */
*lengthPtr = cp - input + 1;
if (*freePtr)
free(value);
if (delim != '\0')
Fatal("Unclosed substitution for %s (%c missing)",
v->name, delim);
return (var_Error);
}
for (;; cp++) {
switch (*cp) {
case 'g':
pattern.flags |= VAR_SUB_GLOBAL;
continue;
case '1':
pattern.flags |= VAR_SUB_ONE;
continue;
default:
break;
}
readonly = TRUE;
newStr = modifier_C(tstr, value, v, vp, &consumed);
tstr += consumed;
break;
}
termc = *cp;
error = regcomp(&pattern.re, re, REG_EXTENDED);
free(re);
if (error) {
*lengthPtr = cp - input + 1;
VarREError(error, &pattern.re, "RE substitution error");
free(pattern.replace);
return (var_Error);
}
pattern.nsub = pattern.re.re_nsub + 1;
if (pattern.nsub < 1)
pattern.nsub = 1;
if (pattern.nsub > 10)
pattern.nsub = 10;
pattern.matches = emalloc(pattern.nsub *
sizeof(regmatch_t));
newStr = VarModify(value, VarRESubstitute, &pattern);
regfree(&pattern.re);
free(pattern.replace);
free(pattern.matches);
break;
}
case 'L':
if (tstr[1] == endc || tstr[1] == ':') {
Buffer *buf;