zsh-workers
 help / color / mirror / code / Atom feed
From: Daniel Shahaf <d.s@daniel.shahaf.name>
To: zsh-workers@zsh.org
Subject: Re: zmathfunc: min, max, sum throw error if result equals 0
Date: Fri, 16 Apr 2021 19:50:28 +0000	[thread overview]
Message-ID: <20210416195028.GE15670@tarpaulin.shahaf.local2> (raw)
In-Reply-To: <CAH+w=7ZFbOJc16r6JX4Lr6uPdVRji_=RmY3WZVBK9GtXzxjPmA@mail.gmail.com>

Again sorry for the delay on getting back to this.

Bart Schaefer wrote on Sun, Mar 07, 2021 at 18:25:00 -0800:
> On Sun, Mar 7, 2021 at 1:57 PM Daniel Shahaf <d.s@daniel.shahaf.name> wrote:
> >
> > Bart Schaefer wrote on Sun, 07 Mar 2021 21:39 +00:00:
> >
> > > Is it worth testing invalid cases?  Such as uses outside math context
> > > where the arguments are not syntax checked?
> >
> > If you have ideas, feel free to write them and post them; I'll
> > transplant them into Z02 once I have committed it.
> 
> One possibility below; I'll follow up if I think of more.
> 
> With your patch adding "true" at the end, we get this:
> 
> % zsh_math_func_min "foo bar" x y z
> zsh_math_func_min:7: bad math expression: operator expected at `bar'
> zsh_math_func_min:7: bad math expression: operator expected at `bar'
> zsh_math_func_min:7: bad math expression: operator expected at `bar'
> zsh_math_func_min:9: bad math expression: operator expected at `bar'
> toltec-ubuntu% echo $?
> 0
> 
> Doesn't seem as though anything that prints that many error messages
> should return zero.
> 

Patch below.

> > > Because of the way math context works, if any of $@ is a string that
> > > can be interpreted as a math expression, the above will evaluate it at
> > > least twice (and up to $# times in the case of $1).  This could have
> > > side-effects.
> >
> > Could you post a regression test for this?
> 
> In thinking more about it, I believe this only matters when the
> function is called outside of math context.  In math context, the
> arguments are all going to be evaluated down to numbers before they
> are passed to the function.
> 
> % (( x = 0 )); zsh_math_func_min "x += 2" 4 5 6
> % print $x
> 8
> % (( (x = 0), min("x += 2", 4, 5, 6) ))
> % print $x
> 2

I see.  Still, going to fix this, if only because those min() max()
sum() implementations are virtually the only example of `functions -M`
in the tree, and it'd be good to have a complete example.

> > Related to code as it is in master, are «(( $arg < result ))» and
> > «(( arg < result ))» equivalent?
> 
> No, but again math context matters.
> 
> % arg="x += 2" x=0 result=0
> % (( $arg > result )) && result=$arg
> % print $result $x $(( result )) $x
> x += 2 1 3 3
> % x=0 result=0
> % (( arg > result )) && (( result=arg ))
> % print $result $x $(( result )) $x
> 4 4 4 4

Nice.  So the first one interpolates $arg as in double-quoted strings
and then parses the string " x += 2 > result ", where the > operator has
higher precedence, and «2 > result» evaluates to 1, and the «print» then
evaluates everything left to right; whereas the latter sees «arg» and
tries to evaluate that _as a number_, which works out to 2 (with a side
effect), so the condition evaluates to true, and the assignment on the
RHS then works out to 4 (with a side effect).  Clear as a cloudless day ☺

Many thanks.

Daniel

diff --git a/Functions/Math/zmathfunc b/Functions/Math/zmathfunc
index 8e4b78549..28f21e562 100644
--- a/Functions/Math/zmathfunc
+++ b/Functions/Math/zmathfunc
@@ -6,7 +6,12 @@ zsh_math_func_min() {
   shift
   local arg
   for arg ; do
-    (( $arg < result )) && result=$arg
+    (( $arg < result ))
+    case $? in
+      (0) result=$arg;;
+      (1) ;;
+      (*) return $?;;
+    esac
   done
   (( result ))
   true # Careful here: `return 0` evaluates an arithmetic expression
@@ -19,7 +24,12 @@ zsh_math_func_max() {
   shift
   local arg
   for arg ; do
-    (( $arg > result )) && result=$arg
+    (( $arg > result ))
+    case $? in
+      (0) result=$arg;;
+      (1) ;;
+      (*) return $?;;
+    esac
   done
   (( result ))
   true # Careful here: `return 0` evaluates an arithmetic expression
@@ -31,7 +41,7 @@ zsh_math_func_sum() {
   local sum
   local arg
   for arg ; do
-    (( sum += $arg ))
+    (( sum += arg ))
   done
   (( sum ))
   true # Careful here: `return 0` evaluates an arithmetic expression


  parent reply	other threads:[~2021-04-16 19:50 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-07 16:37 Nikolaus Thiel
2021-03-07 17:17 ` Daniel Shahaf
2021-03-07 21:39   ` Bart Schaefer
2021-03-07 21:56     ` Daniel Shahaf
2021-03-08  2:25       ` Bart Schaefer
2021-04-16 18:26         ` Daniel Shahaf
2021-04-16 18:47           ` Bart Schaefer
2021-04-16 19:50         ` Daniel Shahaf [this message]
2021-04-16 20:05           ` Bart Schaefer
2021-04-16 20:08             ` Daniel Shahaf
2021-04-16 18:21   ` Daniel Shahaf
2021-05-16 14:54     ` Lawrence Velázquez
2021-05-18  2:02       ` Daniel Shahaf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210416195028.GE15670@tarpaulin.shahaf.local2 \
    --to=d.s@daniel.shahaf.name \
    --cc=zsh-workers@zsh.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).