mirror of git://git.code.sf.net/p/zsh/code
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.
This commit is contained in:
parent
24497ad196
commit
47c05f6b66
|
@ -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.
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
32
Src/math.c
32
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 {
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue