summaryrefslogtreecommitdiffstats
path: root/stream.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-03-27 21:26:50 -0700
committerKaz Kylheku <kaz@kylheku.com>2012-03-27 21:26:50 -0700
commit1e67360104eb51a4df38c8be2fdb513517e06965 (patch)
treea268fda042596fc5f827c5e4c1707a398f39845e /stream.c
parent3a39417c79287b8231e70c4a2742fd8ebe3331ef (diff)
downloadtxr-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.c54
1 files changed, 49 insertions, 5 deletions
diff --git a/stream.c b/stream.c
index a4b7863d..46148b7c 100644
--- a/stream.c
+++ b/stream.c
@@ -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>"),