From 54b395844030342213cacba4c569a6c5e6781c46 Mon Sep 17 00:00:00 2001
From: Peter Stephenson
Date: Wed, 13 Sep 2017 20:54:00 +0100
Subject: First go at var=([key]=value) syntax.
Works for both normal and typeset case, also var+=...
Still to do: allow to be mixed with straight array assignment,
improve typeset -p, implement [key]+=value.
---
Src/params.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
(limited to 'Src/params.c')
diff --git a/Src/params.c b/Src/params.c
index 6fbee880c..e0aaaf620 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -3185,6 +3185,72 @@ assignaparam(char *s, char **val, int flags)
if (flags & ASSPM_WARN)
check_warn_pm(v->pm, "array", created, may_warn_about_nested_vars);
+
+ if ((flags & ASSPM_KEY_VALUE) && (PM_TYPE(v->pm->node.flags) & PM_ARRAY)) {
+ /*
+ * This is an ordinary array with key / value pairs.
+ */
+ int maxlen, origlen;
+ char **aptr, **fullval;
+ zlong *subscripts = (zlong *)zhalloc(arrlen(val) * sizeof(zlong));
+ zlong *iptr = subscripts;
+ if (flags & ASSPM_AUGMENT) {
+ maxlen = origlen = arrlen(v->pm->gsu.a->getfn(v->pm));
+ } else {
+ maxlen = origlen = 0;
+ }
+ for (aptr = val; *aptr && aptr[1]; aptr += 2) {
+ *iptr = mathevali(*aptr);
+ if (*iptr < 0 ||
+ (!isset(KSHARRAYS) && *iptr == 0)) {
+ unqueue_signals();
+ zerr("bad subscript for direct array assignment: %s", *aptr);
+ return NULL;
+ }
+ if (!isset(KSHARRAYS))
+ --*iptr;
+ if (*iptr + 1 > maxlen)
+ maxlen = *iptr + 1;
+ ++iptr;
+ }
+ fullval = zshcalloc((maxlen+1) * sizeof(char *));
+ if (!fullval) {
+ zerr("array too large");
+ return NULL;
+ }
+ fullval[maxlen] = NULL;
+ if (flags & ASSPM_AUGMENT) {
+ char **srcptr = v->pm->gsu.a->getfn(v->pm);
+ for (aptr = fullval; aptr <= fullval + origlen; aptr++) {
+ *aptr = ztrdup(*srcptr);
+ srcptr++;
+ }
+ }
+ iptr = subscripts;
+ for (aptr = val; *aptr && aptr[1]; aptr += 2) {
+ zsfree(*aptr);
+ fullval[*iptr] = aptr[1];
+ ++iptr;
+ }
+ if (*aptr) { /* Shouldn't be possible */
+ DPUTS(1, "Extra element in key / value array");
+ zsfree(*aptr);
+ }
+ free(val);
+ for (aptr = fullval; aptr < fullval + maxlen; aptr++) {
+ /*
+ * Remember we don't have sparse arrays but and they're null
+ * terminated --- so any value we don't set has to be an
+ * empty string.
+ */
+ if (!*aptr)
+ *aptr = ztrdup("");
+ }
+ setarrvalue(v, fullval);
+ unqueue_signals();
+ return v->pm;
+ }
+
if (flags & ASSPM_AUGMENT) {
if (v->start == 0 && v->end == -1) {
if (PM_TYPE(v->pm->node.flags) & PM_ARRAY) {
--
cgit 1.4.1