Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: ${(s::)VAR} vs "${(s::)VAR}"



On Thu, 26 Apr 2012 16:48:00 -0400
Kynn Jones <kynnjo@xxxxxxxxx> 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@xxxxxxxxxxxx>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/



Messages sorted by: Reverse Date, Date, Thread, Author