47364: Enable extendedglob in pattern with ${(*)name/pattern/replacement}

Mikael Magnusson: 47382: Completion for 47364
This commit is contained in:
Bart Schaefer 2020-09-13 16:19:52 -07:00
parent 24a82b9dad
commit 63b6398b70
6 changed files with 35 additions and 5 deletions

View file

@ -1,3 +1,11 @@
2020-09-13 Bart Schaefer <schaefer@zsh.org>
* Mikael Magnusson: 47382: Completion/Zsh/Context/_brace_parameter:
Completion for 47364
* 47364: Doc/Zsh/expn.yo, Src/subst.c, Src/zsh.h, Test/D02glob.ztst:
Enable extendedglob in pattern with ${(*)name/pattern/replacement}
2020-09-09 Stephane Chazelas <stephane@chazelas.org>
* 47352 (+ extra test cases): Src/prompt.c, Test/D01prompt.ztst:

View file

@ -142,6 +142,7 @@ if [[ $PREFIX = *'${('[^\)]# ]]; then
flags+=(
"#:evaluate as numeric expression"
"@:prevent double-quoted joining of arrays"
"*:enable extended globs for pattern"
"A:assign as an array parameter"
"a:sort in array index order (with O to reverse)"
"b:backslash quote pattern characters only"

View file

@ -1422,7 +1422,7 @@ error, and the flag itself has no effect.
enditem()
The following flags are meaningful with the tt(${)...tt(#)...tt(}) or
tt(${)...tt(%)...tt(}) forms. The tt(S) and tt(I) flags may also be
tt(${)...tt(%)...tt(}) forms. The tt(S), tt(I), and tt(*) flags may also be
used with the tt(${)...tt(/)...tt(}) forms.
startitem()
@ -1488,6 +1488,10 @@ will remove the same matches as for `tt(#)', but in reverse order, and the
form using `tt(%%)' will remove the same matches as for `tt(##)' in reverse
order.
)
item(tt(*))(
Enable tt(EXTENDED_GLOB) for substitution via tt(${)...tt(/)...tt(}) or
tt(${)...tt(//)...tt(}).
)
item(tt(B))(
Include the index of the beginning of the match in the result.
)

View file

@ -1708,7 +1708,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
/*
* This expressive name refers to the set of flags which
* is applied to matching for #, %, / and their doubled variants:
* (M), (R), (B), (E), (N), (S).
* (M), (R), (B), (E), (N), (S), (*).
*/
int flags = 0;
/* Value from (I) flag, used for ditto. */
@ -1930,6 +1930,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
case '@':
nojoin = 2; /* nojoin = 2 means force */
break;
case '*':
case Star:
flags |= SUB_EGLOB;
break;
case 'M':
flags |= SUB_MATCH;
break;
@ -2810,7 +2814,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
c == '#' || c == Pound ||
c == '?' || c == Quest ||
c == '/')) {
int eglob = isset(EXTENDEDGLOB);
/*
* Default index is 1 if no (I) or (I) gave zero. But
* why don't we set the default explicitly at the start
@ -2832,9 +2836,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
char *ptr;
/*
* previous flags are irrelevant, except for (S) which
* indicates shortest substring; else look for longest.
* indicates shortest substring; else look for longest,
# and (*) which temporarily enables extended globbing.
*/
flags = (flags & SUB_SUBSTR) ? 0 : SUB_LONG;
flags = ((flags & SUB_SUBSTR) ? 0 : SUB_LONG)|(flags & SUB_EGLOB);
if ((c = *s) == '/') {
/* doubled, so replace all occurrences */
flags |= SUB_GLOBAL;
@ -3136,7 +3141,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
for (ap = aval; *ap; ap++) {
untokenize(*ap);
}
if (flags & SUB_EGLOB)
opts[EXTENDEDGLOB] = 1;
getmatcharr(&aval, s, flags, flnum, replstr);
opts[EXTENDEDGLOB] = eglob;
} else {
if (vunset) {
if (vunset > 0 && unset(UNSET)) {
@ -3151,7 +3159,10 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
copied = 1;
untokenize(val);
}
if (flags & SUB_EGLOB)
opts[EXTENDEDGLOB] = 1;
getmatch(&val, s, flags, flnum, replstr);
opts[EXTENDEDGLOB] = eglob;
}
break;
}

View file

@ -1991,6 +1991,7 @@ struct tieddata {
#define SUB_START 0x1000 /* force match at start with SUB_END
* and no SUB_SUBSTR */
#define SUB_LIST 0x2000 /* no substitution, return list of matches */
#define SUB_EGLOB 0x4000 /* use extended globbing in patterns */
/*
* Structure recording multiple matches inside a test string.

View file

@ -792,6 +792,11 @@
*>*/glob.tmp/(flip|flop)
*>*/glob.tmp/(flip|flop)/trailing/components
unsetopt extendedglob
print -r -- ${(*)=${(@s.+.):-A+B}/(#b)(?)/-${(L)match[1]} ${match[1]}}
0:the '*' qualfier enables extended_glob for pattern matching
>-a A -b B
%clean
# Fix unreadable-directory permissions so ztst can clean up properly