diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | lib.c | 28 | ||||
-rw-r--r-- | txr.1 | 1 |
3 files changed, 36 insertions, 1 deletions
@@ -1,3 +1,11 @@ +2015-03-20 Kaz Kylheku <kaz@kylheku.com> + + * lib.c (int_str): Workaround for wcstol recognizing the 0x prefix when + radix is 16. Also, thrown an error if radix is not in the range + 0 to 36. + + * txr.1: Document int-str's radix range restriction. + 2015-03-17 Kaz Kylheku <kaz@kylheku.com> * txr.c (help): Added missing documentation for -e and -p. @@ -3036,10 +3036,36 @@ val int_str(val str, val base) { const wchar_t *wcs = c_str(str); wchar_t *ptr; + long value; cnum b = c_num(default_arg(base, num_fast(10))); + /* Standard C idiocy: if base is 16, strtoul and its siblings + still recognize the 0x prefix. */ + if (b == 16) { + switch (wcs[0]) { + case '+': + case '-': + switch (wcs[1]) { + case '0': + switch (wcs[2]) { + case 'x': case 'X': + return zero; + } + } + break; + case '0': + switch (wcs[1]) { + case 'x': case 'X': + return zero; + } + break; + } + } else if (b < 2 || b > 36) { + uw_throwf(error_s, lit("int-str: invalid base ~s"), base, nao); + } + /* TODO: detect if we have wcstoll */ - long value = wcstol(wcs, &ptr, b ? b : 10); + value = wcstol(wcs, &ptr, b ? b : 10); if (value == 0 && ptr == wcs) return nil; @@ -19063,6 +19063,7 @@ The .code int-str function converts a string of digits in the specified radix to an integer value. If the radix isn't specified, it defaults to 10. +Otherwise it must be an integer in the range 2 to 36. For radices above 10, letters of the alphabet are used for digits: .code A |