Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Question with no answer, a="1+1"; $(( mathfun($a) ))
- X-seq: zsh-workers 40623
- From: Sebastian Gniazdowski <psprint2@xxxxxxxxxxxx>
- To: zsh-workers@xxxxxxx
- Subject: Re: Question with no answer, a="1+1"; $(( mathfun($a) ))
- Date: Thu, 23 Feb 2017 02:38:27 -0800
- Dkim-signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=fastmail.com; h= content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-sender :x-me-sender:x-sasl-enc; s=mesmtp; bh=otyjQTaGYxclJ1IB8GEvaz5lSJ g=; b=t6/iQzmeDYrAGcz8QunlUznMWIVJI4x7pWP4nxTQD09vpSNzfRydlQ6CwO 3kjfoZTBQZJzBSnpSWfDHoxsx4vvdal0NlvC131GlRrBjniNkspuNh4pa428ydXL gbCGFep3K9NgFyda1ohEs3m83zywgpRuuwZx6eVtBjN2KO6IE=
- Dkim-signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-sender:x-me-sender:x-sasl-enc; s=smtpout; bh=ot yjQTaGYxclJ1IB8GEvaz5lSJg=; b=mYWP1izxI2Bo1b2v/BXqkSV3Tj9XJmOYO3 IhWXhcnAmUPieYwnM4hWLsJGdWXvIwY6/fzYelrTMS8/x+VI7AlSDXZlCfV9XUMy 3fpNaFL9XaC4CfwO03l6YrV+1eeMZn5cDtHLnyIpemwHJW+HyfeBZQhNwtddZZr5 Cizd4NDgQ=
- In-reply-to: <20170223101109.50633602@pwslap01u.europe.root.pri>
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
- References: <CGME20170223085553epcas1p380bee4b00b62d96a31c996e00e758903@epcas1p3.samsung.com> <1487840080.4078992.890215168.6CBEA51D@webmail.messagingengine.com> <20170223101109.50633602@pwslap01u.europe.root.pri>
Hello,
that's cool. I've spotted those:
+ zwarnnam(name, "-Ms: must take a single string
argumet");
+ zwarnnam(name, "-Ms: must take a single string
argumet");
--
Sebastian Gniazdowski
psprint2@xxxxxxxxxxxx
On Thu, Feb 23, 2017, at 02:11 AM, Peter Stephenson wrote:
> On Thu, 23 Feb 2017 00:54:40 -0800
> Sebastian Gniazdowski <psprint2@xxxxxxxxxxxx> wrote:
> > But:
> >
> > % mfun() { echo "dbg: $1"; }; functions -M mfun 1 1; val="1+2"; echo $((
> > mfun($val) ))
> > dbg: 3
> > 3
> >
> > This is probably a show stopper, but maybe I can accomplish the "nicer"
> > goal some other way, maybe even with math functions after all?
>
> (Moved to workers as this is a new implementation.)
>
> This isn't actually difficult to fix, and it fills a gap since
> internally implemented math functions have always had an option for
> string arguments.
>
> Note there is no halfway house: if you get a string argument, it's
> *exactly* what's been passed in after substitution, and you get to
> extract white space, commas, whatever, yourself.
>
> pws
>
> diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
> index bdd1ad1..65bebdf 100644
> --- a/Doc/Zsh/builtins.yo
> +++ b/Doc/Zsh/builtins.yo
> @@ -840,7 +840,7 @@ point numbers are not permitted.
> )
> findex(functions)
> xitem(tt(functions) [ {tt(PLUS())|tt(-)}tt(UkmtTuWz) ] [ tt(-x) var(num)
> ] [ var(name) ... ])
> -xitem(tt(functions -M) var(mathfn) [ var(min) [ var(max) [ var(shellfn)
> ] ] ])
> +xitem(tt(functions -M) [tt(-s)] var(mathfn) [ var(min) [ var(max) [
> var(shellfn) ] ] ])
> xitem(tt(functions -M) [ tt(-m) var(pattern) ... ])
> item(tt(functions +M) [ tt(-m) ] var(mathfn) ... )(
> Equivalent to tt(typeset -f), with the exception of the tt(-x),
> @@ -882,6 +882,13 @@ The result of the last arithmetical expression
> evaluated
> inside the shell function (even if it is a form that normally only
> returns
> a status) gives the result of the mathematical function.
>
> +If the additional option tt(-s) is given to tt(functions -M), the
> +argument to the function is a single string: anything between the
> +opening and matching closing parenthesis is passed to the function as a
> +single argument, even if it includes commas or white space. The minimum
> +and maximum argument specifiers must thererfore be 1 if given. An empty
> +argument list is passed as a zero-length string.
> +
> tt(functions -M) with no arguments lists all such user-defined functions
> in
> the same form as a definition. With the additional option tt(-m) and
> a list of arguments, all functions whose var(mathfn) matches one of
> @@ -898,6 +905,13 @@ For example, the following prints the cube of 3:
> example(zmath_cube+LPAR()RPAR() { (( $1 * $1 * $1 )) }
> functions -M cube 1 1 zmath_cube
> print $(( cube+LPAR()3+RPAR() )))
> +
> +The following string function takes a single argument, including
> +the commas, so prints 11:
> +
> +example(stringfn+LPAR()RPAR() { (( $#1 )) }
> +functions -Ms stringfn
> +print $(( stringfn+LPAR()foo,bar,rod+RPAR() )))
> )
> module(getcap)(zsh/cap)
> findex(getln)
> diff --git a/Src/builtin.c b/Src/builtin.c
> index 16784d7..b72a7a4 100644
> --- a/Src/builtin.c
> +++ b/Src/builtin.c
> @@ -72,7 +72,7 @@ static struct builtin builtins[] =
> BUILTIN("fc", 0, bin_fc, 0, -1, BIN_FC, "aAdDe:EfiIlLmnpPrRt:W",
> NULL),
> BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL),
> BUILTIN("float", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL |
> BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0,
> "E:%F:%HL:%R:%Z:%ghlprtux", "E"),
> - BUILTIN("functions", BINF_PLUSOPTS, bin_functions, 0, -1, 0,
> "kmMtTuUWx:z", NULL),
> + BUILTIN("functions", BINF_PLUSOPTS, bin_functions, 0, -1, 0,
> "kmMstTuUWx:z", NULL),
> BUILTIN("getln", 0, bin_read, 0, -1, 0, "ecnAlE", "zr"),
> BUILTIN("getopts", 0, bin_getopts, 2, -1, 0, NULL, NULL),
> BUILTIN("hash", BINF_MAGICEQUALS, bin_hash, 0, -1, 0, "Ldfmrv",
> NULL),
> @@ -2993,7 +2993,7 @@ listusermathfunc(MathFunc p)
> else
> showargs = 0;
>
> - printf("functions -M %s", p->name);
> + printf("functions -M%s %s", (p->flags & MFF_STR) ? "s" : "",
> p->name);
> if (showargs) {
> printf(" %d", p->minargs);
> showargs--;
> @@ -3220,11 +3220,18 @@ bin_functions(char *name, char **argv, Options
> ops, int func)
> }
> } else {
> /* Add a function */
> - int minargs = 0, maxargs = -1;
> + int minargs, maxargs;
> char *funcname = *argv++;
> char *modname = NULL;
> char *ptr;
>
> + if (OPT_ISSET(ops,'s')) {
> + minargs = maxargs = 1;
> + } else {
> + minargs = 0;
> + maxargs = -1;
> + }
> +
> ptr = itype_end(funcname, IIDENT, 0);
> if (idigit(*funcname) || funcname == ptr || *ptr) {
> zwarnnam(name, "-M %s: bad math function name", funcname);
> @@ -3238,6 +3245,10 @@ bin_functions(char *name, char **argv, Options
> ops, int func)
> *argv);
> return 1;
> }
> + if (OPT_ISSET(ops,'s') && minargs != 1) {
> + zwarnnam(name, "-Ms: must take a single string
> argumet");
> + return 1;
> + }
> maxargs = minargs;
> argv++;
> }
> @@ -3251,6 +3262,10 @@ bin_functions(char *name, char **argv, Options
> ops, int func)
> *argv);
> return 1;
> }
> + if (OPT_ISSET(ops,'s') && maxargs != 1) {
> + zwarnnam(name, "-Ms: must take a single string
> argumet");
> + return 1;
> + }
> argv++;
> }
> if (*argv)
> @@ -3263,6 +3278,8 @@ bin_functions(char *name, char **argv, Options ops,
> int func)
> p = (MathFunc)zshcalloc(sizeof(struct mathfunc));
> p->name = ztrdup(funcname);
> p->flags = MFF_USERFUNC;
> + if (OPT_ISSET(ops,'s'))
> + p->flags |= MFF_STR;
> p->module = modname ? ztrdup(modname) : NULL;
> p->minargs = minargs;
> p->maxargs = maxargs;
> diff --git a/Src/math.c b/Src/math.c
> index 37981cf..f19c0ed 100644
> --- a/Src/math.c
> +++ b/Src/math.c
> @@ -974,7 +974,7 @@ callmathfunc(char *o)
> a[strlen(a) - 1] = '\0';
>
> if ((f = getmathfunc(n, 1))) {
> - if (f->flags & MFF_STR) {
> + if ((f->flags & (MFF_STR|MFF_USERFUNC)) == MFF_STR) {
> return f->sfunc(n, a, f->funcid);
> } else {
> int argc = 0;
> @@ -987,22 +987,34 @@ callmathfunc(char *o)
> addlinknode(l, n);
> }
>
> - while (iblank(*a))
> - a++;
> + if (f->flags & MFF_STR) {
> + if (!*a) {
> + addlinknode(l, dupstring(""));
> + argc++;
> + }
> + } else {
> + while (iblank(*a))
> + a++;
> + }
> while (*a) {
> if (*a) {
> argc++;
> if (f->flags & MFF_USERFUNC) {
> /* need to pass strings */
> char *str;
> - marg = mathevall(a, MPREC_ARG, &a);
> - if (marg.type & MN_FLOAT) {
> - /* convfloat is off the heap */
> - str = convfloat(marg.u.d, 0, 0, NULL);
> + if (f->flags & MFF_STR) {
> + str = dupstring(a);
> + a = "";
> } else {
> - char buf[BDIGBUFSIZE];
> - convbase(buf, marg.u.l, 10);
> - str = dupstring(buf);
> + marg = mathevall(a, MPREC_ARG, &a);
> + if (marg.type & MN_FLOAT) {
> + /* convfloat is off the heap */
> + str = convfloat(marg.u.d, 0, 0, NULL);
> + } else {
> + char buf[BDIGBUFSIZE];
> + convbase(buf, marg.u.l, 10);
> + str = dupstring(buf);
> + }
> }
> addlinknode(l, str);
> } else {
> diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst
> index 0cf2b58..6a675e0 100644
> --- a/Test/C04funcdef.ztst
> +++ b/Test/C04funcdef.ztst
> @@ -102,6 +102,24 @@
> >4
> >5
>
> + strmathfunc() {
> + if [[ $0 = stralpha ]]; then
> + set -- ${1//[^[:alpha:]]}
> + fi
> + (( $#1 ))
> + }
> + functions -Ms strlen 1 1 strmathfunc
> + functions -Ms stralpha 1 1 strmathfunc
> + print $(( strlen(this, is, a, raw, string) ))
> + print $(( strlen() ))
> + print $(( stralpha(this, is, a, raw, string) ))
> + print $(( stralpha() ))
> +0:User-defined math functions, string arguments
> +>24
> +>0
> +>16
> +>0
> +
> command_not_found_handler() {
> print "Great News! I've handled the command:"
> print "$1"
Messages sorted by:
Reverse Date,
Date,
Thread,
Author