From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5698 invoked by alias); 21 Jun 2015 20:05:20 -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: 35552 Received: (qmail 6832 invoked from network); 21 Jun 2015 20:05:16 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2 autolearn=ham autolearn_force=no version=3.4.0 X-Originating-IP: [80.3.228.158] X-Spam: 0 X-Authority: v=2.1 cv=AJvf2gUA c=1 sm=1 tr=0 a=P+FLVI8RzFchTbbqTxIDRw==:117 a=P+FLVI8RzFchTbbqTxIDRw==:17 a=kj9zAlcOel0A:10 a=NLZqzBF-AAAA:8 a=hD80L64hAAAA:8 a=dMkkQ2EAybzPB8MNkR8A:9 a=bGxa7HxEEi5STEK4:21 a=mQmwRgimyCxZ2bpf:21 a=CjuIK1q_8ugA:10 Date: Sun, 21 Jun 2015 21:05:12 +0100 From: Peter Stephenson To: Zsh Hackers' List Subject: Re: Typeset with array Message-ID: <20150621210512.113577a6@ntlworld.com> In-Reply-To: <20150619123930.2688d9e3@pwslap01u.europe.root.pri> References: <5578996E.3080700@thequod.de> <150610191427.ZM30841@torch.brasslantern.com> <5579C247.1060800@thequod.de> <150611183639.ZM32247@torch.brasslantern.com> <20150612094237.338f79d5@pwslap01u.europe.root.pri> <20150619123930.2688d9e3@pwslap01u.europe.root.pri> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Fri, 19 Jun 2015 12:39:30 +0100 Peter Stephenson wrote: > Also, execcmd() needs some work --- currently, the reserved word > doesn't actually force you to use a builtin of the same name, we just > rely on execcmd() finding the builtin in the hash table. If that was > disabled but there was an external command of the same name it would > execute that, missing the special assigment commands on the end. This > probably isn't the right thing to do. This fixes this: we look up the same handler as the builtin for the reserved word, but ignore whether the builtin is disabled because we know the reserved word is enabled. We now force the WC_TYPESET interface even if there aren't any assignments to ensure consistency. "builtin typeset" used the builtin interface even if the reserved word is enabled --- I think that's correct. One drive-by fix to ensure we don't force an array where there's an existing parameter we can use that's a hash. With a few more tests I think this is just about ready for the master branch. pws diff --git a/Src/builtin.c b/Src/builtin.c index 5eb7bfb..dd28c8b 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -2020,7 +2020,8 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func), /* attempting a type conversion, or making a tied colonarray? */ tc = 0; - if (ASG_ARRAYP(asg) && PM_TYPE(on) == PM_SCALAR) + if (ASG_ARRAYP(asg) && PM_TYPE(on) == PM_SCALAR && + !(usepm && (PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED)))) on |= PM_ARRAY; if (usepm && ASG_ARRAYP(asg) && newspecial == NS_NONE && PM_TYPE(pm->node.flags) != PM_ARRAY && diff --git a/Src/exec.c b/Src/exec.c index 6066d55..57e8f63 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -2543,14 +2543,26 @@ execcmd(Estate state, int input, int output, int how, int last1) checked = !has_token(cmdarg); if (!checked) break; - if (!(cflags & (BINF_BUILTIN | BINF_COMMAND)) && - (hn = shfunctab->getnode(shfunctab, cmdarg))) { - is_shfunc = 1; - break; - } - if (!(hn = builtintab->getnode(builtintab, cmdarg))) { - checked = !(cflags & BINF_BUILTIN); - break; + if (type == WC_TYPESET && + (hn = builtintab->getnode2(builtintab, cmdarg))) { + /* + * If reserved word for typeset command found (and so + * enabled), use regardless of whether builtin is + * enabled as we share the implementation. + * + * Reserved words take precedence over shell functions. + */ + checked = 1; + } else { + if (!(cflags & (BINF_BUILTIN | BINF_COMMAND)) && + (hn = shfunctab->getnode(shfunctab, cmdarg))) { + is_shfunc = 1; + break; + } + if (!(hn = builtintab->getnode(builtintab, cmdarg))) { + checked = !(cflags & BINF_BUILTIN); + break; + } } orig_cflags |= cflags; cflags &= ~BINF_BUILTIN & ~BINF_COMMAND; diff --git a/Src/parse.c b/Src/parse.c index a95ec60..5357851 100644 --- a/Src/parse.c +++ b/Src/parse.c @@ -131,13 +131,11 @@ struct heredocs *hdocs; * - followed by strings * * WC_TYPESET - * Variant of WC_SIMPLE used when trailing assignments are - * needed. N.B.: if they are not, we use WC_SIMPLE even - * if this is a TYPESET keyword. + * Variant of WC_SIMPLE used when TYPESET reserved word found. * - data contains the number of string arguments (plus command) * - followed by strings * - followed by number of assignments - * - followed by assignments + * - followed by assignments if non-zero number. * * WC_SUBSH * - data unused @@ -1728,7 +1726,7 @@ static int par_simple(int *cmplx, int nr) { int oecused = ecused, isnull = 1, r, argc = 0, p, isfunc = 0, sr = 0; - int c = *cmplx, nrediradd, assignments = 0, ppost = 0; + int c = *cmplx, nrediradd, assignments = 0, ppost = 0, is_typeset = 0; wordcode postassigns = 0; r = ecused; @@ -1814,7 +1812,7 @@ par_simple(int *cmplx, int nr) incmdpos = 0; if (tok == TYPESET) - intypeset = 1; + intypeset = is_typeset = 1; if (!isset(IGNOREBRACES) && *tokstr == Inbrace) { @@ -2024,9 +2022,12 @@ par_simple(int *cmplx, int nr) intypeset = 0; if (!isfunc) { - if (postassigns) { + if (is_typeset) { ecbuf[p] = WCB_TYPESET(argc); - ecbuf[ppost] = postassigns; + if (postassigns) + ecbuf[ppost] = postassigns; + else + ecadd(0); } else ecbuf[p] = WCB_SIMPLE(argc); }