From fb4744562d2f03246288da2692559d7f9c4014f2 Mon Sep 17 00:00:00 2001 From: Sebastian Gniazdowski Date: Fri, 6 Sep 2019 02:35:14 +0200 Subject: [PATCH] Support the mksh's substitution ${|func;} --- Src/subst.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/Src/subst.c b/Src/subst.c index b132f251b..80a572e17 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 @@ -1847,8 +1848,17 @@ paramsubst(LinkList l, LinkNode n, char **str, int qt, int pf_flags, * nested (P) flags. */ int fetch_needed; + /* 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. @@ -1876,6 +1886,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). @@ -2519,7 +2564,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.21.0