zsh-workers
 help / color / mirror / code / Atom feed
* [PATCH] Forcing array interpretation in parameter substitution
@ 2017-02-25 22:47 Bart Schaefer
  0 siblings, 0 replies; 3+ messages in thread
From: Bart Schaefer @ 2017-02-25 22:47 UTC (permalink / raw)
  To: zsh-workers

} The problem is that nesting ${${...}} "wants" to treat the inner ${...}
} as a scalar, and will do so unless something else forces it to be an
} array.  (f) doesn't accomplish that because $(dirs -v) produces only
} one line of output with the final newline stripped, so there is nothing
} for (f) to split on.  (@) won't accomplish it because it only means
} that things that are already arrays should remain so.
} 
} So what can be done to force interpretation as an array here?

I occurred to me in one of those "why didn't we do this before?" moments
that there's no reason the (A) flag has to have meaning only in context
of ${name=value}.

I haven't found anything obviously wrong with the following patch and
all tests still pass.


diff --git a/Doc/Zsh/expn.yo b/Doc/Zsh/expn.yo
index 43ecd31..402afdb 100644
--- a/Doc/Zsh/expn.yo
+++ b/Doc/Zsh/expn.yo
@@ -955,15 +955,25 @@ This is distinct from em(field splitting) by the tt(f), tt(s)
 or tt(z) flags, which still applies within each array element.
 )
 item(tt(A))(
-Assign as an array parameter with `tt(${)...tt(=)...tt(})',
+Convert the subsitution into an array expression, even if it otherwise
+would be scalar.  This has lower precedence than subscripting, so one
+level of nested expansion is required in order that subscripts apply
+to array elements.  Thus tt(${${LPAR()A)tt(RPAR())var(name)tt(}[1]})
+yields the full value of var(name) when var(name) is scalar.
+
+This assigns an array parameter with `tt(${)...tt(=)...tt(})',
 `tt(${)...tt(:=)...tt(})' or `tt(${)...tt(::=)...tt(})'.
-If this flag is repeated (as in `tt(AA)'), assign an associative
+If this flag is repeated (as in `tt(AA)'), assigns an associative
 array parameter.  Assignment is made before sorting or padding;
 if field splitting is active, the var(word) part is split before
 assignment.  The var(name) part may be a subscripted range for
 ordinary arrays; when assigning an associative array, the var(word)
 part em(must) be converted to an array, for example by using
 `tt(${(AA)=)var(name)tt(=)...tt(})' to activate field splitting.
+
+Surrounding context such as additional nesting or use of the value
+in a scalar assignment may cause the array to be joined back into
+a single string again.
 )
 item(tt(a))(
 Sort in array index order; when combined with `tt(O)' sort in reverse
diff --git a/Src/subst.c b/Src/subst.c
index 4df53bd..02dbe28 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -2902,6 +2902,7 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
 		    } else
 			setaparam(idbeg, a);
 		    isarr = 1;
+		    arrasg = 0;
 		} else {
 		    untokenize(val);
 		    setsparam(idbeg, ztrdup(val));
@@ -3784,6 +3785,16 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
 	insertlinknode(l, n, dupstring(fstr)); /* appended, no incnode */
 	*fstr = '\0';
     }
+    if (arrasg && !isarr) {
+	/*
+	 * Caller requested this be forced to an array even if scalar.
+	 * Any point in distinguishing arrasg == 2 (assoc array) here?
+	 */
+	l->list.flags |= LF_ARRAY;
+	aval = hmkarray(val);
+	isarr = 1;
+	DPUTS(!val, "value is NULL in paramsubst, empty array");
+    }
     if (isarr) {
 	char *x;
 	char *y;


^ permalink raw reply	[flat|nested] 3+ messages in thread
* Re: [PATCH] Forcing array interpretation in parameter substitution
@ 2017-04-13 16:29 Sebastian Gniazdowski
  2017-04-13 21:03 ` Bart Schaefer
  0 siblings, 1 reply; 3+ messages in thread
From: Sebastian Gniazdowski @ 2017-04-13 16:29 UTC (permalink / raw)
  To: zsh-workers

Just realized that this isn't a "5.0.2" or so thing. Great commit really, it allows to index (z) result, or (s::) result, when there is no split and instead of array, a string is returned:

>: var="abc"; echo ${${(z)var}[1]}; echo ${${(Az)var}[1]} "<- so (A) does help"
a
abc <- so (A) does help

I wonder if there can be any workaround for older versions, tried (@z) or silly (0z) etc., and no make-array effect occurs.

--
Sebastian Gniazdowski
psprint /at/ zdharma.org


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-04-13 21:03 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-25 22:47 [PATCH] Forcing array interpretation in parameter substitution Bart Schaefer
2017-04-13 16:29 Sebastian Gniazdowski
2017-04-13 21:03 ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).