summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-10-01 17:35:10 -0700
committerKaz Kylheku <kaz@kylheku.com>2012-10-01 17:35:10 -0700
commit40bae281a56c9e305852905dcbd29125de388b25 (patch)
treee2f1675ca58161fb791e179acf31c744b64deb63 /lib.c
parentbaf80248032cdb8856d9e3217d48e9fd5e9e49c5 (diff)
downloadtxr-40bae281a56c9e305852905dcbd29125de388b25.tar.gz
txr-40bae281a56c9e305852905dcbd29125de388b25.tar.bz2
txr-40bae281a56c9e305852905dcbd29125de388b25.zip
* arith.c (bignum_from_long): New function.
* arith.h (bignum_from_long): Declared. * lib.c (int_str): Streamlined. Only use mp_read_radix in the case when wcstol fails, because now we have bignum_from_long to handle all values of long. Ensure that the bignum is normalized, in case it falls in the fixnum range (does not happen on our usual platforms).
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/lib.c b/lib.c
index 89a38496..fcbcae15 100644
--- a/lib.c
+++ b/lib.c
@@ -2104,11 +2104,11 @@ val int_str(val str, val base)
/* TODO: detect if we have wcstoll */
long value = wcstol(wcs, &ptr, b ? b : 10);
+
if (value == 0 && ptr == wcs)
return nil;
- if (((value == LONG_MAX || value == LONG_MIN) && errno == ERANGE) ||
- (value < NUM_MIN || value > NUM_MAX))
- {
+
+ if ((value == LONG_MAX || value == LONG_MIN) && errno == ERANGE) {
val bignum = make_bignum();
unsigned char *ucs = utf8_dup_to_uc(wcs);
mp_err err = mp_read_radix(mp(bignum), ucs, b);
@@ -2118,10 +2118,15 @@ val int_str(val str, val base)
if (err != MP_OKAY)
return nil;
- return bignum;
- }
+ /* If wcstol overflowed, but the range of long is smaller than
+ that of fixnums, that means that the value might not
+ actually be a bignum, and so we must normalize.
+ We do not need this on our usual target platforms, where NUM_MAX is
+ never larger than LONG_MAX. */
+ return (LONG_MAX < NUM_MAX) ? normalize(bignum) : bignum;
+ }
- return num(value);
+ return bignum_from_long(value);
}
val flo_str(val str)