Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: subscript flags on lhs of assignment



This patch allows assignments to associative array elements where the
(i) or (r) subscript flag is used to select the element. This means you
can do:
  typeset -A assoc
  assoc=(one a two b)
  assoc[(r)a]=new
At the moment, this prints the message:
  "attempt to set slice of associative array"
but that is only really applicable for the (I), (K) and (R) subscript
flags. The SCANPM_MATCHMANY flag also seems to get set for the (k)
flag. Is that a bug?

There may well be better ways to implement this. Using the (k), (i) and
(r) flags seems to result in one element arrays instead of single
values so it would be better if fetchvalue was made to return with
v->pm pointing to the actual association element instead. That couldn't
easily maintain compatibility with (i) outputting keys instead of
values though. This seems to work and is fairly minimal in terms of the
number of changes.

Oliver

Index: Src/params.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/params.c,v
retrieving revision 1.80
diff -u -r1.80 params.c
--- Src/params.c	30 Mar 2004 16:35:38 -0000	1.80
+++ Src/params.c	31 Mar 2004 08:59:17 -0000
@@ -381,6 +381,7 @@
 static Patprog scanprog;
 static char *scanstr;
 static char **paramvals;
+static Param foundparam;     
 
 /**/
 void
@@ -404,6 +405,7 @@
     } else if ((flags & SCANPM_MATCHKEY) && !pattry(scanprog, v.pm->nam)) {
 	return;
     }
+    foundparam = v.pm;
     if (flags & SCANPM_WANTKEYS) {
 	paramvals[numparamvals++] = v.pm->nam;
 	if (!(flags & (SCANPM_WANTVALS|SCANPM_MATCHVAL)))
@@ -1598,7 +1600,7 @@
 	zsfree(val);
 	return;
     }
-    if (v->pm->flags & PM_HASHED) {
+    if ((v->pm->flags & PM_HASHED) && (v->isarr & SCANPM_MATCHMANY)) {
 	zerr("%s: attempt to set slice of associative array", v->pm->nam, 0);
 	zsfree(val);
 	return;
@@ -1663,6 +1665,11 @@
 	    setarrvalue(v, ss);
 	}
 	break;
+    case PM_HASHED:
+        {
+	    (foundparam->sets.cfn) (foundparam, val);
+        }
+	break;
     }
     if ((!v->pm->env && !(v->pm->flags & PM_EXPORTED) &&
 	 !(isset(ALLEXPORT) && !(v->pm->flags & PM_HASHELEM))) ||



Messages sorted by: Reverse Date, Date, Thread, Author