about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2007-05-21 09:30:24 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2007-05-21 09:30:24 +0000
commitfaf05be3d2adc99212af74e2507a66de1161a52a (patch)
tree7a0ac19d76eff3142484c02a83388a5e52848535
parent86ff81f82d97b0118eddb729a2d4956fcbdd7c7a (diff)
downloadzsh-faf05be3d2adc99212af74e2507a66de1161a52a.tar.gz
zsh-faf05be3d2adc99212af74e2507a66de1161a52a.tar.xz
zsh-faf05be3d2adc99212af74e2507a66de1161a52a.zip
23440: Make $param[(R)value] substitute the empty string on failure
-rw-r--r--ChangeLog7
-rw-r--r--Doc/Zsh/params.yo17
-rw-r--r--README4
-rw-r--r--Src/params.c21
-rw-r--r--Test/D06subscript.ztst3
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  <pws@csr.com>
+
+	* 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  <p.w.stephenson@ntlworld.com>
 
 	* 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