mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-03 10:21:46 +02:00
zsh-workers/7540
This commit is contained in:
parent
ffa18a29ab
commit
5e1dc5dc01
2 changed files with 118 additions and 19 deletions
|
@ -447,6 +447,21 @@ match for tt(t*e) is substituted and the result is `tt(spy star)',
|
|||
while in the second case, the shortest matches are taken and the
|
||||
result is `tt(spy spy lispy star)'.
|
||||
)
|
||||
xitem(tt(${)var(name)tt(^)var(pattern)tt(^)var(then)tt(^)var(else)tt(}))
|
||||
item(tt(${)var(name)tt(^^)var(pattern)tt(^)var(then)tt(^)var(else)tt(}))(
|
||||
If the expansion of var(name) matches the var(pattern), the var(then)
|
||||
string is substituted, otherwise the var(else) string is
|
||||
substituted. In the second form the var(pattern) is taken to be
|
||||
negated (even if the tt(EXTENDED_GLOB) option is not set. The
|
||||
var(else) string with the preceding `tt(^)' may be omitted in which
|
||||
case the expansion behaves as if var(name) were unset (or, if
|
||||
var(name) is an array, as if the element compared did not exist). In
|
||||
the var(pattern) and the var(then) string a `tt(^)' may be included by
|
||||
preceding it with two backslashes. Finally, the var(then) and
|
||||
var(else) string may consist of only a dot to make it expand to the
|
||||
original string. To make them expand to only a dot, the string
|
||||
`tt(\.)' has to be used.
|
||||
)
|
||||
item(tt(${#)var(spec)tt(}))(
|
||||
If var(spec) is one of the above substitutions, substitute
|
||||
the length in characters of the result instead of
|
||||
|
|
122
Src/subst.c
122
Src/subst.c
|
@ -725,6 +725,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
|||
char *sep = NULL, *spsep = NULL;
|
||||
char *premul = NULL, *postmul = NULL, *preone = NULL, *postone = NULL;
|
||||
char *replstr = NULL; /* replacement string for /orig/repl */
|
||||
char *thenstr, *elsestr; /* then and else for ${..^..^..^..} */
|
||||
int negpat = 0;
|
||||
zlong prenum = 0, postnum = 0;
|
||||
int copied = 0;
|
||||
int arrasg = 0;
|
||||
|
@ -1227,7 +1229,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
|||
*s == '%' ||
|
||||
*s == '#' || *s == Pound ||
|
||||
*s == '?' || *s == Quest ||
|
||||
*s == '/')) {
|
||||
*s == '/' ||
|
||||
*s == '^' || *s == Hat)) {
|
||||
|
||||
if (!flnum)
|
||||
flnum++;
|
||||
|
@ -1282,7 +1285,47 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
|||
untokenize(replstr);
|
||||
*ptr = '\0';
|
||||
}
|
||||
if (s[-1] == '^' || s[-1] == Hat) {
|
||||
char *ptr = s;
|
||||
|
||||
if (*s == s[-1]) {
|
||||
s++;
|
||||
negpat = 1;
|
||||
}
|
||||
for (ptr = s; *ptr && *ptr != '^' && *ptr != Hat; ptr++)
|
||||
if (*ptr == '\\' && (ptr[1] == '^' || ptr[1] == Hat))
|
||||
chuck(ptr);
|
||||
if (!*ptr || !ptr[1]) {
|
||||
zerr("missing `then' string", NULL, 0);
|
||||
return NULL;
|
||||
}
|
||||
*ptr++ = '\0';
|
||||
thenstr = ptr;
|
||||
for (; *ptr && *ptr != '^' && *ptr != Hat; ptr++)
|
||||
if (*ptr == '\\' && (ptr[1] == '^' || ptr[1] == Hat))
|
||||
chuck(ptr);
|
||||
if (*ptr) {
|
||||
elsestr = ptr + 1;
|
||||
if (elsestr[0] == '\\' && elsestr[1] == '.')
|
||||
elsestr++;
|
||||
if (elsestr[0] == '.' && !elsestr[1])
|
||||
elsestr = (char *) 1;
|
||||
else {
|
||||
singsub(&elsestr);
|
||||
untokenize(elsestr);
|
||||
}
|
||||
*ptr = '\0';
|
||||
} else
|
||||
elsestr = NULL;
|
||||
if (thenstr[0] == '\\' && thenstr[1] == '.')
|
||||
thenstr++;
|
||||
if (thenstr[0] == '.' && !thenstr[1])
|
||||
thenstr = (char *) 1;
|
||||
else {
|
||||
singsub(&thenstr);
|
||||
untokenize(thenstr);
|
||||
}
|
||||
}
|
||||
if (colf)
|
||||
flags |= SUB_ALL;
|
||||
/*
|
||||
|
@ -1396,6 +1439,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
|||
case '#':
|
||||
case Pound:
|
||||
case '/':
|
||||
case '^':
|
||||
case Hat:
|
||||
if (qt) {
|
||||
int one = noerrs, oef = errflag, haserr;
|
||||
|
||||
|
@ -1417,27 +1462,66 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
|||
char t = s[-1];
|
||||
|
||||
singsub(&s);
|
||||
if (t == '/' && (flags & SUB_SUBSTR)) {
|
||||
if (*s == '#' || *s == '%') {
|
||||
flags &= ~SUB_SUBSTR;
|
||||
if (*s == '%')
|
||||
flags |= SUB_END;
|
||||
s++;
|
||||
} else if (*s == '\\') {
|
||||
s++;
|
||||
if (t == '^' || t == Hat) {
|
||||
if (!vunset && isarr) {
|
||||
char **ap, **pp;
|
||||
Patprog pprg;
|
||||
|
||||
if (!(pprg = patcompile(s, PAT_STATIC, NULL))) {
|
||||
zerr("bad pattern: %s", s, 0);
|
||||
return NULL;
|
||||
}
|
||||
if (!copied)
|
||||
aval = arrdup(aval), copied = 1;
|
||||
for (ap = pp = aval; *ap; ap++) {
|
||||
if ((!!pattry(pprg, *ap)) ^ negpat)
|
||||
*pp++ = dupstring(thenstr == ((char *) 1) ?
|
||||
*ap : thenstr);
|
||||
else if (elsestr)
|
||||
*pp++ = dupstring(elsestr == ((char *) 1) ?
|
||||
*ap : elsestr);
|
||||
}
|
||||
*pp = NULL;
|
||||
} else {
|
||||
Patprog pprg;
|
||||
|
||||
if (vunset)
|
||||
val = dupstring("");
|
||||
if ((pprg = patcompile(s, PAT_STATIC, NULL)) &&
|
||||
((!!pattry(pprg, val)) ^ negpat))
|
||||
val = dupstring(thenstr == ((char *) 1) ?
|
||||
val : thenstr);
|
||||
else if (elsestr)
|
||||
val = dupstring(elsestr == ((char *) 1) ?
|
||||
val : elsestr);
|
||||
else {
|
||||
vunset = 1;
|
||||
val = dupstring("");
|
||||
}
|
||||
copied = 1;
|
||||
}
|
||||
} else {
|
||||
if (t == '/' && (flags & SUB_SUBSTR)) {
|
||||
if (*s == '#' || *s == '%') {
|
||||
flags &= ~SUB_SUBSTR;
|
||||
if (*s == '%')
|
||||
flags |= SUB_END;
|
||||
s++;
|
||||
} else if (*s == '\\') {
|
||||
s++;
|
||||
}
|
||||
}
|
||||
if (!vunset && isarr) {
|
||||
getmatcharr(&aval, s, flags, flnum, replstr);
|
||||
copied = 1;
|
||||
} else {
|
||||
if (vunset)
|
||||
val = dupstring("");
|
||||
getmatch(&val, s, flags, flnum, replstr);
|
||||
copied = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!vunset && isarr) {
|
||||
getmatcharr(&aval, s, flags, flnum, replstr);
|
||||
copied = 1;
|
||||
} else {
|
||||
if (vunset)
|
||||
val = dupstring("");
|
||||
getmatch(&val, s, flags, flnum, replstr);
|
||||
copied = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else { /* no ${...=...} or anything, but possible modifiers. */
|
||||
|
|
Loading…
Reference in a new issue