mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-12-13 08:01:27 +01: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 changed files with 568 additions and 137 deletions
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>
|
2006-04-14 Doug Kearns <djkea2@gus.gscit.monash.edu.au>
|
||||||
|
|
||||||
* unposted: Completion/Unix/Command/_raggle: update for version
|
* 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.
|
point numbers are not permitted.
|
||||||
)
|
)
|
||||||
findex(functions)
|
findex(functions)
|
||||||
item(tt(functions) [ {tt(PLUS())|tt(-)}tt(UXkmtuz) ] [ var(name) ... ])(
|
xitem(tt(functions) [ {tt(PLUS())|tt(-)}tt(UXkmtuz) ] [ var(name) ... ])
|
||||||
Equivalent to tt(typeset -f).
|
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)
|
module(getcap)(zsh/cap)
|
||||||
findex(getln)
|
findex(getln)
|
||||||
|
|
@ -652,8 +696,10 @@ tt(kill -IO) and tt(kill -POLL) have the same effect.
|
||||||
findex(let)
|
findex(let)
|
||||||
item(tt(let) var(arg) ...)(
|
item(tt(let) var(arg) ...)(
|
||||||
Evaluate each var(arg) as an arithmetic expression.
|
Evaluate each var(arg) as an arithmetic expression.
|
||||||
See noderef(Arithmetic Evaluation) for a description
|
See
|
||||||
of arithmetic expressions. The exit status is 0 if the
|
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.
|
value of the last expression is nonzero, and 1 otherwise.
|
||||||
)
|
)
|
||||||
findex(limit)
|
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,
|
specifiers, if the corresponding argument starts with a quote character,
|
||||||
the numeric value of the following character is used as the number to
|
the numeric value of the following character is used as the number to
|
||||||
print otherwise the argument is evaluated as an arithmetic expression. See
|
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
|
expressions. With `tt(%n)', the corresponding argument is taken as an
|
||||||
identifier which is created as an integer parameter.
|
identifier which is created as an integer parameter.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ menu(Prompt Themes)
|
||||||
menu(ZLE Functions)
|
menu(ZLE Functions)
|
||||||
menu(Exception Handling)
|
menu(Exception Handling)
|
||||||
menu(MIME Functions)
|
menu(MIME Functions)
|
||||||
|
menu(Mathematical Functions)
|
||||||
menu(Other Functions)
|
menu(Other Functions)
|
||||||
endmenu()
|
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
|
start of the outermost layer of any code that uses exception handling will
|
||||||
eliminate this problem.
|
eliminate this problem.
|
||||||
|
|
||||||
texinode(MIME Functions)(Other Functions)(Exception Handling)(User Contributions)
|
texinode(MIME Functions)(Mathematical Functions)(Exception Handling)(User Contributions)
|
||||||
sect(MIME Functions)
|
sect(MIME Functions)
|
||||||
|
|
||||||
Three functions are available to provide handling of files recognised by
|
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.
|
command to an appropriate viewer.
|
||||||
|
|
||||||
startitem()
|
startitem()
|
||||||
|
findex(zsh-mime-setup)
|
||||||
|
findex(zsh-mime-handler)
|
||||||
xitem(tt(zsh-mime-setup [-flv]))
|
xitem(tt(zsh-mime-setup [-flv]))
|
||||||
item(tt(zsh-mime-handler))(
|
item(tt(zsh-mime-handler))(
|
||||||
These two functions use the files tt(~/.mime.types) and tt(/etc/mime.types),
|
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()
|
enditem()
|
||||||
)
|
)
|
||||||
|
findex(pick-web-browser)
|
||||||
item(tt(pick-web-browser))(
|
item(tt(pick-web-browser))(
|
||||||
This function is separate from the two MIME functions described above
|
This function is separate from the two MIME functions described above
|
||||||
and can be assigned directly to a suffix:
|
and can be assigned directly to a suffix:
|
||||||
|
|
@ -1528,19 +1532,19 @@ example(autoload -U pick-web-browser
|
||||||
alias -s html=pick-web-browser)
|
alias -s html=pick-web-browser)
|
||||||
|
|
||||||
It is provided as an intelligent front end to dispatch a 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
|
It will check if an X Windows display is available, and if so if there
|
||||||
if there is already a browser running which can accept a remote
|
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;
|
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
|
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.
|
set of preferences.
|
||||||
|
|
||||||
Alternatively, tt(pick-web-browser) can be run as a zsh script.
|
Alternatively, tt(pick-web-browser) can be run as a zsh script.
|
||||||
|
|
||||||
Two styles are available to customize the choice of browsers:
|
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
|
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
|
browser. They are looked up in the context tt(:mime:) (which may
|
||||||
be extended in future, so appending `tt(*)' is recommended). For
|
be extended in future, so appending `tt(*)' is recommended). For
|
||||||
example,
|
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
|
specifies that tt(pick-web-browser) should first look for a runing
|
||||||
instance of Opera, Konqueror or Netscape, in that order, and if it
|
instance of Opera, Konqueror or Netscape, in that order, and if it
|
||||||
fails to find any should attempt to start Opera.
|
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()
|
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)
|
sect(Other Functions)
|
||||||
|
|
||||||
There are a large number of helpful functions in the tt(Functions/Misc)
|
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
|
For details of the other tt(zargs) options, see zmanref(xargs) or run
|
||||||
tt(zargs) with the tt(-)tt(-help) option.
|
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)
|
findex(zed)
|
||||||
xitem(tt(zed) [ tt(-f) ] var(name))
|
xitem(tt(zed) [ tt(-f) ] var(name))
|
||||||
item(tt(zed -b))(
|
item(tt(zed -b))(
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@
|
||||||
emulate -L zsh
|
emulate -L zsh
|
||||||
setopt extendedglob cbases nonomatch
|
setopt extendedglob cbases nonomatch
|
||||||
|
|
||||||
|
zmodload -i zsh/zutil
|
||||||
|
|
||||||
local -a xbrowsers ttybrowsers
|
local -a xbrowsers ttybrowsers
|
||||||
|
|
||||||
# X Windows browsers which might be running and can accept
|
# X Windows browsers which might be running and can accept
|
||||||
|
|
@ -38,7 +40,7 @@ zstyle -a :mime: tty-browsers ttybrowsers ||
|
||||||
litc="-_./"
|
litc="-_./"
|
||||||
|
|
||||||
local -a windows remoteargs match mbegin mend
|
local -a windows remoteargs match mbegin mend
|
||||||
local url browser
|
local url browser command
|
||||||
|
|
||||||
url=$1
|
url=$1
|
||||||
if [[ -f $url ]]; then
|
if [[ -f $url ]]; then
|
||||||
|
|
@ -80,22 +82,31 @@ if [[ -n $DISPLAY ]]; then
|
||||||
|
|
||||||
# Is any browser we've heard of running?
|
# Is any browser we've heard of running?
|
||||||
for browser in $xbrowsers; do
|
for browser in $xbrowsers; do
|
||||||
if [[ $windows[(I)(#i)$browser] -ne 0 ]]; then
|
# Some browser executables call themselves <browser>-bin
|
||||||
if [[ $browser = konqueror ]]; then
|
if [[ $windows[(I)(#i)$browser(|[.-]bin)] -ne 0 ]]; then
|
||||||
# kfmclient is less hairy and better supported than direct
|
if zstyle -s ":mime:browser:running:${browser}:" command command; then
|
||||||
# use of dcop. Run kfmclient --commands
|
# The (q)'s here and below are pure paranoia: no browser
|
||||||
# for more information. Note that as konqueror is a fully
|
# name is going to include metacharacters, and we already
|
||||||
# featured file manager, this will actually do complete
|
# converted difficult characters in the URL to hex.
|
||||||
# MIME handling, not just web pages.
|
zformat -f command $command b:${(q)browser} u:${(q)url}
|
||||||
kfmclient openURL $url ||
|
eval $command
|
||||||
dcop $(dcop|grep konqueror) default openBrowserWindow $url
|
|
||||||
elif [[ $browser = firefox ]]; then
|
|
||||||
# open in new tab: should make this customizable
|
|
||||||
$browser -new-tab $url
|
|
||||||
else
|
else
|
||||||
# Mozilla bells and whistles are described at:
|
if [[ $browser = konqueror ]]; then
|
||||||
# http://www.mozilla.org/unix/remote.html
|
# kfmclient is less hairy and better supported than direct
|
||||||
$browser -remote "openURL($url)"
|
# 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
|
fi
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
@ -104,8 +115,13 @@ if [[ -n $DISPLAY ]]; then
|
||||||
# Start our preferred X Windows browser in the background.
|
# Start our preferred X Windows browser in the background.
|
||||||
for browser in $xbrowsers; do
|
for browser in $xbrowsers; do
|
||||||
if eval "[[ =$browser != \\=$browser ]]"; then
|
if eval "[[ =$browser != \\=$browser ]]"; then
|
||||||
# The following is to make the job text more readable.
|
if zstyle -s ":mime:browser:new:${browser}:" command command; then
|
||||||
eval ${(q)browser} ${(q)url} "&"
|
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
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
@ -113,7 +129,12 @@ else
|
||||||
# Start up dumb terminal browser.
|
# Start up dumb terminal browser.
|
||||||
for browser in $ttybrowsers; do
|
for browser in $ttybrowsers; do
|
||||||
if eval "[[ =$browser != \\=$browser ]]"; then
|
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
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
|
||||||
|
|
@ -3,4 +3,5 @@ DISTFILES_SRC='
|
||||||
allopt getjobs mere relative zcalc zmv zargs
|
allopt getjobs mere relative zcalc zmv zargs
|
||||||
checkmail harden nslookup run-help zed zrecompile
|
checkmail harden nslookup run-help zed zrecompile
|
||||||
colors is-at-least promptnl tetris zkbd zstyle+
|
colors is-at-least promptnl tetris zkbd zstyle+
|
||||||
|
zmathfuncdef
|
||||||
'
|
'
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,13 @@
|
||||||
# use the variables listed in the `local' and `integer' lines below
|
# use the variables listed in the `local' and `integer' lines below
|
||||||
# (translation: I can't be bothered to provide a sandbox).
|
# (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):
|
# Some constants are already available: (case sensitive as always):
|
||||||
# PI pi, i.e. 3.1415926545897931
|
# PI pi, i.e. 3.1415926545897931
|
||||||
# E e, i.e. 2.7182818284590455
|
# E e, i.e. 2.7182818284590455
|
||||||
|
|
@ -86,6 +93,8 @@
|
||||||
emulate -L zsh
|
emulate -L zsh
|
||||||
setopt extendedglob
|
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 line ans base defbase forms match mbegin mend psvar optlist opt arg
|
||||||
local compcontext="-math-"
|
local compcontext="-math-"
|
||||||
integer num outdigits outform=1
|
integer num outdigits outform=1
|
||||||
|
|
@ -96,6 +105,7 @@ history -ap "${ZDOTDIR:-$HOME}/.zcalc_history"
|
||||||
forms=( '%2$g' '%.*g' '%.*f' '%.*E' )
|
forms=( '%2$g' '%.*g' '%.*f' '%.*E' )
|
||||||
|
|
||||||
zmodload -i zsh/mathfunc 2>/dev/null
|
zmodload -i zsh/mathfunc 2>/dev/null
|
||||||
|
autoload zmathfuncdef
|
||||||
|
|
||||||
: ${ZCALCPROMPT="%1v> "}
|
: ${ZCALCPROMPT="%1v> "}
|
||||||
|
|
||||||
|
|
@ -167,30 +177,35 @@ while vared -cehp "${(%)ZCALCPROMPT}" line; do
|
||||||
print -s -- $line
|
print -s -- $line
|
||||||
|
|
||||||
case ${${line##[[:blank:]]#}%%[[:blank:]]#} in
|
case ${${line##[[:blank:]]#}%%[[:blank:]]#} in
|
||||||
q) # Exit if `q' on its own.
|
(q) # Exit if `q' on its own.
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
norm) # restore output format to default
|
(norm) # restore output format to default
|
||||||
outform=1
|
outform=1
|
||||||
;;
|
;;
|
||||||
sci[[:blank:]]#(#b)(<->)(#B))
|
(sci[[:blank:]]#(#b)(<->)(#B))
|
||||||
outdigits=$match[1]
|
outdigits=$match[1]
|
||||||
outform=2
|
outform=2
|
||||||
;;
|
;;
|
||||||
fix[[:blank:]]#(#b)(<->)(#B))
|
(fix[[:blank:]]#(#b)(<->)(#B))
|
||||||
outdigits=$match[1]
|
outdigits=$match[1]
|
||||||
outform=3
|
outform=3
|
||||||
;;
|
;;
|
||||||
eng[[:blank:]]#(#b)(<->)(#B))
|
(eng[[:blank:]]#(#b)(<->)(#B))
|
||||||
outdigits=$match[1]
|
outdigits=$match[1]
|
||||||
outform=4
|
outform=4
|
||||||
;;
|
;;
|
||||||
local([[:blank:]]##*|))
|
(local([[:blank:]]##*|))
|
||||||
eval $line
|
eval $line
|
||||||
line=
|
line=
|
||||||
continue
|
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
|
# Latest value is stored as a string, because it might be floating
|
||||||
# point or integer --- we don't know till after the evaluation, and
|
# point or integer --- we don't know till after the evaluation, and
|
||||||
# arrays always store scalars anyway.
|
# arrays always store scalars anyway.
|
||||||
|
|
|
||||||
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_dot, 1, -1, 0, NULL, NULL),
|
||||||
BUILTIN(":", BINF_PSPECIAL, bin_true, 0, -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("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("bg", 0, bin_fg, 0, -1, BIN_BG, NULL, NULL),
|
||||||
BUILTIN("break", BINF_PSPECIAL, bin_break, 0, 1, BIN_BREAK, 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),
|
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("fc", 0, bin_fc, 0, -1, BIN_FC, "nlre:IRWAdDfEimpPa", NULL),
|
||||||
BUILTIN("fg", 0, bin_fg, 0, -1, BIN_FG, NULL, 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("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("getln", 0, bin_read, 0, -1, 0, "ecnAlE", "zr"),
|
||||||
BUILTIN("getopts", 0, bin_getopts, 2, -1, 0, NULL, NULL),
|
BUILTIN("getopts", 0, bin_getopts, 2, -1, 0, NULL, NULL),
|
||||||
BUILTIN("hash", BINF_MAGICEQUALS, bin_hash, 0, -1, 0, "Ldfmrv", 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);
|
(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. *
|
/* Display or change the attributes of shell functions. *
|
||||||
* If called as autoload, it will define a new autoloaded *
|
* If called as autoload, it will define a new autoloaded *
|
||||||
* (undefined) shell function. */
|
* (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,'+'))
|
if (OPT_PLUS(ops,'f') || OPT_ISSET(ops,'+'))
|
||||||
pflags |= PRINT_NAMEONLY;
|
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 *
|
/* If no arguments given, we will print functions. If flags *
|
||||||
* are given, we will print only functions containing these *
|
* are given, we will print only functions containing these *
|
||||||
* flags, else we'll print them all. */
|
* 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)
|
#define execerr() if (!forked) { lastval = 1; goto done; } else _exit(1)
|
||||||
|
|
||||||
static LinkList args;
|
|
||||||
static int doneps4;
|
static int doneps4;
|
||||||
static char *STTYval;
|
static char *STTYval;
|
||||||
|
|
||||||
|
|
@ -464,7 +463,7 @@ isgooderr(int e, char *dir)
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
void
|
void
|
||||||
execute(UNUSED(Cmdnam cmdname), int dash, int defpath)
|
execute(LinkList args, int dash, int defpath)
|
||||||
{
|
{
|
||||||
Cmdnam cn;
|
Cmdnam cn;
|
||||||
char buf[MAXCMDLEN], buf2[MAXCMDLEN];
|
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 *
|
* we first run the stty command with the value of this *
|
||||||
* parameter as it arguments. */
|
* parameter as it arguments. */
|
||||||
if ((s = STTYval) && isatty(0) && (GETPGRP() == getpid())) {
|
if ((s = STTYval) && isatty(0) && (GETPGRP() == getpid())) {
|
||||||
LinkList exargs = args;
|
|
||||||
char *t = tricat("stty", " ", s);
|
char *t = tricat("stty", " ", s);
|
||||||
|
|
||||||
STTYval = 0; /* this prevents infinite recursion */
|
STTYval = 0; /* this prevents infinite recursion */
|
||||||
zsfree(s);
|
zsfree(s);
|
||||||
args = NULL;
|
|
||||||
execstring(t, 1, 0);
|
execstring(t, 1, 0);
|
||||||
zsfree(t);
|
zsfree(t);
|
||||||
args = exargs;
|
|
||||||
} else if (s) {
|
} else if (s) {
|
||||||
STTYval = 0;
|
STTYval = 0;
|
||||||
zsfree(s);
|
zsfree(s);
|
||||||
|
|
@ -1827,6 +1823,7 @@ static void
|
||||||
execcmd(Estate state, int input, int output, int how, int last1)
|
execcmd(Estate state, int input, int output, int how, int last1)
|
||||||
{
|
{
|
||||||
HashNode hn = NULL;
|
HashNode hn = NULL;
|
||||||
|
LinkList args;
|
||||||
LinkNode node;
|
LinkNode node;
|
||||||
Redir fn;
|
Redir fn;
|
||||||
struct multio *mfds[10];
|
struct multio *mfds[10];
|
||||||
|
|
@ -2638,7 +2635,7 @@ execcmd(Estate state, int input, int output, int how, int last1)
|
||||||
zsfree(STTYval);
|
zsfree(STTYval);
|
||||||
STTYval = 0;
|
STTYval = 0;
|
||||||
}
|
}
|
||||||
execute((Cmdnam) hn, cflags & BINF_DASH, use_defpath);
|
execute(args, cflags & BINF_DASH, use_defpath);
|
||||||
} else { /* ( ... ) */
|
} else { /* ( ... ) */
|
||||||
DPUTS(varspc,
|
DPUTS(varspc,
|
||||||
"BUG: assignment before complex command");
|
"BUG: assignment before complex command");
|
||||||
|
|
@ -4094,7 +4091,6 @@ execsave(void)
|
||||||
struct execstack *es;
|
struct execstack *es;
|
||||||
|
|
||||||
es = (struct execstack *) malloc(sizeof(struct execstack));
|
es = (struct execstack *) malloc(sizeof(struct execstack));
|
||||||
es->args = args;
|
|
||||||
es->list_pipe_pid = list_pipe_pid;
|
es->list_pipe_pid = list_pipe_pid;
|
||||||
es->nowait = nowait;
|
es->nowait = nowait;
|
||||||
es->pline_level = pline_level;
|
es->pline_level = pline_level;
|
||||||
|
|
@ -4122,7 +4118,6 @@ execrestore(void)
|
||||||
struct execstack *en;
|
struct execstack *en;
|
||||||
|
|
||||||
DPUTS(!exstack, "BUG: execrestore() without execsave()");
|
DPUTS(!exstack, "BUG: execrestore() without execsave()");
|
||||||
args = exstack->args;
|
|
||||||
list_pipe_pid = exstack->list_pipe_pid;
|
list_pipe_pid = exstack->list_pipe_pid;
|
||||||
nowait = exstack->nowait;
|
nowait = exstack->nowait;
|
||||||
pline_level = exstack->pline_level;
|
pline_level = exstack->pline_level;
|
||||||
|
|
|
||||||
64
Src/math.c
64
Src/math.c
|
|
@ -42,6 +42,14 @@ int noeval;
|
||||||
/**/
|
/**/
|
||||||
mod_export mnumber zero_mnumber;
|
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 */
|
/* last input base we used */
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
|
|
@ -582,22 +590,42 @@ callmathfunc(char *o)
|
||||||
a[strlen(a) - 1] = '\0';
|
a[strlen(a) - 1] = '\0';
|
||||||
|
|
||||||
if ((f = getmathfunc(n, 1))) {
|
if ((f = getmathfunc(n, 1))) {
|
||||||
if (f->flags & MFF_STR)
|
if (f->flags & MFF_STR) {
|
||||||
return f->sfunc(n, a, f->funcid);
|
return f->sfunc(n, a, f->funcid);
|
||||||
else {
|
} else {
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
mnumber *argv = NULL, *q;
|
mnumber *argv = NULL, *q, marg;
|
||||||
LinkList l = newlinklist();
|
LinkList l = newlinklist();
|
||||||
LinkNode node;
|
LinkNode node;
|
||||||
|
|
||||||
|
if (f->flags & MFF_USERFUNC) {
|
||||||
|
/* first argument is function name: always use mathfunc */
|
||||||
|
addlinknode(l, n);
|
||||||
|
}
|
||||||
|
|
||||||
while (iblank(*a))
|
while (iblank(*a))
|
||||||
a++;
|
a++;
|
||||||
while (*a) {
|
while (*a) {
|
||||||
if (*a) {
|
if (*a) {
|
||||||
argc++;
|
argc++;
|
||||||
q = (mnumber *) zhalloc(sizeof(mnumber));
|
if (f->flags & MFF_USERFUNC) {
|
||||||
*q = mathevall(a, ARGPREC, &a);
|
/* need to pass strings */
|
||||||
addlinknode(l, q);
|
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)
|
if (errflag || mtok != COMMA)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -608,12 +636,24 @@ callmathfunc(char *o)
|
||||||
if (!errflag) {
|
if (!errflag) {
|
||||||
if (argc >= f->minargs && (f->maxargs < 0 ||
|
if (argc >= f->minargs && (f->maxargs < 0 ||
|
||||||
argc <= f->maxargs)) {
|
argc <= f->maxargs)) {
|
||||||
if (argc) {
|
if (f->flags & MFF_USERFUNC) {
|
||||||
q = argv = (mnumber *)zhalloc(argc * sizeof(mnumber));
|
char *shfnam = f->module ? f->module : n;
|
||||||
for (node = firstnode(l); node; incnode(node))
|
Eprog prog = getshfunc(shfnam);
|
||||||
*q++ = *(mnumber *)getdata(node);
|
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
|
} else
|
||||||
zerr("wrong number of arguments: %s", o, 0);
|
zerr("wrong number of arguments: %s", o, 0);
|
||||||
}
|
}
|
||||||
|
|
@ -1013,7 +1053,7 @@ mathevall(char *s, int prek, char **ep)
|
||||||
sp = xsp;
|
sp = xsp;
|
||||||
stack = xstack;
|
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;
|
MathFunc p;
|
||||||
|
|
||||||
for (p = mathfuncs; p; p = p->next) {
|
for (p = mathfuncs; p; p = p->next) {
|
||||||
if (p->module) {
|
if (!(p->flags & MFF_USERFUNC) && p->module) {
|
||||||
if (OPT_ISSET(ops,'L')) {
|
if (OPT_ISSET(ops,'L')) {
|
||||||
fputs("zmodload -af", stdout);
|
fputs("zmodload -af", stdout);
|
||||||
printf(" %s %s\n", p->module, p->name);
|
printf(" %s %s\n", p->module, p->name);
|
||||||
|
|
@ -2085,7 +2085,8 @@ add_autoparam(char *nam, char *module)
|
||||||
MathFunc mathfuncs;
|
MathFunc mathfuncs;
|
||||||
|
|
||||||
/**/
|
/**/
|
||||||
static void removemathfunc(MathFunc previous, MathFunc current)
|
void
|
||||||
|
removemathfunc(MathFunc previous, MathFunc current)
|
||||||
{
|
{
|
||||||
if (previous)
|
if (previous)
|
||||||
previous->next = current->next;
|
previous->next = current->next;
|
||||||
|
|
@ -2105,7 +2106,7 @@ getmathfunc(char *name, int autol)
|
||||||
|
|
||||||
for (p = mathfuncs; p; q = p, p = p->next)
|
for (p = mathfuncs; p; q = p, p = p->next)
|
||||||
if (!strcmp(name, p->name)) {
|
if (!strcmp(name, p->name)) {
|
||||||
if (autol && p->module) {
|
if (autol && p->module && !(p->flags & MFF_USERFUNC)) {
|
||||||
char *n = dupstring(p->module);
|
char *n = dupstring(p->module);
|
||||||
|
|
||||||
removemathfunc(q, p);
|
removemathfunc(q, p);
|
||||||
|
|
@ -2131,7 +2132,7 @@ addmathfunc(MathFunc f)
|
||||||
|
|
||||||
for (p = mathfuncs; p; q = p, p = p->next)
|
for (p = mathfuncs; p; q = p, p = p->next)
|
||||||
if (!strcmp(f->name, p->name)) {
|
if (!strcmp(f->name, p->name)) {
|
||||||
if (p->module) {
|
if (p->module && !(p->flags & MFF_USERFUNC)) {
|
||||||
/*
|
/*
|
||||||
* Autoloadable, replace.
|
* Autoloadable, replace.
|
||||||
*/
|
*/
|
||||||
|
|
@ -2206,6 +2207,7 @@ deletemathfunc(MathFunc f)
|
||||||
else
|
else
|
||||||
mathfuncs = f->next;
|
mathfuncs = f->next;
|
||||||
|
|
||||||
|
/* the following applies to both unloaded and user-defined functions */
|
||||||
if (f->module) {
|
if (f->module) {
|
||||||
zsfree(f->name);
|
zsfree(f->name);
|
||||||
zsfree(f->module);
|
zsfree(f->module);
|
||||||
|
|
|
||||||
|
|
@ -86,8 +86,12 @@ struct mathfunc {
|
||||||
int funcid;
|
int funcid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Math function takes a string argument */
|
||||||
#define MFF_STR 1
|
#define MFF_STR 1
|
||||||
|
/* Math function has been loaded from library */
|
||||||
#define MFF_ADDED 2
|
#define MFF_ADDED 2
|
||||||
|
/* Math function is implemented by a shell function */
|
||||||
|
#define MFF_USERFUNC 4
|
||||||
|
|
||||||
#define NUMMATHFUNC(name, func, min, max, id) \
|
#define NUMMATHFUNC(name, func, min, max, id) \
|
||||||
{ NULL, name, 0, func, NULL, NULL, min, max, id }
|
{ NULL, name, 0, func, NULL, NULL, min, max, id }
|
||||||
|
|
@ -815,7 +819,6 @@ struct process {
|
||||||
struct execstack {
|
struct execstack {
|
||||||
struct execstack *next;
|
struct execstack *next;
|
||||||
|
|
||||||
LinkList args;
|
|
||||||
pid_t list_pipe_pid;
|
pid_t list_pipe_pid;
|
||||||
int nowait;
|
int nowait;
|
||||||
int pline_level;
|
int pline_level;
|
||||||
|
|
|
||||||
|
|
@ -11,3 +11,62 @@
|
||||||
foo
|
foo
|
||||||
0:Function definition without braces
|
0:Function definition without braces
|
||||||
>bar
|
>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…
Add table
Add a link
Reference in a new issue