Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: [PATCH] Support the mksh's ${|func;} substitution
- X-seq: zsh-workers 51702
- From: Sebastian Gniazdowski <sgniazdowski@xxxxxxxxx>
- To: Zsh hackers list <zsh-workers@xxxxxxx>
- Subject: Re: [PATCH] Support the mksh's ${|func;} substitution
- Date: Wed, 3 May 2023 14:46:11 +0000
- Archived-at: <https://zsh.org/workers/51702>
- List-id: <zsh-workers.zsh.org>
Hi,
I was looking at some of my old patches and stumbled upon this one
which implements mksh' ${|func;} substitution. The old thread went
over a complex (x) flag choice as a expected candidate for such use
case, however I've now thought that something is better than nothing
and that implementing simpler ${!func;} doesn't block us from adding a
more advanced x-flag in the future. Also, the simplicity of this
substitution is a plus for it, opposed to x-flag complexity (think of
existing e flag, whose's use is fairly complex).
So I thought that I send the patch again upon cleaning conflicts, for
consideration. Or should we revive the advanced x-flag?
To recall - the ${|func;} substitution runs function "func" and
substitutes (returned string in…) $REPLY after it has completed,
without (!) doing forks, which is a performance and functionality
benefit over currently available equivalent: $(func;print -rn --
$REPLY). Original thread:
https://zsh.org/mla/workers/2019/msg00768.html
--
Best regards,
Sebastian Gniazdowski
From 5129820336782902f0dc43d7f196bb66c4579fb9 Mon Sep 17 00:00:00 2001
From: Sebastian Gniazdowski <sgniazdowski@xxxxxxxxx>
Date: Wed, 3 May 2023 14:47:01 +0059
Subject: Support the mksh's ${|func;} substitution
---
Src/subst.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 50 insertions(+), 1 deletion(-)
diff --git a/Src/subst.c b/Src/subst.c
index 974d6171e..abb458195 100644
--- a/Src/subst.c
+++ b/Src/subst.c
@@ -29,6 +29,7 @@
#include "zsh.mdh"
#include "subst.pro"
+#include "exec.pro"
#define LF_ARRAY 1
@@ -1860,8 +1861,17 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
* joining the array into a string (for compatibility with ksh/bash).
*/
int quoted_array_with_offset = 0;
+ /* Indicates ${|func;} */
+ int rplyfunc = 0;
+ /* The name of the function to be ran by ${|...;} */
+ char *cmdarg = NULL;
+ /* The length of the input string */
+ int slen = 0;
+ /* The closing brace pointer */
+ char *outbracep;
*s++ = '\0';
+ slen = strlen(s);
/*
* Nothing to do unless the character following the $ is
* something we recognise.
@@ -1889,6 +1899,41 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
if (c == Inbrace) {
inbrace = 1;
s++;
+
+ /* Short-path for the function-running substitution ${|func;}
+ * The function name is extracted and called, and the
+ * substitution assigned. There's no (...)-flags processing,
+ * i.e. no ${|(U)func;}, because it looks quite awful and
+ * also requires a change to the manual, part about the
+ * substitution order. Use ${(U)${|func;}} instead, it looks
+ * cleaner. */
+ if ( ((outbracep=strchr(s,Outbrace)) ||
+ (outbracep=strchr(s,'}'))) &&
+ (s[0] == Bar || s[0] == '|') &&
+ outbracep[-1] == ';' )
+ {
+ rplyfunc = 1;
+ cmdarg = dupstrpfx(s+1, outbracep-s-2);
+ s=outbracep;
+
+ HashNode hn = NULL;
+ if( (hn = shfunctab->getnode(shfunctab, cmdarg)) ) {
+ /* Execute the shell function */
+ doshfunc((Shfunc) hn, NULL, 1);
+ val = getsparam("REPLY");
+ if (val)
+ vunset = 0;
+ else {
+ vunset = 1;
+ val = dupstring("");
+ }
+ } else {
+ zerr("no such function: %s", cmdarg);
+ return NULL;
+ }
+ fetch_needed = 0;
+ }
+
/*
* In ksh emulation a leading `!' is a special flag working
* sort of like our (k). This is true only for arrays or
@@ -2589,7 +2634,11 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags,
scanflags)) ||
(v->pm && (v->pm->node.flags & PM_UNSET)) ||
(v->flags & VALFLAG_EMPTY))
- vunset = 1;
+ {
+ if (!rplyfunc) {
+ vunset = 1;
+ }
+ }
if (wantt) {
/*
--
2.28.0
Messages sorted by:
Reverse Date,
Date,
Thread,
Author