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

Re: test if a parameter is numeric



Stephane Chazelas <Stephane_Chazelas@xxxxxxxx> wrote:
> By the way, are those normal:
> 
> $ echo $((40#^))
> 39
> 
> (given that ^ is also an arithmetic operator)?
> 
> $ echo $((02#11))
> 3
> $ setopt octalzeroes
> $ echo $((02#11))
> zsh: bad math expression: operator expected at `#11'
> $

Bases are only documented to work up to 36, so it's just a question of
enforcing that.

Bases are always expected to be parsed in decimal, but the octal handler
was a bit overeager; I've changed that and clarified the fact that a
leading zero isn't special here.

Index: Doc/Zsh/options.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/options.yo,v
retrieving revision 1.51
diff -u -r1.51 options.yo
--- Doc/Zsh/options.yo	9 Jan 2007 21:59:31 -0000	1.51
+++ Doc/Zsh/options.yo	12 Feb 2007 16:35:14 -0000
@@ -1101,6 +1101,10 @@
 1003.2-1992 (ISO 9945-2:1993).  This is not enabled by default as it
 causes problems with parsing of, for example, date and time strings with
 leading zeroes.
+
+Sequences of digits indicating a numeric base such as the `tt(08)'
+component in `tt(08#77)' are always interpreted as decimal, regardless
+of leading zeroes.
 )
 pindex(TYPESET_SILENT)
 item(tt(TYPESET_SILENT))(
Index: Src/math.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/math.c,v
retrieving revision 1.28
diff -u -r1.28 math.c
--- Src/math.c	10 Sep 2006 18:10:49 -0000	1.28
+++ Src/math.c	12 Feb 2007 16:35:14 -0000
@@ -216,17 +216,33 @@
 	    lastbase = 16;
 	    return NUM;
 	}
-	else if (isset(OCTALZEROES) &&
-		 (memchr(nptr, '.', strlen(nptr)) == NULL) &&
-		 idigit(*nptr)) {
-	    yyval.u.l = zstrtol(ptr, &ptr, 0);
-	    lastbase = 8;
-	    return NUM;
+	else if (isset(OCTALZEROES))
+	{
+	    char *ptr2;
+
+	    /*
+	     * Make sure this is a real octal constant;
+	     * it can't be a base indication (always decimal)
+	     * or a floating point number.
+	     */
+	    for (ptr2 = nptr; idigit(*ptr2); ptr2++)
+		;
+
+	    if (ptr2 > nptr && *ptr2 != '.' && *ptr2 != 'e' &&
+		*ptr2 != 'E' && *ptr2 != '#')
+	    {
+		yyval.u.l = zstrtol(ptr, &ptr, 0);
+		lastbase = 8;
+		return NUM;
+	    }
+	    nptr = ptr2;
 	}
     }
-
-    while (idigit(*nptr))
-	nptr++;
+    else
+    {
+	while (idigit(*nptr))
+	    nptr++;
+    }
 
     if (*nptr == '.' || *nptr == 'e' || *nptr == 'E') {
 	/* it's a float */
Index: Src/utils.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/utils.c,v
retrieving revision 1.155
diff -u -r1.155 utils.c
--- Src/utils.c	8 Feb 2007 10:43:30 -0000	1.155
+++ Src/utils.c	12 Feb 2007 16:35:14 -0000
@@ -1803,7 +1803,10 @@
 	    base = 8;
     }
     inp = s;
-    if (base <= 10)
+    if (base > 36) {
+	zerr("invalid base: %d", base);
+	return (zlong)0;
+    } else if (base <= 10)
 	for (; *s >= '0' && *s < ('0' + base); s++) {
 	    if (trunc)
 		continue;
Index: Test/C01arith.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/C01arith.ztst,v
retrieving revision 1.10
diff -u -r1.10 C01arith.ztst
--- Test/C01arith.ztst	11 Sep 2006 11:09:15 -0000	1.10
+++ Test/C01arith.ztst	12 Feb 2007 16:35:14 -0000
@@ -136,3 +136,15 @@
   print $(( 5, (3 + 7, 4) ))
 0:commas and parentheses, part 1
 >4
+
+  (setopt octalzeroes; print $(( 08#77 )))
+0:octalzeroes doesn't affect bases
+>63
+
+  print $(( 36#z ))
+0:bases up to 36 work
+>35
+
+  print $(( 37#z ))
+1:bases beyond 36 don't work
+?(eval):1: invalid base: 37


To access the latest news from CSR copy this link into a web browser:  http://www.csr.com/email_sig.php

To get further information regarding CSR, please visit our Investor Relations page at http://ir.csr.com/csr/about/overview



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