summaryrefslogtreecommitdiffstats
path: root/stream.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-09-16 12:28:25 -0700
committerKaz Kylheku <kaz@kylheku.com>2012-09-16 12:28:25 -0700
commit14e48e6f78988bc323908df944fe0a534a38629d (patch)
tree963ddca6bf0e1e1e76362d9aa6d29e704af32fc1 /stream.c
parent04a89cc3d83a71b5c9b5df7088d2408e8f7b8a40 (diff)
downloadtxr-14e48e6f78988bc323908df944fe0a534a38629d.tar.gz
txr-14e48e6f78988bc323908df944fe0a534a38629d.tar.bz2
txr-14e48e6f78988bc323908df944fe0a534a38629d.zip
* 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.
Diffstat (limited to 'stream.c')
-rw-r--r--stream.c22
1 files changed, 8 insertions, 14 deletions
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':