about summary refs log tree commit diff
path: root/Src/math.c
diff options
context:
space:
mode:
authorTanaka Akira <akr@users.sourceforge.net>2000-03-13 09:40:22 +0000
committerTanaka Akira <akr@users.sourceforge.net>2000-03-13 09:40:22 +0000
commit5e8320bf2bc3eb1faf702fcbd9ebf572912170e7 (patch)
treeab5c0d7522fabd571f0a2eb58514497311e7551f /Src/math.c
parent2d69947427fac68c06ca9e659cf2ad5fbacaf19d (diff)
downloadzsh-5e8320bf2bc3eb1faf702fcbd9ebf572912170e7.tar.gz
zsh-5e8320bf2bc3eb1faf702fcbd9ebf572912170e7.tar.xz
zsh-5e8320bf2bc3eb1faf702fcbd9ebf572912170e7.zip
zsh-workers/10104
Diffstat (limited to 'Src/math.c')
-rw-r--r--Src/math.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/Src/math.c b/Src/math.c
index ce685e2db..2dc667c35 100644
--- a/Src/math.c
+++ b/Src/math.c
@@ -950,6 +950,78 @@ mathevalarg(char *s, char **ss)
     return (x.type & MN_FLOAT) ? (zlong)x.u.d : x.u.l;
 }
 
+/**/
+mod_export mnumber
+mathnumber(char *s)
+{
+    mnumber ret;
+
+    ret.type = MN_INTEGER;
+
+    while (*s) {
+	switch (*s++) {
+	case '[':
+	    {
+		int base = zstrtol(s, &s, 10);
+
+		if (*s == ']')
+		    s++;
+		ret.u.l = zstrtol(s, &s, base);
+		return ret;
+	    }
+	case ' ':
+	case '\t':
+	case '\n':
+	    break;
+	case '0':
+	    if (*s == 'x' || *s == 'X') {
+		/* Should we set lastbase here? */
+		ret.u.l = zstrtol(++s, &s, 16);
+		return ret;
+	    }
+	/* Fall through! */
+	default:
+	    if (idigit(*--s) || *s == '.') {
+		char *nptr;
+#ifdef USE_LOCALE
+		char *prev_locale;
+#endif
+		for (nptr = s; idigit(*nptr); nptr++);
+
+		if (*nptr == '.' || *nptr == 'e' || *nptr == 'E') {
+		    /* it's a float */
+		    ret.type = MN_FLOAT;
+#ifdef USE_LOCALE
+		    prev_locale = setlocale(LC_NUMERIC, NULL);
+		    setlocale(LC_NUMERIC, "POSIX");
+#endif
+		    ret.u.d = strtod(s, &nptr);
+#ifdef USE_LOCALE
+		    setlocale(LC_NUMERIC, prev_locale);
+#endif
+		    if (s == nptr || *nptr == '.')
+			goto end;
+		    s = nptr;
+		} else {
+		    /* it's an integer */
+		    ret.u.l = zstrtol(s, &s, 10);
+
+		    if (*s == '#')
+			ret.u.l = zstrtol(++s, &s, ret.u.l);
+		}
+		return ret;
+	    }
+	    goto end;
+	}
+    }
+ end:
+
+    ret.type = MN_INTEGER;
+    ret.u.l = 0;
+
+    return ret;
+}
+
 /*
  * Make sure we have an operator or an operand, whatever is expected.
  * For this purpose, unary operators constitute part of an operand.