summaryrefslogtreecommitdiff
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.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