From 47c05f6b66ebd071a60a76158d7f51d4b49c25a2 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Wed, 1 Mar 2017 10:01:01 +0000 Subject: 40622 with typos fixed: functions -Ms. This adds the capability for mathematical functions based on shell functions to have a string argument. Module functions have had this for a long time. --- Src/builtin.c | 23 ++++++++++++++++++++--- Src/math.c | 32 ++++++++++++++++++++++---------- 2 files changed, 42 insertions(+), 13 deletions(-) (limited to 'Src') diff --git a/Src/builtin.c b/Src/builtin.c index 16784d74a..b2e552db7 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 argument"); + 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 argument"); + 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 37981cf22..f19c0ed61 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 { -- cgit 1.4.1