Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: zcalc -e for command-line based input
- X-seq: zsh-workers 31940
- From: Peter Stephenson <p.stephenson@xxxxxxxxxxx>
- To: Zsh Hackers' List <zsh-workers@xxxxxxx>
- Subject: PATCH: zcalc -e for command-line based input
- Date: Fri, 08 Nov 2013 11:25:33 +0000
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
- Organization: Samsung Cambridge Solution Centre
One of those things you find need...
diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo
index 9d3fc75..bb6613e 100644
--- a/Doc/Zsh/contrib.yo
+++ b/Doc/Zsh/contrib.yo
@@ -3155,7 +3155,7 @@ sect(Mathematical Functions)
startitem()
findex(zcalc)
-item(tt(zcalc) [ var(expression) ... ])(
+item(tt(zcalc) [ tt(-ef) ] [ 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
@@ -3195,6 +3195,10 @@ 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).
+If the option `tt(-e)' is set, the function runs non-interactively:
+the arguments are treated as expressions to be evaluated as if entered
+interactively line by line.
+
If the option `tt(-f)' is set, all numbers are treated as floating
point, hence for example the expression `tt(3/4)' evaluates to 0.75
rather than 0. Options must appear in separate words.
diff --git a/Functions/Misc/zcalc b/Functions/Misc/zcalc
index e9dcc78..1f3392d 100644
--- a/Functions/Misc/zcalc
+++ b/Functions/Misc/zcalc
@@ -85,10 +85,13 @@
# similarly -##<base>; they set the default output base, with and without
# a base discriminator in front, respectively.
#
-#
-# To do:
-# - separate zcalc history from shell history using arrays --- or allow
-# zsh to switch internally to and from array-based history.
+# With the option -e, the arguments are evaluated as if entered
+# interactively. So, for example:
+# zcalc -e -\#16 -e 1055
+# prints
+# 0x41f
+# Any number of expressions may be given and they are evaluated
+# sequentially just as if read automatically.
emulate -L zsh
setopt extendedglob
@@ -97,7 +100,8 @@ setopt extendedglob
# begin with _.
local line ans base defbase forms match mbegin mend psvar optlist opt arg
local compcontext="-zcalc-line-"
-integer num outdigits outform=1
+integer num outdigits outform=1 expression_mode
+local -a expressions
# We use our own history file with an automatic pop on exit.
history -ap "${ZDOTDIR:-$HOME}/.zcalc_history"
@@ -114,7 +118,7 @@ float PI E
(( PI = 4 * atan(1), E = exp(1) ))
# Process command line
-while [[ -n $1 && $1 = -(|[#-]*|f) ]]; do
+while [[ -n $1 && $1 = -(|[#-]*|f|e) ]]; do
optlist=${1[2,-1]}
shift
[[ $optlist = (|-) ]] && break
@@ -130,11 +134,11 @@ while [[ -n $1 && $1 = -(|[#-]*|f) ]]; do
arg=$1
shift
else
- print "-# requires an argument" >&2
+ print -- "-# requires an argument" >&2
return 1
fi
if [[ $arg != (|\#)[[:digit:]]## ]]; then
- print - "-# requires a decimal number as an argument" >&2
+ print -- "-# requires a decimal number as an argument" >&2
return 1
fi
defbase="[#${arg}]"
@@ -142,10 +146,18 @@ while [[ -n $1 && $1 = -(|[#-]*|f) ]]; do
(f) # Force floating point operation
setopt forcefloat
;;
+ (e) # Arguments are expressions
+ (( expression_mode = 1 ));
+ ;;
esac
done
done
+if (( expression_mode )); then
+ expressions=("$@")
+ argv=()
+fi
+
for (( num = 1; num <= $#; num++ )); do
# Make sure all arguments have been evaluated.
# The `$' before the second argv forces string rather than numeric
@@ -156,7 +168,13 @@ done
psvar[1]=$num
local prev_line cont_prompt
-while vared -cehp "${cont_prompt}${ZCALCPROMPT}" line; do
+while (( expression_mode )) ||
+ vared -cehp "${cont_prompt}${ZCALCPROMPT}" line; do
+ if (( expression_mode )); then
+ (( ${#expressions} )) || break
+ line=$expressions[1]
+ shift expressions
+ fi
if [[ $line = (|*[^\\])('\\')#'\' ]]; then
prev_line+=$line[1,-2]
cont_prompt="..."
pws
Messages sorted by:
Reverse Date,
Date,
Thread,
Author