diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | Doc/Zsh/builtins.yo | 16 | ||||
-rw-r--r-- | Src/builtin.c | 23 | ||||
-rw-r--r-- | Src/math.c | 32 | ||||
-rw-r--r-- | Test/C04funcdef.ztst | 18 |
5 files changed, 79 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog index 62145706d..ee31ac6f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2017-03-01 Peter Stephenson <p.stephenson@samsung.com> + * 40622 (typos fixed): Doc/Zsh/builtins.yo, Src/builtin.c, + Src/math.c, Test/C04funcdef.ztst: add functions -Ms for + mathematical functions with string arguments. + * Sebastian: 40562: Test/V11db_gdbm.ztst: this was missed out of the previous commit. diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo index bdd1ad1bb..37e386581 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 therefore 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 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 { diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst index 0cf2b58b9..6a675e0b4 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" |