aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorD. Bohdan <dbohdan@dbohdan.com>2020-09-07 07:58:41 +0000
committerSteve Bennett <steveb@workware.net.au>2020-09-23 10:37:52 +1000
commitc95e5271b69c3f04d105607d1033733d5a3ac734 (patch)
tree0e01d4038f9c1f49bd012bf21a36a48bbf0c9ab7
parentf5546ef728f3c2579250dbaa6f3c1cd98eb57dd8 (diff)
downloadjimtcl-c95e5271b69c3f04d105607d1033733d5a3ac734.zip
jimtcl-c95e5271b69c3f04d105607d1033733d5a3ac734.tar.gz
jimtcl-c95e5271b69c3f04d105607d1033733d5a3ac734.tar.bz2
core: implement 0d radix prefix for decimal
TIP 472
-rw-r--r--jim.c17
-rw-r--r--jim_tcl.txt8
-rw-r--r--tests/expr-base.test7
3 files changed, 22 insertions, 10 deletions
diff --git a/jim.c b/jim.c
index 859d88a..1a47200 100644
--- a/jim.c
+++ b/jim.c
@@ -465,13 +465,15 @@ static int JimCheckConversion(const char *str, const char *endptr)
}
/* Parses the front of a number to determine its sign and base.
- * Returns the index to start parsing according to the given base
+ * Returns the index to start parsing according to the given base.
+ * Sets *base to zero if *str contains no indicator of its base and
+ * to the base (2, 8, 10 or 16) otherwise.
*/
static int JimNumberBase(const char *str, int *base, int *sign)
{
int i = 0;
- *base = 10;
+ *base = 0;
while (isspace(UCHAR(str[i]))) {
i++;
@@ -489,7 +491,7 @@ static int JimNumberBase(const char *str, int *base, int *sign)
}
if (str[i] != '0') {
- /* base 10 */
+ /* no base indicator */
return 0;
}
@@ -498,6 +500,7 @@ static int JimNumberBase(const char *str, int *base, int *sign)
case 'x': case 'X': *base = 16; break;
case 'o': case 'O': *base = 8; break;
case 'b': case 'B': *base = 2; break;
+ case 'd': case 'D': *base = 10; break;
default: return 0;
}
i += 2;
@@ -506,8 +509,8 @@ static int JimNumberBase(const char *str, int *base, int *sign)
/* Parse according to this base */
return i;
}
- /* Parse as base 10 */
- *base = 10;
+ /* Parse as default */
+ *base = 0;
return 0;
}
@@ -520,7 +523,7 @@ static long jim_strtol(const char *str, char **endptr)
int base;
int i = JimNumberBase(str, &base, &sign);
- if (base != 10) {
+ if (base != 0) {
long value = strtol(str + i, endptr, base);
if (endptr == NULL || *endptr != str + i) {
return value * sign;
@@ -542,7 +545,7 @@ static jim_wide jim_strtoull(const char *str, char **endptr)
int base;
int i = JimNumberBase(str, &base, &sign);
- if (base != 10) {
+ if (base != 0) {
jim_wide value = strtoull(str + i, endptr, base);
if (endptr == NULL || *endptr != str + i) {
return value * sign;
diff --git a/jim_tcl.txt b/jim_tcl.txt
index 23c80cb..3b0a54e 100644
--- a/jim_tcl.txt
+++ b/jim_tcl.txt
@@ -719,9 +719,11 @@ White space may be used between the operands and operators and
parentheses; it is ignored by the expression processor.
Where possible, operands are interpreted as integer values.
-Integer values may be specified in decimal (the normal case) or in
-hexadecimal (if the first two characters of the operand are '0x').
-Note that Jim Tcl does *not* treat numbers with leading zeros as octal.
+Integer values may be specified in decimal (the default case that can
+be make explicit by prepending '0d' to the operand) or in binary, octal
+or hexadecimal (if the first two characters of the operand are '0b',
+'0o' or '0x' respectively). Note that Jim Tcl does *not* treat numbers
+with leading zeros as octal.
If an operand does not have one of the integer formats given
above, then it is treated as a floating-point number if that is
diff --git a/tests/expr-base.test b/tests/expr-base.test
index 27d583e..2e81bfe 100644
--- a/tests/expr-base.test
+++ b/tests/expr-base.test
@@ -15,6 +15,11 @@ set good_testcases {
-0b111 -7
-0B101 -5
0o7 7
+ 0d0 0
+ 0d7 7
+ 0d99 99
+ 0d099 99
+ -0d099 -99
}
set i 0
@@ -34,6 +39,8 @@ set bad_testcases {
0x-5
{0x 5}
{0o8 + 1}
+ 0d-5
+ 0dff
}
set i 0