about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@zsh.org>2015-06-19 13:51:02 +0100
committerPeter Stephenson <pws@zsh.org>2015-06-19 13:51:02 +0100
commit83a8d8da1a9f2de483f90a77aa2951a8574e58a0 (patch)
tree2041bf89dc649d0913c3f922682f82ffd1dbb3c3
parent9b730849abf24c512a96f0ba67405ef03d2c26de (diff)
downloadzsh-83a8d8da1a9f2de483f90a77aa2951a8574e58a0.tar.gz
zsh-83a8d8da1a9f2de483f90a77aa2951a8574e58a0.tar.xz
zsh-83a8d8da1a9f2de483f90a77aa2951a8574e58a0.zip
A couple of issues with tied arrays.
-rw-r--r--Src/builtin.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/Src/builtin.c b/Src/builtin.c
index ff382d889..b34669f88 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -2525,7 +2525,7 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
 
     if (on & PM_TIED) {
 	Param apm;
-	struct asgment asg0;
+	struct asgment asg0, asg2;
 	char *oldval = NULL, *joinstr;
 	int joinchar, nargs;
 
@@ -2565,7 +2565,7 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
 	}
 	if (!ASG_ARRAYP(asg) && asg->value.scalar) {
 	    unqueue_signals();
-	    zwarnnam(name, "second argument of tie must be scalar: %s",
+	    zwarnnam(name, "second argument of tie must be array: %s",
 		     asg->name);
 	    return 1;
 	}
@@ -2580,6 +2580,11 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
 	    zerrnam(name, "can't tie array elements: %s", asg0.name);
 	    return 1;
 	}
+	if (ASG_VALUEP(asg) && ASG_VALUEP(&asg0)) {
+	    unqueue_signals();
+	    zerrnam(name, "only one tied parameter can have value: %s", asg0.name);
+	    return 1;
+	}
 
 	/*
 	 * Third argument, if given, is character used to join
@@ -2635,7 +2640,8 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
 		}
 		return 1;
 	    }
-	    if (!asg0.value.scalar && !(PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED)))
+	    if (!asg0.value.scalar && !asg->value.array &&
+		!(PM_TYPE(pm->node.flags) & (PM_ARRAY|PM_HASHED)))
 		oldval = ztrdup(getsparam(asg0.name));
 	    on |= (pm->node.flags & PM_EXPORTED);
 	}
@@ -2643,12 +2649,18 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
 	 * Create the tied array; this is normal except that
 	 * it has the PM_TIED flag set.  Do it first because
 	 * we need the address.
+	 *
+	 * Don't attempt to set it yet, it's too early
+	 * to be exported properly.
 	 */
+	asg2.name = asg->name;
+	asg2.is_array = 0;
+	asg2.value.array = (LinkList)0;
 	if (!(apm=typeset_single(name, asg->name,
 				 (Param)paramtab->getnode(paramtab,
 							  asg->name),
 				 func, (on | PM_ARRAY) & ~PM_EXPORTED,
-				 off, roff, asg, NULL, ops, 0))) {
+				 off, roff, &asg2, NULL, ops, 0))) {
 	    if (oldval)
 		zsfree(oldval);
 	    unqueue_signals();
@@ -2680,7 +2692,9 @@ bin_typeset(char *name, char **argv, LinkList assigns, Options ops, int func)
 	if (apm->ename)
 	    zsfree(apm->ename);
 	apm->ename = ztrdup(asg0.name);
-	if (oldval)
+	if (asg->value.array)
+	    setaparam(asg->name, zlinklist2array(asg->value.array));
+	else if (oldval)
 	    setsparam(asg0.name, oldval);
 	unqueue_signals();