From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 606 invoked by alias); 26 Jan 2015 00:20:31 -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: 34400 Received: (qmail 11083 invoked from network); 26 Jan 2015 00:20:19 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) 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, T_FROM_12LTRDOM,T_MANY_HDRS_LCASE autolearn=ham version=3.3.2 X-CMAE-Score: 0 X-CMAE-Analysis: v=2.1 cv=PYxIXZlY c=1 sm=1 tr=0 a=FT8er97JFeGWzr5TCOCO5w==:117 a=kj9zAlcOel0A:10 a=q2GGsy2AAAAA:8 a=oR5dmqMzAAAA:8 a=-9mUelKeXuEA:10 a=YNv0rlydsVwA:10 a=QHpFk-N_KLmSOQG95rkA:9 a=CjuIK1q_8ugA:10 From: Bart Schaefer Message-id: <150125162016.ZM11528@torch.brasslantern.com> Date: Sun, 25 Jan 2015 16:20:16 -0800 X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh-workers@zsh.org Subject: Partial implementation of "nameref", sort of. MIME-version: 1.0 Content-type: text/plain; charset=us-ascii This is incomplete, but presented for consideration of how to proceed with it. There are obviously some additional checks that could be made, e.g., be sure that a PM_FAKENAMEREF is also a PM_SCALAR and is not a numeric subtype, etc. With this patch: % typeset -n foo=bar % bar=hello % echo $foo hello However, it doesn't work for ${foo} because the itype_end() test in paramsubst() doesn't account for the braces. diff --git a/Src/builtin.c b/Src/builtin.c index 08be1ac..8d8b125 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -120,7 +120,7 @@ static struct builtin builtins[] = BUILTIN("trap", BINF_PSPECIAL | BINF_HANDLES_OPTS, bin_trap, 0, -1, 0, NULL, NULL), BUILTIN("true", 0, bin_true, 0, -1, 0, NULL, NULL), BUILTIN("type", 0, bin_whence, 0, -1, 0, "ampfsSw", "v"), - BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klprtuxmz", NULL), + BUILTIN("typeset", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%afghi:%klprtuxmzn", NULL), BUILTIN("umask", 0, bin_umask, 0, 1, 0, "S", NULL), BUILTIN("unalias", 0, bin_unhash, 1, -1, 0, "ms", "a"), BUILTIN("unfunction", 0, bin_unhash, 1, -1, 0, "m", "f"), @@ -2369,6 +2369,11 @@ bin_typeset(char *name, char **argv, Options ops, int func) else if (OPT_PLUS(ops,optval)) off |= bit; } + if (OPT_MINUS(ops,'n')) { + on |= PM_FAKENAMEREF; + } else if (on || OPT_PLUS(ops,'n')) { + off |= PM_FAKENAMEREF; + } roff = off; /* Sanity checks on the options. Remove conflicting options. */ diff --git a/Src/subst.c b/Src/subst.c index a2bb648..842eb03 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -2237,9 +2237,11 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags) while (inull(*s)) s++; v = (Value) NULL; - } else if (aspar) { + } else if (aspar || ((s = itype_end(s, IIDENT, 0)) && !*s)) { + struct value vtmp; + char *stmp = s = idbeg; /* - * No subexpression, but in any case the value is going + * No subexpression, but in any case the value may be going * to give us the name of a parameter on which we do * our remaining processing. In other words, this * makes ${(P)param} work like ${(P)${param}}. (Probably @@ -2247,12 +2249,20 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags) * and it's been kludged into the subexp code because no * opportunity for a kludge has been neglected.) */ - if ((v = fetchvalue(&vbuf, &s, 1, (qt ? SCANPM_DQUOTED : 0)))) { - val = idbeg = getstrvalue(v); - subexp = 1; - } else + if ((v = fetchvalue(&vtmp, &stmp, 1, (qt ? SCANPM_DQUOTED : 0)))) { + if (aspar || (v->pm->node.flags & PM_FAKENAMEREF)) { + s = stmp; + vbuf = vtmp; + val = idbeg = getstrvalue(v); + aspar = subexp = 1; + } + } else if (aspar) vunset = 1; - } + if (!aspar) { + v = (Value) NULL; + } + } else + s = idbeg; /* * We need to retrieve a value either if we haven't already * got it from a subexpression, or if the processing so diff --git a/Src/zsh.h b/Src/zsh.h index 94e9ffc..dfd9c53 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -1661,6 +1661,7 @@ struct tieddata { #define PM_KSHSTORED (1<<17) /* function stored in ksh form */ #define PM_ZSHSTORED (1<<18) /* function stored in zsh form */ +#define PM_FAKENAMEREF (1<<19) /* behaves like a ksh nameref, sort of */ /* Remaining flags do not correspond directly to command line arguments */ #define PM_LOCAL (1<<21) /* this parameter will be made local */