Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
RFC PATCH: Sketch at :@ subscripting
- X-seq: zsh-workers 47747
- From: Mikael Magnusson <mikachu@xxxxxxxxx>
- To: zsh-workers@xxxxxxx
- Subject: RFC PATCH: Sketch at :@ subscripting
- Date: Fri, 18 Dec 2020 14:18:15 +0100
- Archived-at: <https://zsh.org/workers/47747>
- Archived-at: <http://www.zsh.org/sympa/arcsearch_id/zsh-workers/2020-12/20201218131815.25999-1-mikachu%40gmail.com>
- Authentication-results: zsh.org; iprev=pass (mail-lf1-f46.google.com) smtp.remote-ip=209.85.167.46; dkim=pass header.d=gmail.com header.s=20161025 header.a=rsa-sha256; dmarc=pass header.from=gmail.com; arc=none
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=8tlPwydSg2yUPidJdckGcY+zQbN+r7GYtYqNH2JH6EY=; b=LbOKSMPkaiLrnsWJoVBCxPEnPEuobjPXZUV0G1S7iI+a6TRdA0qu5mCYsAQ0IMPcG9 I3GVsmoDKPOAvCj94hGLuXC+fTEPnz/aQJ25PEnLI1ZI4Qc2gwosubLayZISjHu1Gthw QsIznoQN2pMkJ3SpQdk9Tj8p9vg+tzxqm75F3f++D3T7cw5FG33n5To8Z/CibdjPzPw/ 5gx6oA3sEiOw4eQE7E0Ib/pqokEOACb7LWAESCIGtkwMLGxFraN0wWq7gXWGlnjVcB3v 6PlW0o0RU8jI1q4138oNSoBkMohBWYwXqSKDPJW7dMsbIXYbrs2tglf57qw4Yp8lGgQ5 C0xw==
- List-archive: <http://www.zsh.org/sympa/arc/zsh-workers>
- List-help: <mailto:sympa@zsh.org?subject=help>
- List-id: <zsh-workers.zsh.org>
- List-owner: <mailto:zsh-workers-request@zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- List-subscribe: <mailto:sympa@zsh.org?subject=subscribe%20zsh-workers>
- List-unsubscribe: <mailto:sympa@zsh.org?subject=unsubscribe%20zsh-workers>
- Sender: zsh-workers-request@xxxxxxx
As the subject says, this is in a very early idea stage, but it does work for basic cases at least.
The idea is that you can do this:
% typeset -a somearray=( 'data here' 'some words' etc etc 1 2 3 4 ) idx=(1 3 5)
% echo ${somearray:@idx}
data here etc 1
The way it currently works also lets you do this:
% typeset -a somearray=( 'data here' 'some words' etc etc 1 2 3 4 ) idx=( '(r)<->' '(I)etc' )
% echo ${somearray:@idx}
1 4
Not decided on if that's desirable :).
Anyway, the code as it is written now is very hacky and I'm wondering if I missed the existence of some useful functions, or if the stuff I'm using now would need to be refactored a bit to make this actually possible without doing stupid things like zhtricat("[", *sub_it, "]").
Also curious why getindex() unconditionally *writes* '[' to the first character in the input string passed to it...
---
Src/subst.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/Src/subst.c b/Src/subst.c
index 8de201b663..943b2546c4 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -3167,6 +3167,67 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
}
break;
}
+ } else if (inbrace && (*s == '@')) {
+ /* use every element of the array specified by @ as a subscript */
+ char **idx;
+ ++s;
+ if (*itype_end(s, IIDENT, 0)) {
+ untokenize(s);
+ zerr("not an identifier: %s", s);
+ return NULL;
+ }
+ if (vunset) {
+ if (vunset > 0 && unset(UNSET)) {
+ *idend = '\0';
+ zerr("%s: parameter not set", idbeg);
+ return NULL;
+ }
+ isarr = 0;
+ val = dupstring("");
+ } else {
+ char *sval;
+ idx = getaparam(s);
+ if (!idx) {
+ sval = getsparam(s);
+ if (sval)
+ idx = hmkarray(sval);
+ }
+ if (idx) {
+ if (isarr) {
+ if (PM_TYPE(vbuf.pm->node.flags) & PM_ARRAY) {
+ /* actual code is here */
+ LinkList list = newlinklist();
+ char **sub_it, **val_it;
+ for (sub_it = idx; *sub_it; sub_it++) {
+ char *tmp = zhtricat("[", *sub_it, "]");
+ /* getindex() modifies vbuf in ways that break further
+ * subscripting with differing flags, so better not to
+ * touch it at all. */
+ struct value vbuf_copy = vbuf;
+ getindex(&tmp, &vbuf_copy, 0);
+ for (val_it = getarrvalue(&vbuf_copy); *val_it; val_it++) {
+ addlinknode(list, *val_it);
+ }
+ }
+ aval = hlinklist2array(list, !copied);
+ copied = 1;
+ } else {
+ zerr("assoc @ not implemented");
+ }
+ } else {
+ zerr("scalar @ not implemented");
+ }
+ } else {
+
+ if (unset(UNSET)) {
+ zerr("%s: parameter not set", s);
+ return NULL;
+ }
+ isarr = 0;
+ val = dupstring("");
+ }
+ }
} else if (inbrace && (*s == '^' || *s == Hat)) {
char **zip;
int shortest = 1;
--
2.15.1
Messages sorted by:
Reverse Date,
Date,
Thread,
Author