From faf05be3d2adc99212af74e2507a66de1161a52a Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 21 May 2007 09:30:24 +0000 Subject: 23440: Make $param[(R)value] substitute the empty string on failure --- ChangeLog | 7 +++++++ Doc/Zsh/params.yo | 17 ++++++----------- README | 4 ++++ Src/params.c | 21 ++++++++++++++++++++- Test/D06subscript.ztst | 3 +-- 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 912837e01..c88602f1f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2007-05-21 Peter Stephenson + + * 23440: README, Doc/Zsh/params.yo, Src/params.c, + Test/D06subscript.ztst: Reverse parameter subscripting + with (R) now returns the empty string on failure. Other + operators are not changed. + 2007-05-20 Peter Stephenson * 23444: Src/builtin.c: print -c/-C didn't take into diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo index 6f134baa2..f839ec880 100644 --- a/Doc/Zsh/params.yo +++ b/Doc/Zsh/params.yo @@ -234,15 +234,7 @@ item(tt(R))( Like `tt(r)', but gives the last match. For associative arrays, gives all possible matches. May be used for assigning to ordinary array elements, but not for assigning to associative arrays. - -Note that this flag can give odd results on failure. For an ordinary array -the item substituted is that corresponding to subscript 0. If the option -tt(KSH_ARRAYS) is not in effect, this is the same as the element -corresponding to subscript 1, although the form tt(${array[(I)pattern]}) -will evaluate to 0 for a failed match. If the option tt(KSH_ARRAYS) is in -effect, the subscript is still 0 for a failed match; this cannot be -distinguished from a successful match without testing tt(${array[0]}) -against the pattern. +On failure the empty string is returned. ) item(tt(i))( Like `tt(r)', but gives the index of the match instead; this may not be @@ -251,13 +243,16 @@ behaves like `tt(r)'. For associative arrays, the key part of each pair is compared to the pattern, and the first matching key found is the result. -See `tt(r)' for discussion of subscripts of failed matches. +On failure, a value one past the end of the array or string is returned. ) item(tt(I))( Like `tt(i)', but gives the index of the last match, or all possible matching keys in an associative array. -See `tt(R)' for discussion of subscripts of failed matches. +On failure the value 0 is returned. If the option tt(KSH_ARRAYS) is in +effect, the subscript is still 0 for a failed match; this cannot be +distinguished from a successful match without testing tt(${array[0]}) +against the pattern. ) item(tt(k))( If used in a subscript on an associative array, this flag causes the keys diff --git a/README b/README index 94ba2236c..e80b6fbfb 100644 --- a/README +++ b/README @@ -72,6 +72,10 @@ of the value. The form ${param//#$search/replace} where the value $search starts with "%" considers the "%" to be part of the search string as before. +Parameter subscripts of the form ${array[(R)test]} now return the +empty string if they fail to match. The previous longstanding behaviour +was confusing and useless. + The MULTIBYTE option is on by default where it is available; this causes many operations to recognise characters as in the current locale. Older versions of the shell always assumed a character was one byte. diff --git a/Src/params.c b/Src/params.c index ed8b4a412..14ff4f6ca 100644 --- a/Src/params.c +++ b/Src/params.c @@ -1276,6 +1276,19 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w, if (pprog && pattry(pprog, *p) && !--num) return r; } + /* + * Failed to match. + * If we're returning an index, return 0 to show + * we've gone off the start. Unfortunately this + * is ambiguous with KSH_ARRAYS set, but we're + * stuck with that now. + * + * If the index is to be turned into an element, + * return an index that does not point to a valid + * element (since 0 is treated the same as 1). + */ + if (!ind) + r = len + 1; } else for (r = 1 + beg, p = ta + beg; *p; r++, p++) if (pprog && pattry(pprog, *p) && !--num) @@ -1495,7 +1508,13 @@ getarg(char **str, int *inv, Value v, int a2, zlong *w, } } } - return down ? 0 : slen + 1; + /* + * Failed to match. + * If the argument selects an element rather than + * its index, ensure the element is empty. + * See comments on the array case above. + */ + return (down && ind) ? 0 : slen + 1; } } return r; diff --git a/Test/D06subscript.ztst b/Test/D06subscript.ztst index 9ce022557..4dd8a8237 100644 --- a/Test/D06subscript.ztst +++ b/Test/D06subscript.ztst @@ -29,12 +29,11 @@ >*, [how] I [wonder] what? You are! >] I [ - # $s[(R)x] actually is $s[0], but zsh treats 0 as 1 for subscripting. print $s[(i)x] : $s[(I)x] print $s[(r)x] : $s[(R)x] 0:Scalar pattern subscripts that do not match >61 : 0 ->: T +>: print -R $s[$s[(i)\[]] $s[(i)$s[(r)\*]] $s[(i)${(q)s[(r)\]]}] 0:Scalar subscripting using a pattern subscript to get the index -- cgit 1.4.1