Skip to content
Snippets Groups Projects
Commit 2148381ffd95 authored by Lasse Collin's avatar Lasse Collin
Browse files

Ugly hack to make it possible to use the thousand separator

format character with snprintf() on POSIX systems but not
on non-POSIX systems and still keep xgettext working.
parent d0c864fd0b2f
No related branches found
No related tags found
No related merge requests found
......@@ -233,6 +233,5 @@
../src/xz/suffix.c \
../src/xz/util.c
XZ_SRCS_FIXED = $(XZ_SRCS:.c=-fixed.c)
XZ_OBJS = $(XZ_SRCS:.c=.o)
......@@ -237,12 +236,6 @@
XZ_OBJS = $(XZ_SRCS:.c=.o)
$(XZ_SRCS_FIXED): %-fixed.c: %.c
$(SED) "s/%'/%/g" $< > $@
# We need to "fix" the source files which use ' as format character
# in printf() to get thousand separators. DJGPP doesn't support it.
# It's not in C89 or C99, but it is in POSIX.
$(XZ_OBJS): %.o: %-fixed.c
$(XZ_OBJS): %.o: %.c
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c -o $@ $<
xz.exe: getopt.a liblzma.a $(XZ_OBJS)
......@@ -258,7 +251,4 @@
xz-clean: $(XZ_OBJS:.o=-clean)
-$(RM) xz.exe xz
# FIXME: Deleting hardware-fixed.c may actually delete hardware.c
# on Dosemu 1.4.0 with its FreeDOS 1.0. Maybe it tries with
# truncated 8.3 name first.
$(XZ_OBJS:.o=-clean):
......@@ -264,2 +254,2 @@
$(XZ_OBJS:.o=-clean):
-$(RM) $(@:-clean=.o) $(@:-clean=-fixed.c)
-$(RM) $(@:-clean=.o)
......@@ -363,9 +363,10 @@
if (final) {
// At maximum of four digits is allowed for exact byte count.
if (value < 10000) {
my_snprintf(pos, left, "%'" PRIu64 " B", value);
my_snprintf(pos, left, "%s B",
uint64_to_str(value, 0));
return;
}
// At maximum of five significant digits is allowed for KiB.
if (value < UINT64_C(10239900)) {
......@@ -367,12 +368,12 @@
return;
}
// At maximum of five significant digits is allowed for KiB.
if (value < UINT64_C(10239900)) {
my_snprintf(pos, left, "%'.1f KiB",
(double)(value) / 1024.0);
my_snprintf(pos, left, "%s KiB", double_to_str(
(double)(value) / 1024.0));
return;
}
}
// Otherwise we use MiB.
......@@ -374,10 +375,10 @@
return;
}
}
// Otherwise we use MiB.
my_snprintf(pos, left, "%'.1f MiB",
(double)(value) / (1024.0 * 1024.0));
my_snprintf(pos, left, "%s MiB",
double_to_str((double)(value) / (1024.0 * 1024.0)));
return;
}
......@@ -1157,6 +1158,6 @@
if (long_help) {
printf(_(
"On this system and configuration, this program will use at maximum of roughly\n"
"%'" PRIu64 " MiB RAM and "), hardware_memlimit_get() / (1024 * 1024));
printf(N_("one thread.\n\n", "%'" PRIu32 " threads.\n\n",
"%s MiB RAM and "), uint64_to_str(hardware_memlimit_get() / (1024 * 1024), 0));
printf(N_("one thread.\n\n", "%s threads.\n\n",
hardware_threadlimit_get()),
......@@ -1162,5 +1163,5 @@
hardware_threadlimit_get()),
hardware_threadlimit_get());
uint64_to_str(hardware_threadlimit_get(), 0));
}
printf(_("Report bugs to <%s> (in English or Finnish).\n"),
......
......@@ -163,11 +163,12 @@
message_fatal("Unsupported filter chain or filter options");
// Print memory usage info.
message(V_DEBUG, _("%'" PRIu64 " MiB (%'" PRIu64 " B) of memory is "
"required per thread, "
"limit is %'" PRIu64 " MiB (%'" PRIu64 " B)"),
memory_usage >> 20, memory_usage,
memory_limit >> 20, memory_limit);
message(V_DEBUG, _("%s MiB (%s B) of memory is required per thread, "
"limit is %s MiB (%s B)"),
uint64_to_str(memory_usage >> 20, 0),
uint64_to_str(memory_usage, 1),
uint64_to_str(memory_limit >> 20, 2),
uint64_to_str(memory_limit, 3));
if (memory_usage > memory_limit) {
// If --no-auto-adjust was used or we didn't find LZMA1 or
......@@ -225,9 +226,7 @@
// was given. FIXME: Always warn?
if (!preset_default)
message(V_WARNING, "Adjusted LZMA%c dictionary size "
"from %'" PRIu32 " MiB to "
"%'" PRIu32 " MiB to not exceed "
"the memory usage limit of "
"%'" PRIu64 " MiB",
"from %s MiB to %s MiB to not exceed "
"the memory usage limit of %s MiB",
filters[i].id == LZMA_FILTER_LZMA2
? '2' : '1',
......@@ -232,8 +231,8 @@
filters[i].id == LZMA_FILTER_LZMA2
? '2' : '1',
orig_dict_size >> 20,
opt->dict_size >> 20,
memory_limit >> 20);
uint64_to_str(orig_dict_size >> 20, 0),
uint64_to_str(opt->dict_size >> 20, 1),
uint64_to_str(memory_limit >> 20, 2));
}
/*
......@@ -443,6 +442,6 @@
/ (1024 * 1024);
memlimit /= 1024 * 1024;
message_error(_("Limit was %'" PRIu64 " MiB, "
"but %'" PRIu64 " MiB would "
message_error(_("Limit was %s MiB, "
"but %s MiB would "
"have been needed"),
......@@ -448,5 +447,6 @@
"have been needed"),
memlimit, memusage);
uint64_to_str(memlimit, 0),
uint64_to_str(memusage, 1));
}
if (stop)
......
......@@ -13,6 +13,15 @@
#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)
{
......@@ -118,6 +127,31 @@
}
extern const char *
uint64_to_str(uint64_t value, uint32_t slot)
{
// 2^64 with thousand separators is 26 bytes plus trailing '\0'.
static char bufs[4][32];
assert(slot < ARRAY_SIZE(bufs));
snprintf(bufs[slot], sizeof(bufs[slot]), "%" THOUSAND PRIu64, value);
return bufs[slot];
}
extern const char *
double_to_str(double value)
{
// 64 bytes is surely enough, since it won't fit in some other
// fields anyway.
static char buf[64];
snprintf(buf, sizeof(buf), "%" THOUSAND ".1f", value);
return buf;
}
/*
/// \brief Simple quoting to get rid of ASCII control characters
///
......
......@@ -41,6 +41,26 @@
uint64_t min, uint64_t max);
/// \brief Convert uint64_t to a string
///
/// Convert the given value to a string with locale-specific thousand
/// separators, if supported by the snprintf() implementation. The string
/// is stored into an internal static buffer indicated by the slot argument.
/// A pointer to the selected buffer is returned.
///
/// This function exists, because non-POSIX systems don't support thousand
/// separator in format strings. Solving the problem in a simple way doesn't
/// work, because it breaks gettext (specifically, the xgettext tool).
extern const char *uint64_to_str(uint64_t value, uint32_t slot);
/// \brief Convert double to a string with one decimal place
///
/// This is like uint64_to_str() except that this converts a double and
/// uses exactly one decimal place.
extern const char *double_to_str(double value);
/// \brief Check if filename is empty and print an error message
extern bool is_empty_filename(const char *filename);
......
......@@ -283,7 +283,6 @@
../src/xz/suffix.c \
../src/xz/util.c
XZ_SRCS_FIXED = $(XZ_SRCS:.c=-fixed.c)
XZ_OBJS = $(XZ_SRCS:.c=.o)
XZ_OBJS_STATIC = $(XZ_SRCS:.c=-static.o)
......@@ -287,16 +286,10 @@
XZ_OBJS = $(XZ_SRCS:.c=.o)
XZ_OBJS_STATIC = $(XZ_SRCS:.c=-static.o)
$(XZ_SRCS_FIXED): %-fixed.c: %.c
$(SED) "s/%'/%/g" $< > $@
# We need to "fix" the source files which use ' as format character
# in printf() to get thousand separators. Windows doesn't support it.
# It's not in C89 or C99, but it is in POSIX.
$(XZ_OBJS): %.o: %-fixed.c
$(XZ_OBJS): %.o: %.c
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c -o $@ $<
xz-dynamic.exe: liblzma.dll $(XZ_OBJS) xz_rc.o
$(CC) $(ALL_CFLAGS) $(XZ_OBJS) xz_rc.o -o $@ liblzma.a
$(STRIP) --strip-all $@
......@@ -297,10 +290,10 @@
$(CC) $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c -o $@ $<
xz-dynamic.exe: liblzma.dll $(XZ_OBJS) xz_rc.o
$(CC) $(ALL_CFLAGS) $(XZ_OBJS) xz_rc.o -o $@ liblzma.a
$(STRIP) --strip-all $@
$(XZ_OBJS_STATIC): %-static.o: %-fixed.c
$(XZ_OBJS_STATIC): %-static.o: %.c
$(CC) -DLZMA_API_STATIC $(ALL_CPPFLAGS) $(ALL_CFLAGS) -c -o $@ $<
xz.exe: liblzma_static.lib $(XZ_OBJS_STATIC) xz_rc.o
......@@ -309,4 +302,4 @@
.PHONY: xz-clean
xz-clean:
-$(RM) $(XZ_OBJS) $(XZ_OBJS_STATIC) $(XZ_SRCS_FIXED) xz_rc.o xz-dynamic.exe xz.exe
-$(RM) $(XZ_OBJS) $(XZ_OBJS_STATIC) xz_rc.o xz-dynamic.exe xz.exe
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment