about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Doc/Zsh/contrib.yo6
-rw-r--r--Functions/Misc/zcalc36
3 files changed, 37 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 2adf991f3..d233d0da4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2013-11-08  Peter Stephenson  <p.stephenson@samsung.com>
+
+	* 31940: Doc/Zsh/contrib.yo, Functions/Misc/zcalc: add -e option
+	to zcalc to use input from arguments to command.
+
 2013-11-07  Peter Stephenson  <p.stephenson@samsung.com>
 
 	* 31937: Doc/Zsh/zle.yo, Src/Zle/zle_main.c,
diff --git a/Doc/Zsh/contrib.yo b/Doc/Zsh/contrib.yo
index 9d3fc7562..bb6613ece 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 e9dcc78b9..1f3392d92 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="..."