diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2012-03-27 21:26:50 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2012-03-27 21:26:50 -0700 |
commit | 1e67360104eb51a4df38c8be2fdb513517e06965 (patch) | |
tree | a268fda042596fc5f827c5e4c1707a398f39845e /stream.c | |
parent | 3a39417c79287b8231e70c4a2742fd8ebe3331ef (diff) | |
download | txr-1e67360104eb51a4df38c8be2fdb513517e06965.tar.gz txr-1e67360104eb51a4df38c8be2fdb513517e06965.tar.bz2 txr-1e67360104eb51a4df38c8be2fdb513517e06965.zip |
* stream.c (vformat): Compensate for differences in printf
implementations with regard to printing floating point exponents.
by deleting any plus sign and leading zeros after the 'e'.
* tests/009/json.expected: Regenerated.
Diffstat (limited to 'stream.c')
-rw-r--r-- | stream.c | 54 |
1 files changed, 49 insertions, 5 deletions
@@ -1151,11 +1151,33 @@ val vformat(val stream, val fmtstr, va_list vl) uw_throwf(error_s, lit("excessive precision in format: ~s\n"), num(precision), nao); - if (ch == 'e') + if (ch == 'e') { sprintf(num_buf, "%.*e", precision, n); - else + { + char *dec = strchr(num_buf, '.'); + char *exp = strchr(dec ? dec : num_buf, 'e'); + + if (exp) { + char *scan = ++exp; + + if (*scan == '-') + *exp++ = *scan++; + else if (*scan == '+') + scan++; + + while (scan[0] == '0' && scan[1] == '0') + scan++; + + while (*scan) + *exp++ = *scan++; + + *exp = 0; + } + } + } else { sprintf(num_buf, "%.*f", precision, n); - if (!isdigit(num_buf[0])) { + } + if (!isdigit(num_buf[0]) && !isdigit(num_buf[1])) { if (!vformat_str(stream, lit("#<bad-float>"), width, left, 0)) return nil; @@ -1191,8 +1213,30 @@ val vformat(val stream, val fmtstr, va_list vl) sprintf(num_buf, "%.*g", precision, obj->fl.n); - if (ch == 's' && !precision_p && !strpbrk(num_buf, "e.")) - strcat(num_buf, ".0"); + { + char *dec = strchr(num_buf, '.'); + char *exp = strchr(dec ? dec : num_buf, 'e'); + + if (exp) { + char *scan = ++exp; + + if (*scan == '-') + *exp++ = *scan++; + else if (*scan == '+') + scan++; + + while (*scan == 0) + scan++; + + while (*scan) + *exp++ = *scan++; + + *exp = 0; + } + + if (ch == 's' && !precision_p && !dec && !exp) + strcat(num_buf, ".0"); + } if (!isdigit(num_buf[0]) && !isdigit(num_buf[1])) { if (!vformat_str(stream, lit("#<bad-float>"), |