* ${(s::)VAR} vs "${(s::)VAR}"
@ 2012-04-26 20:48 Kynn Jones
2012-04-27 20:38 ` Peter Stephenson
0 siblings, 1 reply; 5+ messages in thread
From: Kynn Jones @ 2012-04-26 20:48 UTC (permalink / raw)
To: zsh-users
[-- Attachment #1: Type: text/plain, Size: 596 bytes --]
Hi!
I was surprised by the following (note that the first output consists of
3 lines while the second output consists of 4; the only difference between
the two cases is that the first one iterates over ${(s::)VAR} while the
second does so over its double-quoted variant, "${(s::)VAR}"):
% (VAR=123; for c ( ${(s::)VAR} ) echo ">$c<")
>1<
>2<
>3<
% (VAR=123; for c ( "${(s::)VAR}" ) echo ">$c<")
>1<
>2<
>3<
><
Even after-the-fact I cannot explain this difference. I would appreciate
a description of what's going on (and that, I hope, will lead to the
sought-after explanation).
Thanks!
kj
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: ${(s::)VAR} vs "${(s::)VAR}"
2012-04-26 20:48 ${(s::)VAR} vs "${(s::)VAR}" Kynn Jones
@ 2012-04-27 20:38 ` Peter Stephenson
2012-04-28 2:50 ` Bart Schaefer
0 siblings, 1 reply; 5+ messages in thread
From: Peter Stephenson @ 2012-04-27 20:38 UTC (permalink / raw)
To: zsh-users
On Thu, 26 Apr 2012 16:48:00 -0400
Kynn Jones <kynnjo@gmail.com> wrote:
> % (VAR=123; for c ( "${(s::)VAR}" ) echo ">$c<")
> >1<
> >2<
> >3<
> ><
I think I can say with some degree of certainty I haven't a clue what's
going on here, and it doesn't agree with the documentation "An empty
string may also be given in which case every character will be a
separate element" since you don't magically get an extra character
by sticking the expression in double quotes.
This comes from the function wordcount() in utils.c, which is called in
a couple of functions used for splitting words, none of which has any
comments apart from a few speculations from me dating from 2003. The
function takes a mysterious argument mul which presumably has got
something to do with doing something multiple times.
It seems hard to believe it should ever be counting an extra character
when it's reached the null at the end of the string. The following
seems to fix it without any obvious side effects.
Index: Src/utils.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/utils.c,v
retrieving revision 1.268
diff -p -u -r1.268 utils.c
--- Src/utils.c 16 Apr 2012 11:26:10 -0000 1.268
+++ Src/utils.c 27 Apr 2012 20:35:40 -0000
@@ -3114,7 +3114,7 @@ wordcount(char *s, char *sep, int mul)
r = 1;
sl = strlen(sep);
for (; (c = findsep(&s, sep, 0)) >= 0; s += sl)
- if ((c && *(s + sl)) || mul)
+ if ((c || mul) && *(s + sl))
r++;
} else {
char *t = s;
Index: Test/D04parameter.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/D04parameter.ztst,v
retrieving revision 1.67
diff -p -u -r1.67 D04parameter.ztst
--- Test/D04parameter.ztst 22 Apr 2012 18:39:53 -0000 1.67
+++ Test/D04parameter.ztst 27 Apr 2012 20:35:40 -0000
@@ -1304,6 +1304,19 @@
>in
>it
+ str=abcd
+ print -l ${(s..)str}
+ print -l "${(s..)str}"
+0:splitting of strings into characters
+>a
+>b
+>c
+>d
+>a
+>b
+>c
+>d
+
array=('%' '$' 'j' '*' '$foo')
print ${array[(i)*]} "${array[(i)*]}"
print ${array[(ie)*]} "${array[(ie)*]}"
--
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: ${(s::)VAR} vs "${(s::)VAR}"
2012-04-27 20:38 ` Peter Stephenson
@ 2012-04-28 2:50 ` Bart Schaefer
2012-04-29 18:22 ` Peter Stephenson
2012-04-29 18:41 ` Peter Stephenson
0 siblings, 2 replies; 5+ messages in thread
From: Bart Schaefer @ 2012-04-28 2:50 UTC (permalink / raw)
To: zsh-users
On Apr 27, 9:38pm, Peter Stephenson wrote:
}
} This comes from the function wordcount() in utils.c, which is called in
} a couple of functions used for splitting words, none of which has any
} comments apart from a few speculations from me dating from 2003. The
} function takes a mysterious argument mul which presumably has got
} something to do with doing something multiple times.
"mul" takes values -1, 0, 1. The only time it's less than zero is when
called from spacesplit() with allownull == 0. So it must have to do
with handling multiple consecutive appearances of the separator.
} for (; (c = findsep(&s, sep, 0)) >= 0; s += sl)
} - if ((c && *(s + sl)) || mul)
} + if ((c || mul) && *(s + sl))
} r++;
Does it matter that the changed line dereferences s+sl in cases where
the original line does not?
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: ${(s::)VAR} vs "${(s::)VAR}"
2012-04-28 2:50 ` Bart Schaefer
@ 2012-04-29 18:22 ` Peter Stephenson
2012-04-29 18:41 ` Peter Stephenson
1 sibling, 0 replies; 5+ messages in thread
From: Peter Stephenson @ 2012-04-29 18:22 UTC (permalink / raw)
To: zsh-users
On Fri, 27 Apr 2012 19:50:48 -0700
Bart Schaefer <schaefer@brasslantern.com> wrote:
> } for (; (c = findsep(&s, sep, 0)) >= 0; s += sl)
> } - if ((c && *(s + sl)) || mul)
> } + if ((c || mul) && *(s + sl))
> } r++;
>
> Does it matter that the changed line dereferences s+sl in cases where
> the original line does not?
That's true only if c is 0 and mul is 1 (before c had to be 1). c is 0
if we're already at a separator, so I think dereferencing s+sl is still
OK.
--
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: ${(s::)VAR} vs "${(s::)VAR}"
2012-04-28 2:50 ` Bart Schaefer
2012-04-29 18:22 ` Peter Stephenson
@ 2012-04-29 18:41 ` Peter Stephenson
1 sibling, 0 replies; 5+ messages in thread
From: Peter Stephenson @ 2012-04-29 18:41 UTC (permalink / raw)
To: zsh-users
Aha, I have however worked out what's wrong with what I did:
% foo=":bar:"
% print -l "${(s.:.)foo}"
foo
%
There should be an extra empty element, as there used to be. So I think
I need the following instead... Possibly this explains why mul was
relegated to the end in that why.
Index: Src/utils.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/utils.c,v
retrieving revision 1.268
diff -p -u -r1.268 utils.c
--- Src/utils.c 16 Apr 2012 11:26:10 -0000 1.268
+++ Src/utils.c 29 Apr 2012 18:39:39 -0000
@@ -3114,7 +3114,7 @@ wordcount(char *s, char *sep, int mul)
r = 1;
sl = strlen(sep);
for (; (c = findsep(&s, sep, 0)) >= 0; s += sl)
- if ((c && *(s + sl)) || mul)
+ if ((c || mul) && (sl || *(s + sl)))
r++;
} else {
char *t = s;
Index: Test/D04parameter.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/D04parameter.ztst,v
retrieving revision 1.67
diff -p -u -r1.67 D04parameter.ztst
--- Test/D04parameter.ztst 22 Apr 2012 18:39:53 -0000 1.67
+++ Test/D04parameter.ztst 29 Apr 2012 18:39:39 -0000
@@ -1292,7 +1292,7 @@
>in
>it
- foo="line:with::missing::fields:in:it"
+ foo="line:with::missing::fields:in:it:"
print -l "${(@s.:.)foo}"
0:Retention of empty fields in quoted splitting with "@"
>line
@@ -1303,6 +1303,20 @@
>fields
>in
>it
+>
+
+ str=abcd
+ print -l ${(s..)str}
+ print -l "${(s..)str}"
+0:splitting of strings into characters
+>a
+>b
+>c
+>d
+>a
+>b
+>c
+>d
array=('%' '$' 'j' '*' '$foo')
print ${array[(i)*]} "${array[(i)*]}"
--
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2012-04-29 18:51 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-26 20:48 ${(s::)VAR} vs "${(s::)VAR}" Kynn Jones
2012-04-27 20:38 ` Peter Stephenson
2012-04-28 2:50 ` Bart Schaefer
2012-04-29 18:22 ` Peter Stephenson
2012-04-29 18:41 ` Peter Stephenson
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).