aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLasse Collin <lasse.collin@tukaani.org>2009-08-29 14:43:52 +0300
committerLasse Collin <lasse.collin@tukaani.org>2009-08-29 14:43:52 +0300
commit94c66b3297b3ad307eee93cf6b160e3c43997f11 (patch)
treebc0f45c7d64a1788ab2e805bfa156d9f0c1197ab
parentUpdated THANKS. (diff)
downloadxz-94c66b3297b3ad307eee93cf6b160e3c43997f11.tar.xz
Use even more hackish way to support thousand separators.
Seems that in addition on Windows and DOS, also OpenBSD lacks support for %'d style printf() format strings. So far that is the only modern POSIX-like system I know with this problem, but after this hack, the thousand separator shouldn't be a problem on any system. Maybe testing if a format string like %'d produces reasonable output is invoking undefined behavior on some systems, but so far all the problematic systems I've tried just print the raw format string (e.g. %'d prints 'd). Maybe Autoconf test would have been better, but this hack works also for cross-compilation, and avoids recompilation in case the system libc starts to support the thousand separator.
-rw-r--r--src/xz/util.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/src/xz/util.c b/src/xz/util.c
index d160ea0d..9f6bdddd 100644
--- a/src/xz/util.c
+++ b/src/xz/util.c
@@ -13,15 +13,6 @@
#include "private.h"
-// Thousand separator for format strings is not supported outside POSIX.
-// This is used in uint64_to_str() and double_to_str().
-#ifdef DOSLIKE
-# define THOUSAND ""
-#else
-# define THOUSAND "'"
-#endif
-
-
extern void *
xrealloc(void *ptr, size_t size)
{
@@ -135,7 +126,19 @@ uint64_to_str(uint64_t value, uint32_t slot)
assert(slot < ARRAY_SIZE(bufs));
- snprintf(bufs[slot], sizeof(bufs[slot]), "%" THOUSAND PRIu64, value);
+ static enum { UNKNOWN, WORKS, BROKEN } thousand = UNKNOWN;
+ if (thousand == UNKNOWN) {
+ bufs[slot][0] = '\0';
+ snprintf(bufs[slot], sizeof(bufs[slot]), "%'" PRIu64,
+ UINT64_C(1));
+ thousand = bufs[slot][0] == '1' ? WORKS : BROKEN;
+ }
+
+ if (thousand == WORKS)
+ snprintf(bufs[slot], sizeof(bufs[slot]), "%'" PRIu64, value);
+ else
+ snprintf(bufs[slot], sizeof(bufs[slot]), "%" PRIu64, value);
+
return bufs[slot];
}
@@ -147,7 +150,18 @@ double_to_str(double value)
// fields anyway.
static char buf[64];
- snprintf(buf, sizeof(buf), "%" THOUSAND ".1f", value);
+ static enum { UNKNOWN, WORKS, BROKEN } thousand = UNKNOWN;
+ if (thousand == UNKNOWN) {
+ buf[0] = '\0';
+ snprintf(buf, sizeof(buf), "%'.1f", 2.0);
+ thousand = buf[0] == '2' ? WORKS : BROKEN;
+ }
+
+ if (thousand == WORKS)
+ snprintf(buf, sizeof(buf), "%'.1f", value);
+ else
+ snprintf(buf, sizeof(buf), "%.1f", value);
+
return buf;
}