Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: $[ 09.5 ] -- bad math expression



On Sun, 02 Dec 2012 13:59:40 -0800
Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx> wrote:
> In the patch below I pulled the memchr from the original code that was
> changed by 23165.  There may be a better way to do that test.
> 
> Index: Src/math.c
> ===================================================================
> RCS file: /cvsroot/zsh/zsh/Src/math.c,v
> retrieving revision 1.43
> diff -u -r1.43 math.c
> --- Src/math.c  11 Sep 2012 16:02:42 -0000      1.43
> +++ Src/math.c  2 Dec 2012 21:46:50 -0000
> @@ -447,7 +447,8 @@
>      if (*nptr == '-')
>  	nptr++;
>  
> -    if (*nptr == '0')
> +    if (*nptr == '0' &&
> +	(memchr(nptr, '.', strlen(nptr)) == NULL))

I've just very verybelatedly tracked down some problems I've been
seeing combining integers and floats...

  % print $(( 0x3000 + 0.5 ))
  zsh: bad math expression: operator expected at `x3000 + 0....'

to this memchr(), which is overkill --- it scans the entire rest of the
expression.

The only difficult case, in fact, is the test for OCTALZEROES (both the
option setting and checking the number), since for hexadecimal
we have an explicit signal that the value is a hex integer and it
certainly can't be a float if we find that.  It was almost there: the
problem was when we discovered it wasn't an octal we didn't continue
with the normal code for parsing the number before the decimal point if
octalzeroes *wasn't* set (noted by Bart in the original message).

So I think this is the simplest fix.  The while loop will perform one
extra set of tests if OCTALZEROES *is* set, but anything to remove that
is just as complicated as leaving it this way.

diff --git a/Src/math.c b/Src/math.c
index b21a3ad..42355f8 100644
--- a/Src/math.c
+++ b/Src/math.c
@@ -448,9 +448,7 @@ lexconstant(void)
     if (*nptr == '-')
 	nptr++;
 
-    if (*nptr == '0' &&
-	(memchr(nptr, '.', strlen(nptr)) == NULL))
-    {
+    if (*nptr == '0') {
 	nptr++;
 	if (*nptr == 'x' || *nptr == 'X') {
 	    /* Let zstrtol parse number with base */
@@ -491,11 +489,8 @@ lexconstant(void)
 	    nptr = ptr2;
 	}
     }
-    else
-    {
-	while (idigit(*nptr) || *nptr == '_')
-	    nptr++;
-    }
+    while (idigit(*nptr) || *nptr == '_')
+	nptr++;
 
     if (*nptr == '.' || *nptr == 'e' || *nptr == 'E') {
 	char *ptr2;
diff --git a/Test/C01arith.ztst b/Test/C01arith.ztst
index c19135c..7b005c2 100644
--- a/Test/C01arith.ztst
+++ b/Test/C01arith.ztst
@@ -258,3 +258,11 @@
 >0.5
 >3
 >3.
+
+  print $(( 0x30 + 0.5 ))
+  print $(( 077 + 0.5 ))
+  (setopt octalzeroes; print $(( 077 + 0.5 )) )
+0:Mixed float and non-decimal integer constants
+>48.5
+>77.5
+>63.5

pws



Messages sorted by: Reverse Date, Date, Thread, Author