* (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 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 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
* 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-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
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).