From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17844 invoked by alias); 18 Apr 2010 19:26:46 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 27889 Received: (qmail 2274 invoked from network); 18 Apr 2010 19:26:43 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham version=3.3.1 Received-SPF: pass (ns1.primenet.com.au: SPF record at ntlworld.com designates 81.103.221.33 as permitted sender) Date: Sun, 18 Apr 2010 20:11:12 +0100 From: Peter Stephenson To: zsh-workers@zsh.org Subject: Re: Is this a bug? Why not? Message-ID: <20100418201112.5d3e8477@pws-pc> In-Reply-To: References: <100330224612.ZM1818@torch.brasslantern.com> <20100331060602.GA91691@redoubt.spodhuis.org> <100331081153.ZM2688@torch.brasslantern.com> <20100401082624.GA56998@redoubt.spodhuis.org> <100401073618.ZM10593@torch.brasslantern.com> <20100401215752.GA34619@redoubt.spodhuis.org> <100401155118.ZM11873@torch.brasslantern.com> <20100409153754.76d0f6a6@news01> X-Mailer: Claws Mail 3.7.5 (GTK+ 2.18.9; x86_64-redhat-linux-gnu) Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Cloudmark-Analysis: v=1.1 cv=1ggfb5FlKZQUfF3vzm9UBYZ2uTfLsbs/8dSljwg5+mE= c=1 sm=0 a=DogomfpGjd0A:10 a=kj9zAlcOel0A:10 a=pGLkceISAAAA:8 a=NLZqzBF-AAAA:8 a=d0QIAz8AYj0DmFsEqXIA:9 a=okOhCi6S-m-uCM8MYO0A:7 a=1fTnzD7n-pIOwB3kvchG6OoZOWkA:4 a=CjuIK1q_8ugA:10 a=MSl-tDqOz04A:10 a=_dQi-Dcv4p4A:10 a=HpAAvcLHHh0Zw7uRqdWCyQ==:117 On Sat, 17 Apr 2010 15:06:53 +0200 Mikael Magnusson wrote: > This patch (resetting globsubst for the argument of a variable substitution when the pattern matching is already done) > breaks at least cd ~-/ realpath=${~:-\~$linepath}/ doesn't expand the second "~" despite the first "~" because the second tilde is quoted. Strictly this new behaviour is probably correct because the quote should indeed stop the second tilde being active, but actually the hack below fixes this so I've left it (even though removing the backslash seemed to work in this case, too). > and anything using _pids for me. That's because given desc=' PID TTY TIME CMD' out=( ' 2591 pts/1 00:00:02 zsh' ' 2600 pts/1 00:00:01 dropbox' ' 3271 pts/1 00:00:00 zsh' ' 3272 pts/1 00:00:00 ps' ) this expression: pids=( "${(@)${(@M)out#${(l.${#desc[1,(r)(#i)[[:blank:]]pid]}..?.)~:-}[^[:blank:]]#}##*[[:blank:]]}" ) sets pids=( '' '' '' '' ) Er... obviously. What's happening is ${(l.${#desc[1,(r)(#i)[[:blank:]]pid]}..?.)~:-} should turn into ????? which are activated for use in patterns, because of the "~", but it isn't because globsubst is now turned off when we get to padding because we already handled the value as the right hand side of ":-" (i.e. the empty string) so there was no value to activate. One fix is to leave globsubst on when it's forced by the "~" flag. That doesn't screw up sh compatibility, which knows nothing about the flag, but it's not really the right thing to do, which would be to track through to see where the text came from and conditionally tokenize it, yeugh. The difference is in the case where GLOB_SUBST is set but you're using zsh substitution syntax, which is not typical (and is the sort of complicated hybrid I'd dearly love to forbid but will never be able to). As I'm definitely not doing any major surgery on paramsubst() to preserve different notions of globsubst at different points in the function myself (feel free to volunteer) it may be all you will get in any case. See the test file for a simpler indication of implications. Ultimately, I think this hack may actually be the right thing to do because it preserves traditional zsh behaviour in typical cases (where the option isn't set and ~ is used to force it) as well as any script adhering to sh syntax. I'll think about some documentation. "Ceterum censeo functio de substitutione parametrum esse rescribenda" ("Furthermore, I am of the opinion that paramsubst() ought to be rewritten") --- Marcus Porcius Cato the Elder Index: Src/subst.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/subst.c,v retrieving revision 1.103 diff -p -u -r1.103 subst.c --- Src/subst.c 9 Apr 2010 15:40:14 -0000 1.103 +++ Src/subst.c 18 Apr 2010 19:03:01 -0000 @@ -1386,7 +1386,8 @@ paramsubst(LinkList l, LinkNode n, char int plan9 = isset(RCEXPANDPARAM); /* * Likwise, but with ~ and ~~. Also, we turn it off later - * on if qt is passed down. + * on if qt is passed down. The value can go to 2 if we + * use ~ to force this on. */ int globsubst = isset(GLOBSUBST); /* @@ -1899,12 +1900,12 @@ paramsubst(LinkList l, LinkNode n, char * spsep, NULL means $IFS. */ } else if (c == '~' || c == Tilde) { - /* GLOB_SUBST on or off (doubled) */ + /* GLOB_SUBST (forced) on or off (doubled) */ if ((c = *++s) == '~' || c == Tilde) { globsubst = 0; s++; } else - globsubst = 1; + globsubst = 2; } else if (c == '+') { /* * Return whether indicated parameter is set. @@ -1935,7 +1936,8 @@ paramsubst(LinkList l, LinkNode n, char break; } /* Don't activate special pattern characters if inside quotes */ - globsubst = globsubst && !qt; + if (qt) + globsubst = 0; /* * At this point, we usually expect a parameter name. @@ -2417,7 +2419,10 @@ paramsubst(LinkList l, LinkNode n, char multsub(&val, spbreak && !aspar, (aspar ? NULL : &aval), &isarr, NULL); opts[SHWORDSPLIT] = ws; copied = 1; - spbreak = globsubst = 0; + spbreak = 0; + /* Leave globsubst on if forced */ + if (globsubst != 2) + globsubst = 0; } break; case ':': Index: Test/D04parameter.ztst =================================================================== RCS file: /cvsroot/zsh/zsh/Test/D04parameter.ztst,v retrieving revision 1.41 diff -p -u -r1.41 D04parameter.ztst --- Test/D04parameter.ztst 9 Apr 2010 15:40:14 -0000 1.41 +++ Test/D04parameter.ztst 18 Apr 2010 19:03:01 -0000 @@ -226,10 +226,12 @@ foo="boring*" print ${foo+$foo} print ${foo+"$foo"} + print ${~foo+"$foo"} ) 0:globsubst together with nested quoted expansion >boringfile >boring* +>boringfile print -l "${$(print one word)}" "${=$(print two words)}" 0:splitting of $(...) inside ${...} -- Peter Stephenson Web page now at http://homepage.ntlworld.com/p.w.stephenson/