zsh-users
 help / color / mirror / code / Atom feed
* ${(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).