mirror of
git://git.code.sf.net/p/zsh/code
synced 2024-10-01 00:12:08 +02:00
22416, tweaked: math functions via shell functions
unposted: add styles to pick-web-browser
This commit is contained in:
parent
5c2d5b013e
commit
b7474e065b
12
ChangeLog
12
ChangeLog
@ -1,3 +1,15 @@
|
||||
2006-04-19 Peter Stephenson <p.w.stephenson@ntlworld.com>
|
||||
|
||||
* unposted: Doc/Zsh/contrib.yo, Functions/MIME/pick-web-browser:
|
||||
add some styles for commands.
|
||||
|
||||
* 22416: Doc/Zsh/builtins.yo, Doc/Zsh/contrib.yo,
|
||||
Functions/Misc/.distfiles, Functions/Misc/zcalc,
|
||||
Functions/Misc/zmathfuncdef, Src/builtin.c, Src/exec.c,
|
||||
Src/module,c, Src/math.c, Src/module.c, Src/zsh.h,
|
||||
Test/C04funcdef.ztst: user-defined math functions via
|
||||
shell functions.
|
||||
|
||||
2006-04-14 Doug Kearns <djkea2@gus.gscit.monash.edu.au>
|
||||
|
||||
* unposted: Completion/Unix/Command/_raggle: update for version
|
||||
|
@ -501,8 +501,52 @@ Equivalent to tt(typeset -E), except that options irrelevant to floating
|
||||
point numbers are not permitted.
|
||||
)
|
||||
findex(functions)
|
||||
item(tt(functions) [ {tt(PLUS())|tt(-)}tt(UXkmtuz) ] [ var(name) ... ])(
|
||||
Equivalent to tt(typeset -f).
|
||||
xitem(tt(functions) [ {tt(PLUS())|tt(-)}tt(UXkmtuz) ] [ var(name) ... ])
|
||||
xitem(tt(functions -M) 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(-M) option.
|
||||
Use of the tt(-M) option may not be combined with any of the options
|
||||
handled by tt(typeset -f).
|
||||
|
||||
tt(functions -M) var(mathfn) defines var(mathfn) as the name of
|
||||
a mathematical function recognised in all forms of arithmetical expressions;
|
||||
see
|
||||
ifzman(the section `Arithmetic Evaluation' in zmanref(zshmisc))\
|
||||
ifnzman(noderef(Arithmetic Evaluation))\
|
||||
. By default var(mathfn) may take
|
||||
any number of comma-separated arguments. If var(min) is given,
|
||||
it must have exactly var(min) args; if var(min) and var(max) are
|
||||
both given, it must have at least var(min) and and at most var(max)
|
||||
args. var(max) may be -1 to indicate that there is no upper limit.
|
||||
|
||||
By default the function is implemented by a shell function of the same
|
||||
name; if var(shellfn) is specified it gives the name of the corresponding
|
||||
shell function while var(mathfn) remains the name used in arithmetical
|
||||
expressions. The name of the function in tt($0) is var(mathfn) (not
|
||||
var(shellfn) as would usually be the case), provided the option
|
||||
tt(FUNCTION_ARGZERO) is in effect. The positional parameters in the shell
|
||||
function correspond to the arguments of the mathematical function call.
|
||||
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.
|
||||
|
||||
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
|
||||
the pattern arguments are listed.
|
||||
|
||||
tt(function +M) removes the list of mathematical functions; with the
|
||||
additional option tt(-m) the arguments are treated as patterns and
|
||||
all functions whose tt(mathfn) matches the pattern are removed. Note
|
||||
that the shell function implementing the behaviour is not removed
|
||||
(regardless of whether its name coincides with tt(mathfn)).
|
||||
|
||||
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() )))
|
||||
)
|
||||
module(getcap)(zsh/cap)
|
||||
findex(getln)
|
||||
@ -652,8 +696,10 @@ tt(kill -IO) and tt(kill -POLL) have the same effect.
|
||||
findex(let)
|
||||
item(tt(let) var(arg) ...)(
|
||||
Evaluate each var(arg) as an arithmetic expression.
|
||||
See noderef(Arithmetic Evaluation) for a description
|
||||
of arithmetic expressions. The exit status is 0 if the
|
||||
See
|
||||
ifzman(the section `Arithmetic Evaluation' in zmanref(zshmisc))\
|
||||
ifnzman(noderef(Arithmetic Evaluation))
|
||||
for a description of arithmetic expressions. The exit status is 0 if the
|
||||
value of the last expression is nonzero, and 1 otherwise.
|
||||
)
|
||||
findex(limit)
|
||||
@ -856,7 +902,9 @@ that allows it to be reused as shell input. With the numeric format
|
||||
specifiers, if the corresponding argument starts with a quote character,
|
||||
the numeric value of the following character is used as the number to
|
||||
print otherwise the argument is evaluated as an arithmetic expression. See
|
||||
noderef(Arithmetic Evaluation) for a description of arithmetic
|
||||
ifzman(the section `Arithmetic Evaluation' in zmanref(zshmisc))\
|
||||
ifnzman(noderef(Arithmetic Evaluation))
|
||||
for a description of arithmetic
|
||||
expressions. With `tt(%n)', the corresponding argument is taken as an
|
||||
identifier which is created as an integer parameter.
|
||||
|
||||
|
@ -15,6 +15,7 @@ menu(Prompt Themes)
|
||||
menu(ZLE Functions)
|
||||
menu(Exception Handling)
|
||||
menu(MIME Functions)
|
||||
menu(Mathematical Functions)
|
||||
menu(Other Functions)
|
||||
endmenu()
|
||||
|
||||
@ -1339,7 +1340,7 @@ if a shell error subsequently occurs. Adding tt(unset EXCEPTION) at the
|
||||
start of the outermost layer of any code that uses exception handling will
|
||||
eliminate this problem.
|
||||
|
||||
texinode(MIME Functions)(Other Functions)(Exception Handling)(User Contributions)
|
||||
texinode(MIME Functions)(Mathematical Functions)(Exception Handling)(User Contributions)
|
||||
sect(MIME Functions)
|
||||
|
||||
Three functions are available to provide handling of files recognised by
|
||||
@ -1347,6 +1348,8 @@ extension, for example to dispatch a file tt(text.ps) when executed as a
|
||||
command to an appropriate viewer.
|
||||
|
||||
startitem()
|
||||
findex(zsh-mime-setup)
|
||||
findex(zsh-mime-handler)
|
||||
xitem(tt(zsh-mime-setup [-flv]))
|
||||
item(tt(zsh-mime-handler))(
|
||||
These two functions use the files tt(~/.mime.types) and tt(/etc/mime.types),
|
||||
@ -1520,6 +1523,7 @@ example(text/html; /usr/bin/lynx '%s'; needsterminal)
|
||||
)
|
||||
enditem()
|
||||
)
|
||||
findex(pick-web-browser)
|
||||
item(tt(pick-web-browser))(
|
||||
This function is separate from the two MIME functions described above
|
||||
and can be assigned directly to a suffix:
|
||||
@ -1528,19 +1532,19 @@ example(autoload -U pick-web-browser
|
||||
alias -s html=pick-web-browser)
|
||||
|
||||
It is provided as an intelligent front end to dispatch a web browser.
|
||||
It will check if an X Windows display is available, and if so
|
||||
if there is already a browser running which can accept a remote
|
||||
It will check if an X Windows display is available, and if so if there
|
||||
is already a browser running on the display which can accept a remote
|
||||
connection. In that case, the file will be displayed in that browser;
|
||||
you should check explicitly if it has appeared in the running browser's
|
||||
window. Otherwise, it will start a new browser according to a builtin
|
||||
window. Otherwise, it will start a new browser according to a built-in
|
||||
set of preferences.
|
||||
|
||||
Alternatively, tt(pick-web-browser) can be run as a zsh script.
|
||||
|
||||
Two styles are available to customize the choice of browsers:
|
||||
tt(x-browsers) when running under the X Windows System, and
|
||||
tt(x-browsers) when running under the X Window System, and
|
||||
tt(tty-browsers) otherwise. These are arrays in decreasing order
|
||||
of preference consiting of the command name under which to start the
|
||||
of preference consisting of the command name under which to start the
|
||||
browser. They are looked up in the context tt(:mime:) (which may
|
||||
be extended in future, so appending `tt(*)' is recommended). For
|
||||
example,
|
||||
@ -1550,10 +1554,140 @@ example(zstyle ':mime:*' x-browsers opera konqueror netscape)
|
||||
specifies that tt(pick-web-browser) should first look for a runing
|
||||
instance of Opera, Konqueror or Netscape, in that order, and if it
|
||||
fails to find any should attempt to start Opera.
|
||||
|
||||
In addition, the style tt(command), if set, is used to pick the command
|
||||
used to open a page for a browser. The context is
|
||||
tt(:mime:browser:new:$browser:) to start a new browser or
|
||||
tt(:mime:browser:running:$browser:) to open a URL in a browser already
|
||||
runing on the current X display. The escape sequence tt(%b) in the
|
||||
style's value will be replaced by the browser, while tt(%u) will be
|
||||
replaced by the URL. If the style is not set, the default for all new
|
||||
instances is equivalent to tt(%b %u) and the defaults for using running
|
||||
browsers are equivalent to the values tt(kfmclient openURL %u) for
|
||||
Konqueror, tt(firefox -new-tab %u) for Firefox and tt(%b -remote
|
||||
"openUrl+LPAR()%u+RPAR()") for all others.
|
||||
)
|
||||
enditem()
|
||||
|
||||
texinode(Other Functions)()(MIME Functions)(User Contributions)
|
||||
texinode(Mathematical Functions)(Other Functions)(MIME Functions)(User Contributions)
|
||||
sect(Mathematical Functions)
|
||||
|
||||
startitem()
|
||||
findex(zcalc)
|
||||
item(tt(zcalc) [ var(expression) ... ])(
|
||||
A reasonably powerful calculator based on zsh's arithmetic evaluation
|
||||
facility. The syntax is similar to that of formulae in most programming
|
||||
languages; see
|
||||
ifzman(the section `Arithmetic Evaluation' in zmanref(zshmisc))\
|
||||
ifnzman(noderef(Arithmetic Evaluation)) for details. The mathematical
|
||||
library tt(zsh/mathfunc) will be loaded if it is available; see
|
||||
ifzman(the section `The zsh/mathfunc Module' in zmanref(zshmodules))\
|
||||
ifnzman(noderef(The zsh/mathfunc Module)). The mathematical functions
|
||||
correspond to the raw system libraries, so trigonometric functions are
|
||||
evaluated using radians, and so on.
|
||||
|
||||
Each line typed is evaluated as an expression. The prompt shows a number,
|
||||
which corresponds to a positional parameter where the result of that
|
||||
calculation is stored. For example, the result of the calculation on the
|
||||
line preceded by `tt(4> )' is available as tt($4). The last value
|
||||
calculated is available as tt(ans). Full command line editing, including
|
||||
the history of previous calculations, is available; the history is saved in
|
||||
the file tt(~/.zcalc_history). To exit, enter a blank line or type `tt(q)'
|
||||
on its own.
|
||||
|
||||
If arguments are given to tt(zcalc) on start up, they are used to prime the
|
||||
first few positional parameters. A visual indication of this is given when
|
||||
the calculator starts.
|
||||
|
||||
The constants tt(PI) (3.14159...) and tt(E) (2.71828...) are provided.
|
||||
Parameter assignment is possible, but note that all parameters will be put
|
||||
into the global namespace.
|
||||
|
||||
The output base can be initialised by passing the option `tt(-#)var(base)',
|
||||
for example `tt(zcalc -#16)' (the `tt(#)' may have to be quoted, depending
|
||||
on the globbing options set).
|
||||
|
||||
The prompt is configurable via the parameter tt(ZCALCPROMPT), which
|
||||
undergoes standard prompt expansion. The index of the current entry is
|
||||
stored locally in the first element of the array tt(psvar), which can be
|
||||
referred to in tt(ZCALCPROMPT) as `tt(%1v)'. The default prompt is
|
||||
`tt(%1v> )'.
|
||||
|
||||
The output precision may be specified within zcalc by special commands
|
||||
familiar from many calculators:
|
||||
startitem()
|
||||
item(tt(norm))(
|
||||
The default output format. It corresponds to the printf tt(%g)
|
||||
specification. Typically this shows six decimal digits.
|
||||
)
|
||||
item(tt(sci) var(digits))(
|
||||
Scientific notation, corresponding to the printf tt(%g) output format with
|
||||
the precision given by var(digits). This produces either fixed point or
|
||||
exponential notation depending on the value output.
|
||||
)
|
||||
item(tt(fix) var(digits))(
|
||||
Fixed point notation, corresponding to the printf tt(%f) output format with
|
||||
the precision given by var(digits).
|
||||
)
|
||||
item(tt(eng) var(digits))(
|
||||
Exponential notation, corresponding to the printf tt(%E) output format with
|
||||
the precision given by var(digits).
|
||||
)
|
||||
enditem()
|
||||
|
||||
Other special commands:
|
||||
startitem()
|
||||
item(tt(local) var(arg) ...)(
|
||||
Declare variables local to the function. Note that certain variables
|
||||
are used by the function for its own purposes. Other variables
|
||||
may be used, too, but they will be taken from or put into the global
|
||||
scope.
|
||||
)
|
||||
item(tt(function) var(name) [ var(body) ])(
|
||||
Define a mathematical function or (with no var(body)) delete it.
|
||||
The function is defined using tt(zmathfuncdef), see below.
|
||||
|
||||
Note that tt(zcalc) takes care of all quoting. Hence for example:
|
||||
|
||||
example(function cube $1 * $1 * $1)
|
||||
|
||||
defines a function to cube the sole argument.
|
||||
)
|
||||
item(tt([#)var(base)tt(]))(
|
||||
When this syntax appears on a line by itself, the default output radix
|
||||
is set to var(base). Use, for example, `tt([#16])' to display hexadecimal
|
||||
output preceded by an indication of the base, or `tt([##16])' just to
|
||||
display the raw number in the given base. Bases themselves are always
|
||||
specified in decimal. `tt([#])' restores the normal output format. Note
|
||||
that setting an output base suppresses floating point output; use `tt([#])'
|
||||
to return to normal operation.
|
||||
|
||||
)
|
||||
enditem()
|
||||
|
||||
See the comments in the function for a few extra tips.
|
||||
)
|
||||
findex(zmathfuncdef)
|
||||
item(tt(zmathfuncdef) var(mathfunc) [ var(body) ])(
|
||||
A convenient front end to tt(functions -M).
|
||||
|
||||
With two arguments, define a mathematical function named var(mathfunc)
|
||||
which can be used in any form of arithmetic evaluation. var(body)
|
||||
is a mathematical expression to implement the function. It may
|
||||
contain references to position parameters tt($1), tt($2), ...
|
||||
to refer to mandatory parameters and tt(${1:-)var(defvalue)tt(}) ...
|
||||
to refer to optional parameters. Note that the forms must be
|
||||
strictly adhered to for the function to calculate the correct number
|
||||
of arguments. The implementation is held in a shell function named
|
||||
tt(zsh_math_func_)var(mathfunc); usually the user will not need
|
||||
to refer to the shell function directly.
|
||||
|
||||
With one argument, remove the mathematical function var(mathfunc)
|
||||
as well as the shell function implementation.
|
||||
)
|
||||
enditem()
|
||||
|
||||
texinode(Other Functions)()(Mathematical Functions)(User Contributions)
|
||||
sect(Other Functions)
|
||||
|
||||
There are a large number of helpful functions in the tt(Functions/Misc)
|
||||
@ -1720,77 +1854,6 @@ This is a good choice in that example because no plain file can be named
|
||||
For details of the other tt(zargs) options, see zmanref(xargs) or run
|
||||
tt(zargs) with the tt(-)tt(-help) option.
|
||||
)
|
||||
findex(zcalc)
|
||||
item(tt(zcalc) [ var(expression) ... ])(
|
||||
A reasonably powerful calculator based on zsh's arithmetic evaluation
|
||||
facility. The syntax is similar to that of formulae in most programming
|
||||
languages; see
|
||||
ifzman(the section `Arithmetic Evaluation' in zmanref(zshmisc))\
|
||||
ifnzman(noderef(Arithmetic Evaluation)) for details. The mathematical
|
||||
library tt(zsh/mathfunc) will be loaded if it is available; see
|
||||
ifzman(the section `The zsh/mathfunc Module' in zmanref(zshmodules))\
|
||||
ifnzman(noderef(The zsh/mathfunc Module)). The mathematical functions
|
||||
correspond to the raw system libraries, so trigonometric functions are
|
||||
evaluated using radians, and so on.
|
||||
|
||||
Each line typed is evaluated as an expression. The prompt shows a number,
|
||||
which corresponds to a positional parameter where the result of that
|
||||
calculation is stored. For example, the result of the calculation on the
|
||||
line preceded by `tt(4> )' is available as tt($4). Full command line
|
||||
editing, including the history of previous calculations, is available; the
|
||||
history is saved in the file tt(~/.zcalc_history). To exit, enter a blank
|
||||
line or type `tt(q)' on its own.
|
||||
|
||||
If arguments are given to tt(zcalc) on start up, they are used to prime the
|
||||
first few positional parameters. A visual indication of this is given when
|
||||
the calculator starts.
|
||||
|
||||
The constants tt(PI) (3.14159...) and tt(E) (2.71828...) are provided.
|
||||
Parameter assignment is possible, but note that all parameters will be put
|
||||
into the global namespace.
|
||||
|
||||
An extra facility is provided for changing the default output base. Use,
|
||||
for example, `tt([#16])' to display hexadecimal output preceded by an
|
||||
indication of the base, or `tt([##16])' just to display the raw number in
|
||||
the given base. Bases themselves are always specified in decimal.
|
||||
`tt([#])' restores the normal output format. Note that setting an output
|
||||
base suppresses floating point output; use `tt([#])' to return to normal
|
||||
operation.
|
||||
|
||||
The output base can be initialised by passing the option `tt(-#)var(base)',
|
||||
for example `tt(zcalc -#16)' (the `tt(#)' may have to be quoted, depending
|
||||
on the globbing options set).
|
||||
|
||||
The prompt is configurable via the parameter tt(ZCALCPROMPT), which
|
||||
undergoes standard prompt expansion. The index of the current entry is
|
||||
stored locally in the first element of the array tt(psvar), which can be
|
||||
referred to in tt(ZCALCPROMPT) as `tt(%1v)'. The default prompt is
|
||||
`tt(%1v> )'.
|
||||
|
||||
The output precision may be specified within zcalc by special commands
|
||||
familiar from many calculators:
|
||||
startitem()
|
||||
item(tt(norm))(
|
||||
The default output format. It corresponds to the printf tt(%g)
|
||||
specification. Typically this shows six decimal digits.
|
||||
)
|
||||
item(tt(sci) var(digits))(
|
||||
Scientific notation, corresponding to the printf tt(%g) output format with
|
||||
the precision given by var(digits). This produces either fixed point or
|
||||
exponential notation depending on the value output.
|
||||
)
|
||||
item(tt(fix) var(digits))(
|
||||
Fixed point notation, corresponding to the printf tt(%f) output format with
|
||||
the precision given by var(digits).
|
||||
)
|
||||
item(tt(eng) var(digits))(
|
||||
Exponential notation, corresponding to the printf tt(%E) output format with
|
||||
the precision given by var(digits).
|
||||
)
|
||||
enditem()
|
||||
|
||||
See the comments in the function for a few extra tips.
|
||||
)
|
||||
findex(zed)
|
||||
xitem(tt(zed) [ tt(-f) ] var(name))
|
||||
item(tt(zed -b))(
|
||||
|
@ -22,6 +22,8 @@
|
||||
emulate -L zsh
|
||||
setopt extendedglob cbases nonomatch
|
||||
|
||||
zmodload -i zsh/zutil
|
||||
|
||||
local -a xbrowsers ttybrowsers
|
||||
|
||||
# X Windows browsers which might be running and can accept
|
||||
@ -38,7 +40,7 @@ zstyle -a :mime: tty-browsers ttybrowsers ||
|
||||
litc="-_./"
|
||||
|
||||
local -a windows remoteargs match mbegin mend
|
||||
local url browser
|
||||
local url browser command
|
||||
|
||||
url=$1
|
||||
if [[ -f $url ]]; then
|
||||
@ -80,22 +82,31 @@ if [[ -n $DISPLAY ]]; then
|
||||
|
||||
# Is any browser we've heard of running?
|
||||
for browser in $xbrowsers; do
|
||||
if [[ $windows[(I)(#i)$browser] -ne 0 ]]; then
|
||||
if [[ $browser = konqueror ]]; then
|
||||
# kfmclient is less hairy and better supported than direct
|
||||
# use of dcop. Run kfmclient --commands
|
||||
# for more information. Note that as konqueror is a fully
|
||||
# featured file manager, this will actually do complete
|
||||
# MIME handling, not just web pages.
|
||||
kfmclient openURL $url ||
|
||||
dcop $(dcop|grep konqueror) default openBrowserWindow $url
|
||||
elif [[ $browser = firefox ]]; then
|
||||
# open in new tab: should make this customizable
|
||||
$browser -new-tab $url
|
||||
# Some browser executables call themselves <browser>-bin
|
||||
if [[ $windows[(I)(#i)$browser(|[.-]bin)] -ne 0 ]]; then
|
||||
if zstyle -s ":mime:browser:running:${browser}:" command command; then
|
||||
# The (q)'s here and below are pure paranoia: no browser
|
||||
# name is going to include metacharacters, and we already
|
||||
# converted difficult characters in the URL to hex.
|
||||
zformat -f command $command b:${(q)browser} u:${(q)url}
|
||||
eval $command
|
||||
else
|
||||
# Mozilla bells and whistles are described at:
|
||||
# http://www.mozilla.org/unix/remote.html
|
||||
$browser -remote "openURL($url)"
|
||||
if [[ $browser = konqueror ]]; then
|
||||
# kfmclient is less hairy and better supported than direct
|
||||
# use of dcop. Run kfmclient --commands
|
||||
# for more information. Note that as konqueror is a fully
|
||||
# featured file manager, this will actually do complete
|
||||
# MIME handling, not just web pages.
|
||||
kfmclient openURL $url ||
|
||||
dcop $(dcop|grep konqueror) default openBrowserWindow $url
|
||||
elif [[ $browser = firefox ]]; then
|
||||
# open in new tab
|
||||
$browser -new-tab $url
|
||||
else
|
||||
# Mozilla bells and whistles are described at:
|
||||
# http://www.mozilla.org/unix/remote.html
|
||||
$browser -remote "openURL($url)"
|
||||
fi
|
||||
fi
|
||||
return
|
||||
fi
|
||||
@ -104,8 +115,13 @@ if [[ -n $DISPLAY ]]; then
|
||||
# Start our preferred X Windows browser in the background.
|
||||
for browser in $xbrowsers; do
|
||||
if eval "[[ =$browser != \\=$browser ]]"; then
|
||||
# The following is to make the job text more readable.
|
||||
eval ${(q)browser} ${(q)url} "&"
|
||||
if zstyle -s ":mime:browser:new:${browser}:" command command; then
|
||||
zformat -f command $command b:${(q)browser} u:${(q)url}
|
||||
eval $command "&"
|
||||
else
|
||||
# The following is to make the job text more readable.
|
||||
eval ${(q)browser} ${(q)url} "&"
|
||||
fi
|
||||
break
|
||||
fi
|
||||
done
|
||||
@ -113,7 +129,12 @@ else
|
||||
# Start up dumb terminal browser.
|
||||
for browser in $ttybrowsers; do
|
||||
if eval "[[ =$browser != \\=$browser ]]"; then
|
||||
$browser $url
|
||||
if zstyle -s ":mime:browser:new:${browser}" command command; then
|
||||
zformat -f command $command b:${(q)browser} u:${(q)url}
|
||||
eval $command
|
||||
else
|
||||
$browser $url
|
||||
fi
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
@ -3,4 +3,5 @@ DISTFILES_SRC='
|
||||
allopt getjobs mere relative zcalc zmv zargs
|
||||
checkmail harden nslookup run-help zed zrecompile
|
||||
colors is-at-least promptnl tetris zkbd zstyle+
|
||||
zmathfuncdef
|
||||
'
|
||||
|
@ -42,6 +42,13 @@
|
||||
# use the variables listed in the `local' and `integer' lines below
|
||||
# (translation: I can't be bothered to provide a sandbox).
|
||||
#
|
||||
# You can declare or delete math functions (implemented via zmathfuncdef):
|
||||
# 1> function cube $1 * $1 * $1
|
||||
# This has a single compulsory argument. Note the function takes care of
|
||||
# the punctuation. To delete the function, put nothing (at all) after
|
||||
# the function name:
|
||||
# 1> function cube
|
||||
#
|
||||
# Some constants are already available: (case sensitive as always):
|
||||
# PI pi, i.e. 3.1415926545897931
|
||||
# E e, i.e. 2.7182818284590455
|
||||
@ -86,6 +93,8 @@
|
||||
emulate -L zsh
|
||||
setopt extendedglob
|
||||
|
||||
# TODO: make local variables that shouldn't be visible in expressions
|
||||
# begin with _.
|
||||
local line ans base defbase forms match mbegin mend psvar optlist opt arg
|
||||
local compcontext="-math-"
|
||||
integer num outdigits outform=1
|
||||
@ -96,6 +105,7 @@ history -ap "${ZDOTDIR:-$HOME}/.zcalc_history"
|
||||
forms=( '%2$g' '%.*g' '%.*f' '%.*E' )
|
||||
|
||||
zmodload -i zsh/mathfunc 2>/dev/null
|
||||
autoload zmathfuncdef
|
||||
|
||||
: ${ZCALCPROMPT="%1v> "}
|
||||
|
||||
@ -167,34 +177,39 @@ while vared -cehp "${(%)ZCALCPROMPT}" line; do
|
||||
print -s -- $line
|
||||
|
||||
case ${${line##[[:blank:]]#}%%[[:blank:]]#} in
|
||||
q) # Exit if `q' on its own.
|
||||
(q) # Exit if `q' on its own.
|
||||
return 0
|
||||
;;
|
||||
norm) # restore output format to default
|
||||
(norm) # restore output format to default
|
||||
outform=1
|
||||
;;
|
||||
sci[[:blank:]]#(#b)(<->)(#B))
|
||||
(sci[[:blank:]]#(#b)(<->)(#B))
|
||||
outdigits=$match[1]
|
||||
outform=2
|
||||
;;
|
||||
fix[[:blank:]]#(#b)(<->)(#B))
|
||||
(fix[[:blank:]]#(#b)(<->)(#B))
|
||||
outdigits=$match[1]
|
||||
outform=3
|
||||
;;
|
||||
eng[[:blank:]]#(#b)(<->)(#B))
|
||||
(eng[[:blank:]]#(#b)(<->)(#B))
|
||||
outdigits=$match[1]
|
||||
outform=4
|
||||
;;
|
||||
local([[:blank:]]##*|))
|
||||
(local([[:blank:]]##*|))
|
||||
eval $line
|
||||
line=
|
||||
continue
|
||||
;;
|
||||
*)
|
||||
(function[[:blank:]]##(#b)([^[:blank:]]##)(|[[:blank:]]##([^[:blank:]]*)))
|
||||
zmathfuncdef $match[1] $match[3]
|
||||
line=
|
||||
continue
|
||||
;;
|
||||
(*)
|
||||
# Latest value is stored as a string, because it might be floating
|
||||
# point or integer --- we don't know till after the evaluation, and
|
||||
# arrays always store scalars anyway.
|
||||
#
|
||||
#
|
||||
# Since it's a string, we'd better make sure we know which
|
||||
# base it's in, so don't change that until we actually print it.
|
||||
eval "ans=\$(( $line ))"
|
||||
|
176
Src/builtin.c
176
Src/builtin.c
@ -46,7 +46,7 @@ static struct builtin builtins[] =
|
||||
BUILTIN(".", BINF_PSPECIAL, bin_dot, 1, -1, 0, NULL, NULL),
|
||||
BUILTIN(":", BINF_PSPECIAL, bin_true, 0, -1, 0, NULL, NULL),
|
||||
BUILTIN("alias", BINF_MAGICEQUALS | BINF_PLUSOPTS, bin_alias, 0, -1, 0, "Lgmrs", NULL),
|
||||
BUILTIN("autoload", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "tUXwkz", "u"),
|
||||
BUILTIN("autoload", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "ktUwXz", "u"),
|
||||
BUILTIN("bg", 0, bin_fg, 0, -1, BIN_BG, NULL, NULL),
|
||||
BUILTIN("break", BINF_PSPECIAL, bin_break, 0, 1, BIN_BREAK, NULL, NULL),
|
||||
BUILTIN("bye", 0, bin_break, 0, 1, BIN_EXIT, NULL, NULL),
|
||||
@ -72,7 +72,7 @@ static struct builtin builtins[] =
|
||||
BUILTIN("fc", 0, bin_fc, 0, -1, BIN_FC, "nlre:IRWAdDfEimpPa", NULL),
|
||||
BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, NULL),
|
||||
BUILTIN("float", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL, bin_typeset, 0, -1, 0, "E:%F:%HL:%R:%Z:%ghlprtux", "E"),
|
||||
BUILTIN("functions", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "kmtuUz", NULL),
|
||||
BUILTIN("functions", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "kmMtuUz", 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),
|
||||
@ -2476,6 +2476,43 @@ eval_autoload(Shfunc shf, char *name, Options ops, int func)
|
||||
(OPT_ISSET(ops,'z') ? 0 : 1)), 1);
|
||||
}
|
||||
|
||||
|
||||
/* List a user-defined math function. */
|
||||
static void
|
||||
listusermathfunc(MathFunc p)
|
||||
{
|
||||
int showargs;
|
||||
|
||||
if (p->module)
|
||||
showargs = 3;
|
||||
else if (p->maxargs != (p->minargs ? p->minargs : -1))
|
||||
showargs = 2;
|
||||
else if (p->minargs)
|
||||
showargs = 1;
|
||||
else
|
||||
showargs = 0;
|
||||
|
||||
printf("functions -M %s", p->name);
|
||||
if (showargs) {
|
||||
printf(" %d", p->minargs);
|
||||
showargs--;
|
||||
}
|
||||
if (showargs) {
|
||||
printf(" %d", p->maxargs);
|
||||
showargs--;
|
||||
}
|
||||
if (showargs) {
|
||||
/*
|
||||
* function names are not required to consist of ident characters
|
||||
*/
|
||||
putchar(' ');
|
||||
quotedzputs(p->module, stdout);
|
||||
showargs--;
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
|
||||
/* Display or change the attributes of shell functions. *
|
||||
* If called as autoload, it will define a new autoloaded *
|
||||
* (undefined) shell function. */
|
||||
@ -2522,6 +2559,141 @@ bin_functions(char *name, char **argv, Options ops, int func)
|
||||
if (OPT_PLUS(ops,'f') || OPT_ISSET(ops,'+'))
|
||||
pflags |= PRINT_NAMEONLY;
|
||||
|
||||
if (OPT_MINUS(ops,'M') || OPT_PLUS(ops,'M')) {
|
||||
MathFunc p, q;
|
||||
/*
|
||||
* Add/remove/list function as mathematical.
|
||||
*/
|
||||
if (on || off || pflags || OPT_ISSET(ops,'X') || OPT_ISSET(ops,'u')
|
||||
|| OPT_ISSET(ops,'U') || OPT_ISSET(ops,'w')) {
|
||||
zwarnnam(name, "invalid option(s)", NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
if (!*argv) {
|
||||
/* List functions. */
|
||||
queue_signals();
|
||||
for (p = mathfuncs; p; p = p->next)
|
||||
if (p->flags & MFF_USERFUNC)
|
||||
listusermathfunc(p);
|
||||
unqueue_signals();
|
||||
} else if (OPT_ISSET(ops,'m')) {
|
||||
/* List matching functions. */
|
||||
for (; *argv; argv++) {
|
||||
tokenize(*argv);
|
||||
if ((pprog = patcompile(*argv, PAT_STATIC, 0))) {
|
||||
queue_signals();
|
||||
for (p = mathfuncs, q = NULL; p; q = p, p = p->next) {
|
||||
MathFunc next;
|
||||
do {
|
||||
next = NULL;
|
||||
if ((p->flags & MFF_USERFUNC) &&
|
||||
pattry(pprog, p->name)) {
|
||||
if (OPT_PLUS(ops,'M')) {
|
||||
next = p->next;
|
||||
removemathfunc(q, p);
|
||||
p = next;
|
||||
} else
|
||||
listusermathfunc(p);
|
||||
}
|
||||
/* if we deleted one, retry with the new p */
|
||||
} while (next);
|
||||
}
|
||||
unqueue_signals();
|
||||
} else {
|
||||
untokenize(*argv);
|
||||
zwarnnam(name, "bad pattern : %s", *argv, 0);
|
||||
returnval = 1;
|
||||
}
|
||||
}
|
||||
} else if (OPT_PLUS(ops,'M')) {
|
||||
/* Delete functions. -m is allowed but is handled above. */
|
||||
for (; *argv; argv++) {
|
||||
queue_signals();
|
||||
for (p = mathfuncs, q = NULL; p; q = p, p = p->next) {
|
||||
if (!strcmp(p->name, *argv)) {
|
||||
if (!(p->flags & MFF_USERFUNC)) {
|
||||
zwarnnam(name, "+M %s: is a library function",
|
||||
*argv, 0);
|
||||
returnval = 1;
|
||||
break;
|
||||
}
|
||||
removemathfunc(q, p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
unqueue_signals();
|
||||
}
|
||||
} else {
|
||||
/* Add a function */
|
||||
int minargs = 0, maxargs = -1;
|
||||
char *funcname = *argv++;
|
||||
char *modname = NULL;
|
||||
char *ptr;
|
||||
|
||||
for (ptr = funcname; *ptr; ptr++)
|
||||
if (!iident(*ptr))
|
||||
break;
|
||||
if (idigit(*funcname) || funcname == ptr || *ptr) {
|
||||
zwarnnam(name, "-M %s: bad math function name", funcname, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (*argv) {
|
||||
minargs = (int)zstrtol(*argv, &ptr, 0);
|
||||
if (minargs < 0 || *ptr) {
|
||||
zwarnnam(name, "-M: invalid min number of arguments: %s",
|
||||
*argv, 0);
|
||||
return 1;
|
||||
}
|
||||
maxargs = minargs;
|
||||
argv++;
|
||||
}
|
||||
if (*argv) {
|
||||
maxargs = (int)zstrtol(*argv, &ptr, 0);
|
||||
if (maxargs < -1 ||
|
||||
(maxargs != -1 && maxargs < minargs) ||
|
||||
*ptr) {
|
||||
zwarnnam(name,
|
||||
"-M: invalid max number of arguments: %s",
|
||||
*argv, 0);
|
||||
return 1;
|
||||
}
|
||||
argv++;
|
||||
}
|
||||
if (*argv)
|
||||
modname = *argv++;
|
||||
if (*argv) {
|
||||
zwarnnam(name, "-M: too many arguments", NULL, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
p = (MathFunc)zshcalloc(sizeof(struct mathfunc));
|
||||
p->name = ztrdup(funcname);
|
||||
p->flags = MFF_USERFUNC;
|
||||
p->module = modname ? ztrdup(modname) : NULL;
|
||||
p->minargs = minargs;
|
||||
p->maxargs = maxargs;
|
||||
|
||||
queue_signals();
|
||||
for (q = mathfuncs; q; q = q->next) {
|
||||
if (!strcmp(q->name, funcname)) {
|
||||
zwarnnam(name, "-M %s: function already exists",
|
||||
funcname, 0);
|
||||
zsfree(p->name);
|
||||
zsfree(p->module);
|
||||
zfree(p, sizeof(struct mathfunc));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
p->next = mathfuncs;
|
||||
mathfuncs = p;
|
||||
unqueue_signals();
|
||||
}
|
||||
|
||||
return returnval;
|
||||
}
|
||||
|
||||
/* If no arguments given, we will print functions. If flags *
|
||||
* are given, we will print only functions containing these *
|
||||
* flags, else we'll print them all. */
|
||||
|
11
Src/exec.c
11
Src/exec.c
@ -142,7 +142,6 @@ mod_export Funcstack funcstack;
|
||||
|
||||
#define execerr() if (!forked) { lastval = 1; goto done; } else _exit(1)
|
||||
|
||||
static LinkList args;
|
||||
static int doneps4;
|
||||
static char *STTYval;
|
||||
|
||||
@ -464,7 +463,7 @@ isgooderr(int e, char *dir)
|
||||
|
||||
/**/
|
||||
void
|
||||
execute(UNUSED(Cmdnam cmdname), int dash, int defpath)
|
||||
execute(LinkList args, int dash, int defpath)
|
||||
{
|
||||
Cmdnam cn;
|
||||
char buf[MAXCMDLEN], buf2[MAXCMDLEN];
|
||||
@ -482,15 +481,12 @@ execute(UNUSED(Cmdnam cmdname), int dash, int defpath)
|
||||
* we first run the stty command with the value of this *
|
||||
* parameter as it arguments. */
|
||||
if ((s = STTYval) && isatty(0) && (GETPGRP() == getpid())) {
|
||||
LinkList exargs = args;
|
||||
char *t = tricat("stty", " ", s);
|
||||
|
||||
STTYval = 0; /* this prevents infinite recursion */
|
||||
zsfree(s);
|
||||
args = NULL;
|
||||
execstring(t, 1, 0);
|
||||
zsfree(t);
|
||||
args = exargs;
|
||||
} else if (s) {
|
||||
STTYval = 0;
|
||||
zsfree(s);
|
||||
@ -1827,6 +1823,7 @@ static void
|
||||
execcmd(Estate state, int input, int output, int how, int last1)
|
||||
{
|
||||
HashNode hn = NULL;
|
||||
LinkList args;
|
||||
LinkNode node;
|
||||
Redir fn;
|
||||
struct multio *mfds[10];
|
||||
@ -2638,7 +2635,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
||||
zsfree(STTYval);
|
||||
STTYval = 0;
|
||||
}
|
||||
execute((Cmdnam) hn, cflags & BINF_DASH, use_defpath);
|
||||
execute(args, cflags & BINF_DASH, use_defpath);
|
||||
} else { /* ( ... ) */
|
||||
DPUTS(varspc,
|
||||
"BUG: assignment before complex command");
|
||||
@ -4094,7 +4091,6 @@ execsave(void)
|
||||
struct execstack *es;
|
||||
|
||||
es = (struct execstack *) malloc(sizeof(struct execstack));
|
||||
es->args = args;
|
||||
es->list_pipe_pid = list_pipe_pid;
|
||||
es->nowait = nowait;
|
||||
es->pline_level = pline_level;
|
||||
@ -4122,7 +4118,6 @@ execrestore(void)
|
||||
struct execstack *en;
|
||||
|
||||
DPUTS(!exstack, "BUG: execrestore() without execsave()");
|
||||
args = exstack->args;
|
||||
list_pipe_pid = exstack->list_pipe_pid;
|
||||
nowait = exstack->nowait;
|
||||
pline_level = exstack->pline_level;
|
||||
|
64
Src/math.c
64
Src/math.c
@ -42,6 +42,14 @@ int noeval;
|
||||
/**/
|
||||
mod_export mnumber zero_mnumber;
|
||||
|
||||
/*
|
||||
* The last value we computed: note this isn't cleared
|
||||
* until the next computation, unlike unlike yyval.
|
||||
* Everything else is saved and returned to allow recursive calls.
|
||||
*/
|
||||
/**/
|
||||
mnumber lastmathval;
|
||||
|
||||
/* last input base we used */
|
||||
|
||||
/**/
|
||||
@ -582,22 +590,42 @@ callmathfunc(char *o)
|
||||
a[strlen(a) - 1] = '\0';
|
||||
|
||||
if ((f = getmathfunc(n, 1))) {
|
||||
if (f->flags & MFF_STR)
|
||||
if (f->flags & MFF_STR) {
|
||||
return f->sfunc(n, a, f->funcid);
|
||||
else {
|
||||
} else {
|
||||
int argc = 0;
|
||||
mnumber *argv = NULL, *q;
|
||||
mnumber *argv = NULL, *q, marg;
|
||||
LinkList l = newlinklist();
|
||||
LinkNode node;
|
||||
|
||||
if (f->flags & MFF_USERFUNC) {
|
||||
/* first argument is function name: always use mathfunc */
|
||||
addlinknode(l, n);
|
||||
}
|
||||
|
||||
while (iblank(*a))
|
||||
a++;
|
||||
while (*a) {
|
||||
if (*a) {
|
||||
argc++;
|
||||
q = (mnumber *) zhalloc(sizeof(mnumber));
|
||||
*q = mathevall(a, ARGPREC, &a);
|
||||
addlinknode(l, q);
|
||||
if (f->flags & MFF_USERFUNC) {
|
||||
/* need to pass strings */
|
||||
char *str;
|
||||
marg = mathevall(a, ARGPREC, &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 {
|
||||
q = (mnumber *) zhalloc(sizeof(mnumber));
|
||||
*q = mathevall(a, ARGPREC, &a);
|
||||
addlinknode(l, q);
|
||||
}
|
||||
if (errflag || mtok != COMMA)
|
||||
break;
|
||||
}
|
||||
@ -608,12 +636,24 @@ callmathfunc(char *o)
|
||||
if (!errflag) {
|
||||
if (argc >= f->minargs && (f->maxargs < 0 ||
|
||||
argc <= f->maxargs)) {
|
||||
if (argc) {
|
||||
q = argv = (mnumber *)zhalloc(argc * sizeof(mnumber));
|
||||
for (node = firstnode(l); node; incnode(node))
|
||||
*q++ = *(mnumber *)getdata(node);
|
||||
if (f->flags & MFF_USERFUNC) {
|
||||
char *shfnam = f->module ? f->module : n;
|
||||
Eprog prog = getshfunc(shfnam);
|
||||
if (prog == &dummy_eprog)
|
||||
zerr("no such function: %s", shfnam, 0);
|
||||
else {
|
||||
doshfunc(n, prog, l, 0, 1);
|
||||
return lastmathval;
|
||||
}
|
||||
} else {
|
||||
if (argc) {
|
||||
q = argv =
|
||||
(mnumber *)zhalloc(argc * sizeof(mnumber));
|
||||
for (node = firstnode(l); node; incnode(node))
|
||||
*q++ = *(mnumber *)getdata(node);
|
||||
}
|
||||
return f->nfunc(n, argc, argv, f->funcid);
|
||||
}
|
||||
return f->nfunc(n, argc, argv, f->funcid);
|
||||
} else
|
||||
zerr("wrong number of arguments: %s", o, 0);
|
||||
}
|
||||
@ -1013,7 +1053,7 @@ mathevall(char *s, int prek, char **ep)
|
||||
sp = xsp;
|
||||
stack = xstack;
|
||||
}
|
||||
return ret;
|
||||
return lastmathval = ret;
|
||||
}
|
||||
|
||||
|
||||
|
10
Src/module.c
10
Src/module.c
@ -1384,7 +1384,7 @@ bin_zmodload_math(char *nam, char **args, Options ops)
|
||||
MathFunc p;
|
||||
|
||||
for (p = mathfuncs; p; p = p->next) {
|
||||
if (p->module) {
|
||||
if (!(p->flags & MFF_USERFUNC) && p->module) {
|
||||
if (OPT_ISSET(ops,'L')) {
|
||||
fputs("zmodload -af", stdout);
|
||||
printf(" %s %s\n", p->module, p->name);
|
||||
@ -2085,7 +2085,8 @@ add_autoparam(char *nam, char *module)
|
||||
MathFunc mathfuncs;
|
||||
|
||||
/**/
|
||||
static void removemathfunc(MathFunc previous, MathFunc current)
|
||||
void
|
||||
removemathfunc(MathFunc previous, MathFunc current)
|
||||
{
|
||||
if (previous)
|
||||
previous->next = current->next;
|
||||
@ -2105,7 +2106,7 @@ getmathfunc(char *name, int autol)
|
||||
|
||||
for (p = mathfuncs; p; q = p, p = p->next)
|
||||
if (!strcmp(name, p->name)) {
|
||||
if (autol && p->module) {
|
||||
if (autol && p->module && !(p->flags & MFF_USERFUNC)) {
|
||||
char *n = dupstring(p->module);
|
||||
|
||||
removemathfunc(q, p);
|
||||
@ -2131,7 +2132,7 @@ addmathfunc(MathFunc f)
|
||||
|
||||
for (p = mathfuncs; p; q = p, p = p->next)
|
||||
if (!strcmp(f->name, p->name)) {
|
||||
if (p->module) {
|
||||
if (p->module && !(p->flags & MFF_USERFUNC)) {
|
||||
/*
|
||||
* Autoloadable, replace.
|
||||
*/
|
||||
@ -2206,6 +2207,7 @@ deletemathfunc(MathFunc f)
|
||||
else
|
||||
mathfuncs = f->next;
|
||||
|
||||
/* the following applies to both unloaded and user-defined functions */
|
||||
if (f->module) {
|
||||
zsfree(f->name);
|
||||
zsfree(f->module);
|
||||
|
@ -86,8 +86,12 @@ struct mathfunc {
|
||||
int funcid;
|
||||
};
|
||||
|
||||
/* Math function takes a string argument */
|
||||
#define MFF_STR 1
|
||||
/* Math function has been loaded from library */
|
||||
#define MFF_ADDED 2
|
||||
/* Math function is implemented by a shell function */
|
||||
#define MFF_USERFUNC 4
|
||||
|
||||
#define NUMMATHFUNC(name, func, min, max, id) \
|
||||
{ NULL, name, 0, func, NULL, NULL, min, max, id }
|
||||
@ -815,7 +819,6 @@ struct process {
|
||||
struct execstack {
|
||||
struct execstack *next;
|
||||
|
||||
LinkList args;
|
||||
pid_t list_pipe_pid;
|
||||
int nowait;
|
||||
int pline_level;
|
||||
|
@ -11,3 +11,62 @@
|
||||
foo
|
||||
0:Function definition without braces
|
||||
>bar
|
||||
|
||||
functions -M m1
|
||||
m1() { (( $# )) }
|
||||
print $(( m1() ))
|
||||
print $(( m1(1) ))
|
||||
print $(( m1(1,2) ))
|
||||
0:User-defined math functions, argument handling
|
||||
>0
|
||||
>1
|
||||
>2
|
||||
|
||||
functions -M m2
|
||||
m2() {
|
||||
integer sum
|
||||
local val
|
||||
for val in $*; do
|
||||
(( sum += $val ))
|
||||
done
|
||||
}
|
||||
print $(( m2(1) ))
|
||||
print $(( m2(1,3+3,4**2) ))
|
||||
0:User-defined math functions, complex argument handling
|
||||
>1
|
||||
>23
|
||||
|
||||
functions -M m3 1 2
|
||||
m3() { (( 1 )) }
|
||||
print zero
|
||||
(print $(( m3() )))
|
||||
print one
|
||||
print $(( m3(1) ))
|
||||
print two
|
||||
print $(( m3(1,2) ))
|
||||
print three
|
||||
(print $(( m3(1,2,3) )))
|
||||
1:User-defined math functions, argument checking
|
||||
>zero
|
||||
>one
|
||||
>1
|
||||
>two
|
||||
>1
|
||||
>three
|
||||
?(eval):4: wrong number of arguments: m3()
|
||||
?(eval):10: wrong number of arguments: m3(1,2,3)
|
||||
|
||||
functions -M m4 0 0 testmathfunc
|
||||
functions -M m5 0 0 testmathfunc
|
||||
testmathfunc() {
|
||||
if [[ $0 = m4 ]]; then
|
||||
(( 4 ))
|
||||
else
|
||||
(( 5 ))
|
||||
fi
|
||||
}
|
||||
print $(( m4() ))
|
||||
print $(( m5() ))
|
||||
0:User-defined math functions, multiple interfaces
|
||||
>4
|
||||
>5
|
||||
|
Loading…
Reference in New Issue
Block a user