mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-10 12:40:58 +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
|
while in the second case, the shortest matches are taken and the
|
||||||
result is `tt(spy spy lispy star)'.
|
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(}))(
|
item(tt(${#)var(spec)tt(}))(
|
||||||
If var(spec) is one of the above substitutions, substitute
|
If var(spec) is one of the above substitutions, substitute
|
||||||
the length in characters of the result instead of
|
the length in characters of the result instead of
|
||||||
|
|
90
Src/subst.c
90
Src/subst.c
|
@ -725,6 +725,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
||||||
char *sep = NULL, *spsep = NULL;
|
char *sep = NULL, *spsep = NULL;
|
||||||
char *premul = NULL, *postmul = NULL, *preone = NULL, *postone = NULL;
|
char *premul = NULL, *postmul = NULL, *preone = NULL, *postone = NULL;
|
||||||
char *replstr = NULL; /* replacement string for /orig/repl */
|
char *replstr = NULL; /* replacement string for /orig/repl */
|
||||||
|
char *thenstr, *elsestr; /* then and else for ${..^..^..^..} */
|
||||||
|
int negpat = 0;
|
||||||
zlong prenum = 0, postnum = 0;
|
zlong prenum = 0, postnum = 0;
|
||||||
int copied = 0;
|
int copied = 0;
|
||||||
int arrasg = 0;
|
int arrasg = 0;
|
||||||
|
@ -1227,7 +1229,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
||||||
*s == '%' ||
|
*s == '%' ||
|
||||||
*s == '#' || *s == Pound ||
|
*s == '#' || *s == Pound ||
|
||||||
*s == '?' || *s == Quest ||
|
*s == '?' || *s == Quest ||
|
||||||
*s == '/')) {
|
*s == '/' ||
|
||||||
|
*s == '^' || *s == Hat)) {
|
||||||
|
|
||||||
if (!flnum)
|
if (!flnum)
|
||||||
flnum++;
|
flnum++;
|
||||||
|
@ -1282,7 +1285,47 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
||||||
untokenize(replstr);
|
untokenize(replstr);
|
||||||
*ptr = '\0';
|
*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)
|
if (colf)
|
||||||
flags |= SUB_ALL;
|
flags |= SUB_ALL;
|
||||||
/*
|
/*
|
||||||
|
@ -1396,6 +1439,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
||||||
case '#':
|
case '#':
|
||||||
case Pound:
|
case Pound:
|
||||||
case '/':
|
case '/':
|
||||||
|
case '^':
|
||||||
|
case Hat:
|
||||||
if (qt) {
|
if (qt) {
|
||||||
int one = noerrs, oef = errflag, haserr;
|
int one = noerrs, oef = errflag, haserr;
|
||||||
|
|
||||||
|
@ -1417,6 +1462,45 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
||||||
char t = s[-1];
|
char t = s[-1];
|
||||||
|
|
||||||
singsub(&s);
|
singsub(&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 (t == '/' && (flags & SUB_SUBSTR)) {
|
||||||
if (*s == '#' || *s == '%') {
|
if (*s == '#' || *s == '%') {
|
||||||
flags &= ~SUB_SUBSTR;
|
flags &= ~SUB_SUBSTR;
|
||||||
|
@ -1427,8 +1511,6 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!vunset && isarr) {
|
if (!vunset && isarr) {
|
||||||
getmatcharr(&aval, s, flags, flnum, replstr);
|
getmatcharr(&aval, s, flags, flnum, replstr);
|
||||||
copied = 1;
|
copied = 1;
|
||||||
|
@ -1438,6 +1520,8 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
|
||||||
getmatch(&val, s, flags, flnum, replstr);
|
getmatch(&val, s, flags, flnum, replstr);
|
||||||
copied = 1;
|
copied = 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else { /* no ${...=...} or anything, but possible modifiers. */
|
} else { /* no ${...=...} or anything, but possible modifiers. */
|
||||||
|
|
Loading…
Reference in a new issue