xz message handling improvements
authorLasse Collin <lasse.collin@tukaani.org>
Wed, 17 Dec 2008 18:11:23 +0000 (20:11 +0200)
committerLasse Collin <lasse.collin@tukaani.org>
Wed, 17 Dec 2008 18:11:23 +0000 (20:11 +0200)
src/xz/message.c
src/xz/message.h
src/xz/process.c

index 040147c..d973374 100644 (file)
@@ -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)
@@ -722,6 +713,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)
 {
@@ -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));
        }
index 7ef9b16..d67fecc 100644 (file)
@@ -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);
 
index 4a02875..191dfc0 100644 (file)
@@ -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)