diff options
author | D. Bohdan <dbohdan@dbohdan.com> | 2020-09-07 07:58:41 +0000 |
---|---|---|
committer | Steve Bennett <steveb@workware.net.au> | 2020-09-23 10:37:52 +1000 |
commit | c95e5271b69c3f04d105607d1033733d5a3ac734 (patch) | |
tree | 0e01d4038f9c1f49bd012bf21a36a48bbf0c9ab7 | |
parent | f5546ef728f3c2579250dbaa6f3c1cd98eb57dd8 (diff) | |
download | jimtcl-c95e5271b69c3f04d105607d1033733d5a3ac734.zip jimtcl-c95e5271b69c3f04d105607d1033733d5a3ac734.tar.gz jimtcl-c95e5271b69c3f04d105607d1033733d5a3ac734.tar.bz2 |
core: implement 0d radix prefix for decimal
TIP 472
-rw-r--r-- | jim.c | 17 | ||||
-rw-r--r-- | jim_tcl.txt | 8 | ||||
-rw-r--r-- | tests/expr-base.test | 7 |
3 files changed, 22 insertions, 10 deletions
@@ -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 |