From 14e48e6f78988bc323908df944fe0a534a38629d Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 16 Sep 2012 12:28:25 -0700 Subject: * stream.c (vformat): Fix bug in ~x format directive for printing integers in hex. When we use the printf's %x conversion specifiers for fixnums, we get incorrect results when the values are negative, because the argument is actually treated as an unsigned integer. The end result is that (format t "~x" -1) produces FFFFFFFF rather than -1. Also, merged together mindless code duplication. --- ChangeLog | 9 +++++++++ stream.c | 22 ++++++++-------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3281ad6a..9fee44f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2012-09-16 Kaz Kylheku + + * stream.c (vformat): Fix bug in ~x format directive for printing + integers in hex. When we use the printf's %x conversion specifiers for + fixnums, we get incorrect results when the values are negative, because + the argument is actually treated as an unsigned integer. + The end result is that (format t "~x" -1) produces FFFFFFFF + rather than -1. Also, merged together mindless code duplication. + 2012-09-16 Kaz Kylheku * parser.l: Implemented hexadecimal integer constants. diff --git a/stream.c b/stream.c index e3d8d962..c430f2ee 100644 --- a/stream.c +++ b/stream.c @@ -1126,7 +1126,7 @@ val vformat(val stream, val fmtstr, va_list vl) case vf_spec: state = vf_init; switch (ch) { - case 'x': + case 'x': case 'X': obj = va_arg(vl, val); if (bignump(obj)) { int nchars = mp_radix_size(mp(obj), 16); @@ -1134,20 +1134,14 @@ val vformat(val stream, val fmtstr, va_list vl) pnum = (char *) chk_malloc(nchars + 1); mp_toradix_case(mp(obj), (unsigned char *) pnum, 16, 1); } else { + const char *fmt = ch == 'x' ? num_fmt->hex : num_fmt->HEX; value = c_num(obj); - sprintf(num_buf, num_fmt->hex, value); - } - goto output_num; - case 'X': - obj = va_arg(vl, val); - if (bignump(obj)) { - int nchars = mp_radix_size(mp(obj), 16); - if (nchars >= (int) sizeof (num_buf)) - pnum = (char *) chk_malloc(nchars + 1); - mp_toradix_case(mp(obj), (unsigned char *) pnum, 16, 0); - } else { - value = c_num(obj); - sprintf(num_buf, num_fmt->HEX, value); + if (value < 0) { + num_buf[0] = '-'; + sprintf(num_buf + 1, fmt, -value); + } else { + sprintf(num_buf, fmt, value); + } } goto output_num; case 'o': -- cgit v1.2.3