From 6c4a2b778ca4c625bf15cf700d6ec3ce1aea1bcf 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 | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/Src/subst.c b/Src/subst.c index b132f251b..dc2b58cc7 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -29,6 +29,7 @@ #include "zsh.mdh" #include "subst.pro" +#include "builtin.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 *rplycode[2] = {NULL, 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,36 @@ 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; + rplycode[0] = dupstrpfx(s+1, outbracep-s-2); + s=outbracep; + + /* Execute the shell function */ + bin_eval(NULL, rplycode, NULL, 0); + + val = getsparam("REPLY"); + if (val) + vunset = 0; + else { + vunset = 1; + val = dupstring(""); + } + fetch_needed = 0; + } + /* * In ksh emulation a leading `!' is a special flag working * sort of like our (k). @@ -2519,7 +2559,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