aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/xz/message.c125
-rw-r--r--src/xz/message.h7
-rw-r--r--src/xz/process.c28
3 files changed, 146 insertions, 14 deletions
diff --git a/src/xz/message.c b/src/xz/message.c
index 040147c4..d9733742 100644
--- a/src/xz/message.c
+++ b/src/xz/message.c
@@ -123,15 +123,6 @@ my_snprintf(char **pos, size_t *left, const char *fmt, ...)
return;
}
-// Ugly hack to make it possible to use lzma_attribute((format(printf, 3, 4)))
-// and thus catch stupid things, while still allowing format characters that
-// are not in ISO C but are in POSIX. This has to be done after my_snprintf()
-// has been defined.
-#ifdef __GNUC__
-# define my_snprintf __extension__ my_snprintf
-# define my_printf __extension__ printf
-#endif
-
extern void
message_init(const char *given_argv0)
@@ -723,6 +714,118 @@ message_strm(lzma_ret code)
extern void
+message_filters(enum message_verbosity v, const lzma_filter *filters)
+{
+ if (v > verbosity)
+ return;
+
+ fprintf(stderr, _("%s: Filter chain:"), argv0);
+
+ for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) {
+ fprintf(stderr, " --");
+
+ switch (filters[i].id) {
+ case LZMA_FILTER_LZMA1:
+ case LZMA_FILTER_LZMA2: {
+ const lzma_options_lzma *opt = filters[i].options;
+ const char *mode;
+ const char *mf;
+
+ switch (opt->mode) {
+ case LZMA_MODE_FAST:
+ mode = "fast";
+ break;
+
+ case LZMA_MODE_NORMAL:
+ mode = "normal";
+ break;
+
+ default:
+ mode = "UNKNOWN";
+ break;
+ }
+
+ switch (opt->mf) {
+ case LZMA_MF_HC3:
+ mf = "hc3";
+ break;
+
+ case LZMA_MF_HC4:
+ mf = "hc4";
+ break;
+
+ case LZMA_MF_BT2:
+ mf = "bt2";
+ break;
+
+ case LZMA_MF_BT3:
+ mf = "bt3";
+ break;
+
+ case LZMA_MF_BT4:
+ mf = "bt4";
+ break;
+
+ default:
+ mf = "UNKNOWN";
+ break;
+ }
+
+ fprintf(stderr, "lzma%c=dict=%" PRIu32
+ ",lc=%" PRIu32 ",lp=%" PRIu32
+ ",pb=%" PRIu32
+ ",mode=%s,nice=%" PRIu32 ",mf=%s"
+ ",depth=%" PRIu32,
+ filters[i].id == LZMA_FILTER_LZMA2
+ ? '2' : '1',
+ opt->dict_size,
+ opt->lc, opt->lp, opt->pb,
+ mode, opt->nice_len, mf, opt->depth);
+ break;
+ }
+
+ case LZMA_FILTER_X86:
+ fprintf(stderr, "x86");
+ break;
+
+ case LZMA_FILTER_POWERPC:
+ fprintf(stderr, "powerpc");
+ break;
+
+ case LZMA_FILTER_IA64:
+ fprintf(stderr, "ia64");
+ break;
+
+ case LZMA_FILTER_ARM:
+ fprintf(stderr, "arm");
+ break;
+
+ case LZMA_FILTER_ARMTHUMB:
+ fprintf(stderr, "armthumb");
+ break;
+
+ case LZMA_FILTER_SPARC:
+ fprintf(stderr, "sparc");
+ break;
+
+ case LZMA_FILTER_DELTA: {
+ const lzma_options_delta *opt = filters[i].options;
+ fprintf(stderr, "delta=dist=%" PRIu32, opt->dist);
+ break;
+ }
+
+ default:
+ fprintf(stderr, "UNKNOWN");
+ break;
+ }
+ }
+
+ fputc('\n', stderr);
+ return;
+}
+
+
+extern void
message_try_help(void)
{
// Print this with V_WARNING instead of V_ERROR to prevent it from
@@ -867,13 +970,13 @@ message_help(bool long_help)
puts(_("\nWith no FILE, or when FILE is -, read standard input.\n"));
if (long_help) {
- my_printf(_(
+ printf(_(
"On this system and configuration, the tool will use at maximum of\n"
" * roughly %'" PRIu64 " MiB RAM for compression;\n"
" * roughly %'" PRIu64 " MiB RAM for decompression; and\n"),
hardware_memlimit_encoder() / (1024 * 1024),
hardware_memlimit_decoder() / (1024 * 1024));
- my_printf(N_(" * one thread for (de)compression.\n\n",
+ printf(N_(" * one thread for (de)compression.\n\n",
" * %'" PRIu64 " threads for (de)compression.\n\n",
(uint64_t)(opt_threads)), (uint64_t)(opt_threads));
}
diff --git a/src/xz/message.h b/src/xz/message.h
index 7ef9b165..d67fecc7 100644
--- a/src/xz/message.h
+++ b/src/xz/message.h
@@ -94,10 +94,15 @@ extern void message_bug(void) lzma_attribute((noreturn));
extern void message_signal_handler(void) lzma_attribute((noreturn));
-/// Converts lzma_ret to a string.
+/// Convert lzma_ret to a string.
extern const char *message_strm(lzma_ret code);
+/// Print the filter chain.
+extern void message_filters(
+ enum message_verbosity v, const lzma_filter *filters);
+
+
/// Print a message that user should try --help.
extern void message_try_help(void);
diff --git a/src/xz/process.c b/src/xz/process.c
index 4a028751..191dfc09 100644
--- a/src/xz/process.c
+++ b/src/xz/process.c
@@ -119,6 +119,9 @@ coder_set_compression_settings(void)
message_fatal(_("With --format=lzma only the LZMA1 filter "
"is supported"));
+ // Print the selected filter chain.
+ message_filters(V_DEBUG, filters);
+
// If using --format=raw, we can be decoding. The memusage function
// also validates the filter chain and the options used for the
// filters.
@@ -135,6 +138,12 @@ coder_set_compression_settings(void)
if (memory_usage == UINT64_MAX)
message_fatal("Unsupported filter chain or filter options");
+ // Print memory usage info.
+ message(V_DEBUG, _("%" PRIu64 " MiB of memory is required per thread, "
+ "limit is %" PRIu64 " MiB"),
+ memory_usage / (1024 * 1024),
+ memory_limit / (1024 * 1024));
+
if (preset_default) {
// When no preset was explicitly requested, we use the default
// preset only if the memory usage limit allows. Otherwise we
@@ -348,9 +357,24 @@ coder_run(file_pair *pair)
}
if (ret == LZMA_MEMLIMIT_ERROR) {
- // Figure out how much memory would have
+ // Figure out how much memory it would have
// actually needed.
- // TODO
+ uint64_t memusage = lzma_memusage(&strm);
+ uint64_t memlimit
+ = hardware_memlimit_decoder();
+
+ // Round the memory limit down and usage up.
+ // This way we don't display a ridiculous
+ // message like "Limit was 9 MiB, but 9 MiB
+ // would have been needed".
+ memusage = (memusage + 1024 * 1024 - 1)
+ / (1024 * 1024);
+ memlimit /= 1024 * 1024;
+
+ message_error(_("Limit was %'" PRIu64 " MiB, "
+ "but %'" PRIu64 " MiB would "
+ "have been needed"),
+ memlimit, memusage);
}
if (stop)