* (s) splitting – is there any way to provide «dynamic» separator
@ 2014-10-09 15:00 Vasiliy Ivanov
2014-10-09 21:14 ` Peter Stephenson
2014-10-10 1:45 ` (s) splitting - is there any way to provid e "dynamic" separator Bart Schaefer
0 siblings, 2 replies; 10+ messages in thread
From: Vasiliy Ivanov @ 2014-10-09 15:00 UTC (permalink / raw)
To: zsh-workers
Hi,
Sorry if I (maybe) missed something obvious, but I failed to find a way to use separator from
parameter (e.g. a='1:2:3'; sep=':'; print -l ${(s.$sep.)a}).
I think this is because expansion/substitution are not available in flags? If so, is there any
another way for such a «dynamic» splitting?
--
Regards,
Vasiliy Ivanov <beelzebubbie.logs@gmail.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: (s) splitting – is there any way to provide «dynamic» separator
2014-10-09 15:00 (s) splitting – is there any way to provide «dynamic» separator Vasiliy Ivanov
@ 2014-10-09 21:14 ` Peter Stephenson
2014-10-09 21:48 ` Mikael Magnusson
2014-10-10 1:45 ` (s) splitting - is there any way to provid e "dynamic" separator Bart Schaefer
1 sibling, 1 reply; 10+ messages in thread
From: Peter Stephenson @ 2014-10-09 21:14 UTC (permalink / raw)
To: zsh-workers
On Thu, 09 Oct 2014 21:00:32 +0600
Vasiliy Ivanov <beelzebubbie.logs@gmail.com> wrote:
> Sorry if I (maybe) missed something obvious, but I failed to find a way to use separator from
> parameter (e.g. a='1:2:3'; sep=':'; print -l ${(s.$sep.)a}).
> I think this is because expansion/substitution are not available in
> flags? If so, is there any another way for such a «dynamic» splitting?
I don't think you've missed anything obvious or elegant.
One way is
(){
local IFS=$sep
print -l ${=a}
}
Or if you can rely on not having whitespace
print -l ${=${a//:/ }}
Or, of course,
eval print -l '${(s.'$sep'.)a}'
as long as you can sanity check $sep.
Of course there's nothing to stop us adding a simple parameter
substitution as a special case at this point (or any similarly delimited
parameter argument) ... Can't see how this can do much harm since it
sure as heck *looks* like a parameter expansion.
diff --git a/Src/subst.c b/Src/subst.c
index 1aa9b98..5727c12 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -1385,12 +1385,23 @@ static char *
untok_and_escape(char *s, int escapes, int tok_arg)
{
int klen;
- char *dst;
+ char *dst = NULL;
- untokenize(dst = dupstring(s));
- if (escapes) {
- dst = getkeystring(dst, &klen, GETKEYS_SEP, NULL);
- dst = metafy(dst, klen, META_HREALLOC);
+ if ((*s == String || *s == Qstring) && s[1]) {
+ char *pstart = s+1, *pend;
+ for (pend = pstart; *pend; pend++)
+ if (!iident(*pend))
+ break;
+ if (!*pend) {
+ dst = dupstring(getsparam(pstart));
+ }
+ }
+ if (dst == NULL) {
+ untokenize(dst = dupstring(s));
+ if (escapes) {
+ dst = getkeystring(dst, &klen, GETKEYS_SEP, NULL);
+ dst = metafy(dst, klen, META_HREALLOC);
+ }
}
if (tok_arg)
shtokenize(dst);
--
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: (s) splitting – is there any way to provide «dynamic» separator
2014-10-09 21:14 ` Peter Stephenson
@ 2014-10-09 21:48 ` Mikael Magnusson
2014-10-10 18:26 ` Peter Stephenson
0 siblings, 1 reply; 10+ messages in thread
From: Mikael Magnusson @ 2014-10-09 21:48 UTC (permalink / raw)
To: Peter Stephenson; +Cc: zsh workers
On 9 October 2014 23:14, Peter Stephenson <p.w.stephenson@ntlworld.com> wrote:
> On Thu, 09 Oct 2014 21:00:32 +0600
> Vasiliy Ivanov <beelzebubbie.logs@gmail.com> wrote:
>> Sorry if I (maybe) missed something obvious, but I failed to find a way to use separator from
>> parameter (e.g. a='1:2:3'; sep=':'; print -l ${(s.$sep.)a}).
>> I think this is because expansion/substitution are not available in
>> flags? If so, is there any another way for such a «dynamic» splitting?
>
> I don't think you've missed anything obvious or elegant.
>
> One way is
>
> (){
> local IFS=$sep
> print -l ${=a}
> }
>
> Or if you can rely on not having whitespace
>
> print -l ${=${a//:/ }}
>
> Or, of course,
>
> eval print -l '${(s.'$sep'.)a}'
>
> as long as you can sanity check $sep.
>
>
> Of course there's nothing to stop us adding a simple parameter
> substitution as a special case at this point (or any similarly delimited
> parameter argument) ... Can't see how this can do much harm since it
> sure as heck *looks* like a parameter expansion.
I checked to make sure you can still do (s:$:) and that does still
work. Moving into extremely unlikely corner-case land, (s:$b:) would
split on the literal string $b before. With the patch, it actually
still does, but only if b is unset. If b is set, then it is expanded
and the expansion is split on instead. So the only problem here would
be if someone used to split on a literal string $foo and then foo is
set, their code would stop working.
I don't know if it's worth it but we could possibly elect to only do
this expansion if the p flag is active? Right now it means to expand
\t into a literal tab, but it makes sense to have it more generally
mean "expand stuff" in the string I think?
eg, I think this would do it?
+ if (escapes && (*s == String || *s == Qstring) && s[1]) {
--
Mikael Magnusson
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: (s) splitting - is there any way to provid e "dynamic" separator
2014-10-09 15:00 (s) splitting – is there any way to provide «dynamic» separator Vasiliy Ivanov
2014-10-09 21:14 ` Peter Stephenson
@ 2014-10-10 1:45 ` Bart Schaefer
2014-10-10 7:06 ` (s) splitting - is there any way to provide " Vasiliy Ivanov
1 sibling, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 2014-10-10 1:45 UTC (permalink / raw)
To: zsh-workers; +Cc: Vasiliy Ivanov
On Oct 9, 9:00pm, Vasiliy Ivanov wrote:
}
} Sorry if I (maybe) missed something obvious, but I failed to find a
} way to use separator from parameter
} (e.g. a='1:2:3'; sep=':'; print -l ${(s.$sep.)a}).
Something like this:
print -l ${(ps.\0.)a//$sep/$'\0'}
(Assuming there are no nul-bytes in the value of $a to begin with.)
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: (s) splitting - is there any way to provide "dynamic" separator
2014-10-10 1:45 ` (s) splitting - is there any way to provid e "dynamic" separator Bart Schaefer
@ 2014-10-10 7:06 ` Vasiliy Ivanov
2014-10-11 0:38 ` Han Pingtian
0 siblings, 1 reply; 10+ messages in thread
From: Vasiliy Ivanov @ 2014-10-10 7:06 UTC (permalink / raw)
To: Bart Schaefer; +Cc: zsh-workers
On 10.10.2014 07:45, Bart Schaefer wrote:
> On Oct 9, 9:00pm, Vasiliy Ivanov wrote:
> }
> } Sorry if I (maybe) missed something obvious, but I failed to find a
> } way to use separator from parameter
> } (e.g. a='1:2:3'; sep=':'; print -l ${(s.$sep.)a}).
>
> Something like this:
>
> print -l ${(ps.\0.)a//$sep/$'\0'}
>
> (Assuming there are no nul-bytes in the value of $a to begin with.)
>
Thanks, this seems more elegant than «eval» way, but I failed to understand this:
% a='11::22:33'; b=("${(@s.:.)a}"); print $#b
4 (as expected)
but (I expected same result)
% a='11::22:33'; sep=':'; b=("${(@ps.\0.)a//$sep/$'\0'}"); print $#b
1
while
% a='11::22:33'; sep=':'; b=(${(@ps.\0.)a//$sep/$'\0'}); print $#b
3
--
Regards,
Vasiliy Ivanov <beelzebubbie.logs@gmail.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: (s) splitting – is there any way to provide «dynamic» separator
2014-10-09 21:48 ` Mikael Magnusson
@ 2014-10-10 18:26 ` Peter Stephenson
2014-10-13 10:30 ` Peter Stephenson
0 siblings, 1 reply; 10+ messages in thread
From: Peter Stephenson @ 2014-10-10 18:26 UTC (permalink / raw)
To: zsh workers
On Thu, 9 Oct 2014 23:48:37 +0200
Mikael Magnusson <mikachu@gmail.com> wrote:
> I don't know if it's worth it but we could possibly elect to only do
> this expansion if the p flag is active? Right now it means to expand
> \t into a literal tab, but it makes sense to have it more generally
> mean "expand stuff" in the string I think?
Yes, that works very well because anything with an escape is not a
parameter expansion. So you're only going to come a cropper if you use
the (p) flag for no reason. It's also easy and gives me a single place
to document the effect.
We could in principle do a full singsub() on the string argument when
the flag is present, but I think that's asking for trouble in terms of
complexity.
diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index 5aab259..a0478e7 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -1124,6 +1124,19 @@ item(tt(p))(
Recognize the same escape sequences as the tt(print) builtin
in string arguments to any of the flags described below that
follow this argument.
+
+Alternatively, with this option string arguments may be in the form
+tt($)var(var) in which case the value of the variable is substituted.
+Note this form is strict; the string argument does not undergo general
+parameter expansion.
+
+For example,
+
+example(sep=:
+val=a:b:c
+print ${+LPAR()ps.$sep.+RPAR()val})
+
+splits the variable on a tt(:).
)
item(tt(~))(
Strings inserted into the expansion by any of the flags below are to
diff --git a/Src/subst.c b/Src/subst.c
index 1aa9b98..61aa1c1 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -1385,12 +1385,23 @@ static char *
untok_and_escape(char *s, int escapes, int tok_arg)
{
int klen;
- char *dst;
+ char *dst = NULL;
- untokenize(dst = dupstring(s));
- if (escapes) {
- dst = getkeystring(dst, &klen, GETKEYS_SEP, NULL);
- dst = metafy(dst, klen, META_HREALLOC);
+ if (escapes && (*s == String || *s == Qstring) && s[1]) {
+ char *pstart = s+1, *pend;
+ for (pend = pstart; *pend; pend++)
+ if (!iident(*pend))
+ break;
+ if (!*pend) {
+ dst = dupstring(getsparam(pstart));
+ }
+ }
+ if (dst == NULL) {
+ untokenize(dst = dupstring(s));
+ if (escapes) {
+ dst = getkeystring(dst, &klen, GETKEYS_SEP, NULL);
+ dst = metafy(dst, klen, META_HREALLOC);
+ }
}
if (tok_arg)
shtokenize(dst);
--
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: (s) splitting - is there any way to provide "dynamic" separator
2014-10-10 7:06 ` (s) splitting - is there any way to provide " Vasiliy Ivanov
@ 2014-10-11 0:38 ` Han Pingtian
2014-10-11 3:31 ` Bart Schaefer
0 siblings, 1 reply; 10+ messages in thread
From: Han Pingtian @ 2014-10-11 0:38 UTC (permalink / raw)
To: zsh-workers
On Fri, Oct 10, 2014 at 01:06:21PM +0600, Vasiliy Ivanov wrote:
> On 10.10.2014 07:45, Bart Schaefer wrote:
> > On Oct 9, 9:00pm, Vasiliy Ivanov wrote:
> > }
> > } Sorry if I (maybe) missed something obvious, but I failed to find a
> > } way to use separator from parameter
> > } (e.g. a='1:2:3'; sep=':'; print -l ${(s.$sep.)a}).
> >
> > Something like this:
> >
> > print -l ${(ps.\0.)a//$sep/$'\0'}
> >
> > (Assuming there are no nul-bytes in the value of $a to begin with.)
> >
>
> Thanks, this seems more elegant than «eval» way, but I failed to understand this:
>
> % a='11::22:33'; b=("${(@s.:.)a}"); print $#b
> 4 (as expected)
>
> but (I expected same result)
>
> % a='11::22:33'; sep=':'; b=("${(@ps.\0.)a//$sep/$'\0'}"); print $#b
> 1
>
% a=11::22:33;print -l ${(ps.\0.)a//:/$'\0'}
11
22
33
% a=11::22:33;print -l "${(ps.\0.)a//:/$'\0'}"
11$''$''22$''33
%
Looks like $'\0' in double-quotes is converted to $'' and it doesn't equal
to \0 ?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: (s) splitting - is there any way to provide "dynamic" separator
2014-10-11 0:38 ` Han Pingtian
@ 2014-10-11 3:31 ` Bart Schaefer
2014-10-11 11:52 ` Han Pingtian
0 siblings, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 2014-10-11 3:31 UTC (permalink / raw)
To: zsh-workers
On Oct 11, 8:38am, Han Pingtian wrote:
}
} % a=11::22:33;print -l ${(ps.\0.)a//:/$'\0'}
} 11
} 22
} 33
} % a=11::22:33;print -l "${(ps.\0.)a//:/$'\0'}"
} 11$''$''22$''33
} %
}
} Looks like $'\0' in double-quotes is converted to $'' and it doesn't equal
} to \0 ?
Although it looks like an expansion, $'...' is actually a form of quotes,
and therefore cannot be used inside a double-quoted string.
The \0 is actually being removed by "print -l". Add the -R option:
torch% a=11::22:33;print -l -R "${(ps.\0.)a//:/$'\0'}"
11$'\0'$'\0'22$'\0'33
torch%
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: (s) splitting - is there any way to provide "dynamic" separator
2014-10-11 3:31 ` Bart Schaefer
@ 2014-10-11 11:52 ` Han Pingtian
0 siblings, 0 replies; 10+ messages in thread
From: Han Pingtian @ 2014-10-11 11:52 UTC (permalink / raw)
To: zsh-workers
On Fri, Oct 10, 2014 at 08:31:35PM -0700, Bart Schaefer wrote:
> On Oct 11, 8:38am, Han Pingtian wrote:
> }
> } % a=11::22:33;print -l ${(ps.\0.)a//:/$'\0'}
> } 11
> } 22
> } 33
> } % a=11::22:33;print -l "${(ps.\0.)a//:/$'\0'}"
> } 11$''$''22$''33
> } %
> }
> } Looks like $'\0' in double-quotes is converted to $'' and it doesn't equal
> } to \0 ?
>
> Although it looks like an expansion, $'...' is actually a form of quotes,
> and therefore cannot be used inside a double-quoted string.
>
Thanks.
> The \0 is actually being removed by "print -l". Add the -R option:
>
> torch% a=11::22:33;print -l -R "${(ps.\0.)a//:/$'\0'}"
> 11$'\0'$'\0'22$'\0'33
> torch%
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: (s) splitting – is there any way to provide «dynamic» separator
2014-10-10 18:26 ` Peter Stephenson
@ 2014-10-13 10:30 ` Peter Stephenson
0 siblings, 0 replies; 10+ messages in thread
From: Peter Stephenson @ 2014-10-13 10:30 UTC (permalink / raw)
To: zsh workers
Here's a test.
diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst
index 49dcea9..d7f39cb 100644
--- a/Test/D04parameter.ztst
+++ b/Test/D04parameter.ztst
@@ -1636,3 +1636,23 @@
print ${noexist:^foo})
1:Zipping arrays, NO_UNSET part 2
?(eval):2: noexist: parameter not set
+
+ expr="a@b,c@d:e@f,g@h:i@j,k@l"
+ for sep in : , @; do
+ print -l ${(ps.$sep.)expr}
+ done
+0:Use of variable to get separator when splitting parameter
+>a@b,c@d
+>e@f,g@h
+>i@j,k@l
+>a@b
+>c@d:e@f
+>g@h:i@j
+>k@l
+>a
+>b,c
+>d:e
+>f,g
+>h:i
+>j,k
+>l
pws
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2014-10-13 10:30 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-09 15:00 (s) splitting – is there any way to provide «dynamic» separator Vasiliy Ivanov
2014-10-09 21:14 ` Peter Stephenson
2014-10-09 21:48 ` Mikael Magnusson
2014-10-10 18:26 ` Peter Stephenson
2014-10-13 10:30 ` Peter Stephenson
2014-10-10 1:45 ` (s) splitting - is there any way to provid e "dynamic" separator Bart Schaefer
2014-10-10 7:06 ` (s) splitting - is there any way to provide " Vasiliy Ivanov
2014-10-11 0:38 ` Han Pingtian
2014-10-11 3:31 ` Bart Schaefer
2014-10-11 11:52 ` Han Pingtian
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).