Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: [key]=value syntax, work in progress
- X-seq: zsh-workers 41676
- From: Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
- To: Zsh hackers list <zsh-workers@xxxxxxx>
- Subject: PATCH: [key]=value syntax, work in progress
- Date: Mon, 11 Sep 2017 21:51:15 +0100
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ntlworld.com; s=meg.feb2017; t=1505163076; bh=7zEy+l3CRxs0s5ndg1FbESDM+DaiTjaTdsv/kpIw7fQ=; h=Date:From:To:Subject; b=r+5T/8IV9ZRo2A8Y9fU9rEk0LmVijoRMa4uBiiwVgjcljv84oKL7Fe5w1mIGo7vrm mrjMoDApd7ZJBSyYvnRVGaWEb9UwgVlMeRqLSvCYHo6OYX2rLsac/TKDt9b5jKgwg/ wqDhggcLJVCOXz6SWFMtF4NnSBIRxfKOq/NUPswxoEHdQYVuMSjG7cVeDRiHHaX2r0 cN46xRbyXx8rGBUwH31TUm9f0W9PjaxZ2lh8uf+ovz882OgaGf8wWI184l3ASiz1PT nWhwuk3QA+t0v5VXPq1ZaQ9CjvN7I+3dtSVevLe07q5fSKqPUd3Q2aPsw8/vfoUAjX yReJVtEZawaQA==
- 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
Very early days in an attempt to support the [key]=value syntax in array
assignment. See tests at end for what I have done so far.
typeset does not yet support this syntax.
Note that the index does not determine the type of the array / hash
being created --- this is how bash works, and it would be a guess at
best as we allow math evaluation for numeric subscripts.
Please let me know now of anything that is going in the wrong direction
or based on a misunderstanding or just plain wrong. The clumsiest bit
is the addition to do key / value assignment for normal arrays, but I
don't think it's actually broken.
Note globbing is suppressed for this form of array assignment. That
seems pretty much inevitable --- turning a value into multiple values
isn't useful here.
Feel free to come up with corner cases, but I'm likely to test for
them as errors rather than add gratuitous extra support.
pws
diff --git a/Src/exec.c b/Src/exec.c
index e2432fd..73506a1 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -2394,7 +2394,7 @@ static void
addvars(Estate state, Wordcode pc, int addflags)
{
LinkList vl;
- int xtr, isstr, htok = 0;
+ int xtr, isstr, htok = 0, dontglob = 0;
char **arr, **ptr, *name;
int flags;
@@ -2428,8 +2428,38 @@ addvars(Estate state, Wordcode pc, int addflags)
if ((isstr = (WC_ASSIGN_TYPE(ac) == WC_ASSIGN_SCALAR))) {
init_list1(svl, ecgetstr(state, EC_DUPTOK, &htok));
vl = &svl;
- } else
+ } else {
+ char *start, *end;
+ LinkNode ve, next;
vl = ecgetlist(state, WC_ASSIGN_NUM(ac), EC_DUPTOK, &htok);
+ if (vl &&
+ (ve = firstnode(vl)) &&
+ (start = (char *)getdata(ve)) &&
+ start[0] == Inbrack &&
+ (end = strchr(start+1, Outbrack)) &&
+ end[1] == Equals) {
+ dontglob = 1;
+ myflags |= ASSPM_KEY_VALUE;
+ for (;;) {
+ *end = '\0';
+ next = nextnode(ve);
+ setdata(ve, start+1);
+ insertlinknode(vl, ve, end+2);
+ ve = next;
+ if (!ve)
+ break;
+ if (!(start = (char *)getdata(ve)) ||
+ start[0] != Inbrack ||
+ !(end = strchr(start+1, Outbrack)) ||
+ end[1] != Equals) {
+ zerr("bad array element, expected [key]=value: %s",
+ start);
+ state->pc = opc;
+ return;
+ }
+ }
+ }
+ }
if (vl && htok) {
prefork(vl, (isstr ? (PREFORK_SINGLE|PREFORK_ASSIGN) :
@@ -2438,8 +2468,9 @@ addvars(Estate state, Wordcode pc, int addflags)
state->pc = opc;
return;
}
- if (!isstr || (isset(GLOBASSIGN) && isstr &&
- haswilds((char *)getdata(firstnode(vl))))) {
+ if (!dontglob &&
+ (!isstr || (isset(GLOBASSIGN) && isstr &&
+ haswilds((char *)getdata(firstnode(vl)))))) {
globlist(vl, 0);
/* Unset the parameter to force it to be recreated
* as either scalar or array depending on how many
diff --git a/Src/params.c b/Src/params.c
index 6fbee88..8201fa5 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -3185,6 +3185,64 @@ 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)) {
+ int maxlen, origlen;
+ char **aptr, **fullval, *dummy;
+ 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 = mathevalarg(*aptr, &dummy);
+ if (*iptr < 0 ||
+ (!isset(KSHARRAYS) && *iptr == 0)) {
+ 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 *));
+ fullval[maxlen] = NULL;
+ if (flags & ASSPM_AUGMENT) {
+ char **srcptr = v->pm->gsu.a->getfn(v->pm);
+ for (aptr = fullval; aptr <= fullval + maxlen; 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) {
diff --git a/Src/zsh.h b/Src/zsh.h
index 1e982a6..13fb1e1 100644
--- a/Src/zsh.h
+++ b/Src/zsh.h
@@ -2060,6 +2060,11 @@ enum {
ASSPM_WARN = (ASSPM_WARN_CREATE|ASSPM_WARN_NESTED),
/* Import from environment, so exercise care evaluating value */
ASSPM_ENV_IMPORT = 1 << 3,
+ /* Array is key / value pairs.
+ * This is normal for associative arrays but variant behaviour for
+ * normal arrays.
+ */
+ ASSPM_KEY_VALUE = 1 << 4
};
/* node for named directory hash table (nameddirtab) */
diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst
index 8dbc1e8..fd098d5 100644
--- a/Test/D04parameter.ztst
+++ b/Test/D04parameter.ztst
@@ -2207,3 +2207,25 @@ F:behavior, see http://austingroupbugs.net/view.php?id=888
0:(z) splitting with remaining tokens
>foo-bar*thingy?
+ typeset -A keyvalhash
+ keyvalhash=([one]=eins [two]=zwei)
+ keyvalhash+=([three]=drei)
+ for key in ${(ok)keyvalhash}; do
+ print $key $keyvalhash[$key]
+ done
+0:[key]=val for hashes
+>one eins
+>three drei
+>two zwei
+
+ keyvalarray=([1]=one [3]=three)
+ print -l "${keyvalarray[@]}"
+ keyvalarray+=([2]=two)
+ print -l "${keyvalarray[@]}"
+0:[key]=val for normal arrays
+>one
+>
+>three
+>one
+>two
+>three
Messages sorted by:
Reverse Date,
Date,
Thread,
Author