Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Partial implementation of "nameref", sort of.
- X-seq: zsh-workers 34400
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxx
- Subject: Partial implementation of "nameref", sort of.
- Date: Sun, 25 Jan 2015 16:20:16 -0800
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
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 */
Messages sorted by:
Reverse Date,
Date,
Thread,
Author