summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2010-11-25 10:34:32 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2010-11-25 10:34:32 +0000
commitfc6c76519b863f38ab650e0e82fce574c5dc98e1 (patch)
treee8b04143855ec64e08084349de5d173a48c969a0
parent32a4c982065bff9829ef6be87095530c7acc96d3 (diff)
downloadzsh-fc6c76519b863f38ab650e0e82fce574c5dc98e1.tar.gz
zsh-fc6c76519b863f38ab650e0e82fce574c5dc98e1.zip
28434: make ${NAME:OFFSET} always use zero-offset
-rw-r--r--ChangeLog7
-rw-r--r--Doc/Zsh/expn.yo60
-rw-r--r--Src/subst.c11
-rw-r--r--Test/D04parameter.ztst14
4 files changed, 56 insertions, 36 deletions
diff --git a/ChangeLog b/ChangeLog
index 3ba0a6b1d..a68c01534 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2010-11-25 Peter Stephenson <pws@csr.com>
+
+ * 28434: Doc/Zsh/expn.yo, Src/subst.c, Test/D04parameter.ztst:
+ Make ${NAME:OFFSET} always use zero-offset.
+
2010-11-22 Peter Stephenson <pws@csr.com>
* 28424: Doc/Zsh/options.yo, Src/options.c, Src/utils.c,
@@ -13838,5 +13843,5 @@
*****************************************************
* This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.5125 $
+* $Revision: 1.5126 $
*****************************************************
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index 416d46407..0c26a7ca5 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -588,23 +588,29 @@ remove the non-matched elements).
xitem(tt(${)var(name)tt(:)var(offset)tt(}))
item(tt(${)var(name)tt(:)var(offset)tt(:)var(length)tt(}))(
This syntax gives effects similar to parameter subscripting
-in the form tt($)var(name)tt({)var(offset)tt(,)var(end)tt(}) but in
-a form compatible with other shells.
-
-If the variable var(name) is a scalar, substitute the contents
-starting from offset var(offset); if var(name) is an array,
-substitute elements from element var(offset). If var(length) is
-given, substitute that many characters or elements, otherwise the
-entire rest of the scalar or array.
-
-var(offset) is treated similarly to a parameter subscript:
-the offset of the first character or element in var(name)
-is 0 if the option tt(KSH_ARRAYS) is set, else 1; a negative
-subscript counts backwards so that -1 corresponds to the last
-character or element.
+in the form tt($)var(name)tt({)var(start)tt(,)var(end)tt(}), but is
+compatible with other shells; note that both var(offset) and var(length)
+are interpreted differently from the components of a subscript.
+
+If var(offset) is non-negative, then if the variable var(name) is a
+scalar substitute the contents starting var(offset) characters from the
+first character of the string, and if var(name) is an array substitute
+elements starting var(offset) elements from the first element. If
+var(length) is given, substitute that many characters or elements,
+otherwise the entire rest of the scalar or array.
+
+A positive var(offset) is always treated as the offset of a character or
+element in var(name) from the first character or element of the array
+(this is different from native zsh subscript notation). Hence 0
+refers to the first character or element regardless of the setting of
+the option tt(KSH_ARRAYS).
+
+A negative offset counts backwards from the end of the scalar or array,
+so that -1 corresponds to the last character or element, and so on.
var(length) is always treated directly as a length and hence may not be
-negative.
+negative. The option tt(MULTIBYTE) is obeyed, i.e. the offset and length
+count multibyte characters where appropriate.
var(offset) and var(length) undergo the same set of shell substitutions
as for scalar assignment; in addition, they are then subject to arithmetic
@@ -615,19 +621,29 @@ print ${foo: 1 + 2}
print ${foo:$(( 1 + 2))}
print ${foo:$(echo 1 + 2)})
-all have the same effect.
+all have the same effect, extracting the string starting at the fourth
+character of tt($foo) if the substution would otherwise return a scalar,
+or the array starting at the fourth element if tt($foo) would return an
+array. Note that with the option tt(KSH_ARRAYS) tt($foo) always returns
+a scalar (regardless of the use of the offset syntax) and a form
+such as tt($foo[*]:3) is required to extract elements of an array named
+tt(foo).
-Note that if var(offset) is negative, the tt(-) may not appear immediately
+If var(offset) is negative, the tt(-) may not appear immediately
after the tt(:) as this indicates the
-tt(${)var(name)tt(:-)var(word)tt(}) form of substitution; a space
+tt(${)var(name)tt(:-)var(word)tt(}) form of substitution. Instead, a space
may be inserted before the tt(-). Furthermore, neither var(offset) nor
var(length) may begin with an alphabetic character or tt(&) as these are
-used to indicate history-style modifiers.
+used to indicate history-style modifiers. To substitute a value from a
+variable, the recommended approach is to proceed it with a tt($) as this
+signifies the intention (parameter substitution can easily be rendered
+unreadable); however, as arithmetic substitution is performed, the
+expression tt(${var: offs}) does work, retrieving the offset from
+tt($offs).
For further compatibility with other shells there is a special case
-when the tt(KSH_ARRAYS) option is active, as in emulation of
-Bourne-style shells. In this case array subscript 0 usually refers to the
-first element of the array. However, if the substitution refers to the
+for array offset 0. This usually accesses to the
+first element of the array. However, if the substitution refers the
positional parameter array, e.g. tt($@) or tt($*), then offset 0
instead refers to tt($0), offset 1 refers to tt($1), and so on. In
other words, the positional parameter array is effectively extended by
diff --git a/Src/subst.c b/Src/subst.c
index 12825ff93..031a1affd 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -1640,7 +1640,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
int subexp;
/*
* If we're referring to the positional parameters, then
- * e.g ${*:1:1} refers to $1 even if KSH_ARRAYS is in effect.
+ * e.g ${*:1:1} refers to $1.
* This is for compatibility.
*/
int horrible_offset_hack = 0;
@@ -2768,16 +2768,15 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int ssub)
return NULL;
}
}
- if (!isset(KSHARRAYS) || horrible_offset_hack) {
+ if (horrible_offset_hack) {
/*
* As part of the 'orrible hoffset 'ack,
* (what hare you? Han 'orrible hoffset 'ack,
* sergeant major), if we are given a ksh/bash/POSIX
- * style array which includes offset 0, we use
- * $0.
+ * style positional parameter array which includes
+ * offset 0, we use $0.
*/
- if (isset(KSHARRAYS) && horrible_offset_hack &&
- offset == 0 && isarr) {
+ if (offset == 0 && isarr) {
offset_hack_argzero = 1;
} else if (offset > 0) {
offset--;
diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst
index 46565a121..4bd911e5f 100644
--- a/Test/D04parameter.ztst
+++ b/Test/D04parameter.ztst
@@ -1268,15 +1268,15 @@
print ${foo:$(echo 3 + 3):`echo 4 - 3`}
print ${foo: -1}
print ${foo: -10}
-0:Bash-style subscripts, scalar
->3456789
+0:Bash-style offsets, scalar
>456789
>56789
>6789
->3
+>789
>4
>5
>6
+>7
>9
>123456789
@@ -1291,15 +1291,15 @@
print ${foo:$(echo 3 + 3):`echo 4 - 3`}
print ${foo: -1}
print ${foo: -10}
-0:Bash-style subscripts, array
->3 4 5 6 7 8 9
+0:Bash-style offsets, array
>4 5 6 7 8 9
>5 6 7 8 9
>6 7 8 9
->3
+>7 8 9
>4
>5
>6
+>7
>9
>1 2 3 4 5 6 7 8 9
@@ -1321,7 +1321,7 @@
echo ${str: -1:1}
}
testfn
-0:Bash-style subscripts, Bourne-style indexing
+0:Bash-style offsets, Bourne-style indexing
>1
>2
>3