Add support for --info-memory and --robot to xz.
authorLasse Collin <lasse.collin@tukaani.org>
Mon, 16 Nov 2009 16:16:45 +0000 (18:16 +0200)
committerLasse Collin <lasse.collin@tukaani.org>
Mon, 16 Nov 2009 16:16:45 +0000 (18:16 +0200)
Currently --robot works only with --info-memory and
--version. --help and --long-help work too, but --robot
has no effect on them.

Thanks to Jonathan Nieder for the original patches.

src/xz/args.c
src/xz/args.h
src/xz/main.c
src/xz/message.c
src/xz/message.h
src/xz/xz.1

index b35a5b6..75b6220 100644 (file)
@@ -21,6 +21,7 @@
 bool opt_stdout = false;
 bool opt_force = false;
 bool opt_keep_original = false;
+bool opt_robot = false;
 
 // We don't modify or free() this, but we need to assign it in some
 // non-const pointers.
@@ -44,6 +45,8 @@ parse_real(args_info *args, int argc, char **argv)
 
                OPT_FILES,
                OPT_FILES0,
+               OPT_INFO_MEMORY,
+               OPT_ROBOT,
        };
 
        static const char short_opts[]
@@ -51,51 +54,53 @@ parse_real(args_info *args, int argc, char **argv)
 
        static const struct option long_opts[] = {
                // Operation mode
-               { "compress",       no_argument,       NULL,  'z' },
-               { "decompress",     no_argument,       NULL,  'd' },
-               { "uncompress",     no_argument,       NULL,  'd' },
-               { "test",           no_argument,       NULL,  't' },
-               { "list",           no_argument,       NULL,  'l' },
+               { "compress",     no_argument,       NULL,  'z' },
+               { "decompress",   no_argument,       NULL,  'd' },
+               { "uncompress",   no_argument,       NULL,  'd' },
+               { "test",         no_argument,       NULL,  't' },
+               { "list",         no_argument,       NULL,  'l' },
 
                // Operation modifiers
-               { "keep",           no_argument,       NULL,  'k' },
-               { "force",          no_argument,       NULL,  'f' },
-               { "stdout",         no_argument,       NULL,  'c' },
-               { "to-stdout",      no_argument,       NULL,  'c' },
-               { "suffix",         required_argument, NULL,  'S' },
+               { "keep",         no_argument,       NULL,  'k' },
+               { "force",        no_argument,       NULL,  'f' },
+               { "stdout",       no_argument,       NULL,  'c' },
+               { "to-stdout",    no_argument,       NULL,  'c' },
+               { "suffix",       required_argument, NULL,  'S' },
                // { "recursive",      no_argument,       NULL,  'r' }, // TODO
-               { "files",          optional_argument, NULL,  OPT_FILES },
-               { "files0",         optional_argument, NULL,  OPT_FILES0 },
+               { "files",        optional_argument, NULL,  OPT_FILES },
+               { "files0",       optional_argument, NULL,  OPT_FILES0 },
 
                // Basic compression settings
-               { "format",         required_argument, NULL,  'F' },
-               { "check",          required_argument, NULL,  'C' },
-               { "memory",         required_argument, NULL,  'M' },
-               { "threads",        required_argument, NULL,  'T' },
+               { "format",       required_argument, NULL,  'F' },
+               { "check",        required_argument, NULL,  'C' },
+               { "memory",       required_argument, NULL,  'M' },
+               { "threads",      required_argument, NULL,  'T' },
 
-               { "extreme",        no_argument,       NULL,  'e' },
-               { "fast",           no_argument,       NULL,  '0' },
-               { "best",           no_argument,       NULL,  '9' },
+               { "extreme",      no_argument,       NULL,  'e' },
+               { "fast",         no_argument,       NULL,  '0' },
+               { "best",         no_argument,       NULL,  '9' },
 
                // Filters
-               { "lzma1",          optional_argument, NULL,  OPT_LZMA1 },
-               { "lzma2",          optional_argument, NULL,  OPT_LZMA2 },
-               { "x86",            optional_argument, NULL,  OPT_X86 },
-               { "powerpc",        optional_argument, NULL,  OPT_POWERPC },
-               { "ia64",           optional_argument, NULL,  OPT_IA64 },
-               { "arm",            optional_argument, NULL,  OPT_ARM },
-               { "armthumb",       optional_argument, NULL,  OPT_ARMTHUMB },
-               { "sparc",          optional_argument, NULL,  OPT_SPARC },
-               { "delta",          optional_argument, NULL,  OPT_DELTA },
-               { "subblock",       optional_argument, NULL,  OPT_SUBBLOCK },
+               { "lzma1",        optional_argument, NULL,  OPT_LZMA1 },
+               { "lzma2",        optional_argument, NULL,  OPT_LZMA2 },
+               { "x86",          optional_argument, NULL,  OPT_X86 },
+               { "powerpc",      optional_argument, NULL,  OPT_POWERPC },
+               { "ia64",         optional_argument, NULL,  OPT_IA64 },
+               { "arm",          optional_argument, NULL,  OPT_ARM },
+               { "armthumb",     optional_argument, NULL,  OPT_ARMTHUMB },
+               { "sparc",        optional_argument, NULL,  OPT_SPARC },
+               { "delta",        optional_argument, NULL,  OPT_DELTA },
+               { "subblock",     optional_argument, NULL,  OPT_SUBBLOCK },
 
                // Other options
-               { "quiet",          no_argument,       NULL,  'q' },
-               { "verbose",        no_argument,       NULL,  'v' },
-               { "no-warn",        no_argument,       NULL,  'Q' },
-               { "help",           no_argument,       NULL,  'h' },
-               { "long-help",      no_argument,       NULL,  'H' },
-               { "version",        no_argument,       NULL,  'V' },
+               { "quiet",        no_argument,       NULL,  'q' },
+               { "verbose",      no_argument,       NULL,  'v' },
+               { "no-warn",      no_argument,       NULL,  'Q' },
+               { "robot",        no_argument,       NULL,  OPT_ROBOT },
+               { "info-memory",  no_argument,       NULL,  OPT_INFO_MEMORY },
+               { "help",         no_argument,       NULL,  'h' },
+               { "long-help",    no_argument,       NULL,  'H' },
+               { "version",      no_argument,       NULL,  'V' },
 
                { NULL,                 0,                 NULL,   0 }
        };
@@ -169,6 +174,11 @@ parse_real(args_info *args, int argc, char **argv)
                        opt_force = true;
                        break;
 
+               // --info-memory
+               case OPT_INFO_MEMORY:
+                       // This doesn't return.
+                       message_memlimit();
+
                // --help
                case 'h':
                        // This doesn't return.
@@ -207,6 +217,11 @@ parse_real(args_info *args, int argc, char **argv)
                        message_verbosity_increase();
                        break;
 
+               // --robot
+               case OPT_ROBOT:
+                       opt_robot = true;
+                       break;
+
                case 'z':
                        opt_mode = MODE_COMPRESS;
                        break;
index 91e43ad..ac5959b 100644 (file)
@@ -35,6 +35,7 @@ extern bool opt_stdout;
 extern bool opt_force;
 extern bool opt_keep_original;
 // extern bool opt_recursive;
+extern bool opt_robot;
 
 extern const char *stdin_filename;
 
index 3295bba..b197ca4 100644 (file)
@@ -153,6 +153,13 @@ main(int argc, char **argv)
        args_info args;
        args_parse(&args, argc, argv);
 
+       if (opt_mode == MODE_LIST)
+               message_fatal("--list is not implemented yet.");
+
+       if (opt_robot)
+               message_fatal(_("Compression and decompression with --robot "
+                       "are not supported yet."));
+
        // Tell the message handling code how many input files there are if
        // we know it. This way the progress indicator can show it.
        if (args.files_name != NULL)
@@ -172,10 +179,6 @@ main(int argc, char **argv)
                }
        }
 
-       if (opt_mode == MODE_LIST) {
-               message_fatal("--list is not implemented yet.");
-       }
-
        // Hook the signal handlers. We don't need these before we start
        // the actual action, so this is done after parsing the command
        // line arguments.
index fcbf596..be7c3fa 100644 (file)
@@ -1,7 +1,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 //
 /// \file       message.c
-/// \brief      Printing messages to stderr
+/// \brief      Printing messages
 //
 //  Author:     Lasse Collin
 //
@@ -152,7 +152,7 @@ message_init(void)
        if (progress_automatic) {
                // stderr is a terminal. Check the COLUMNS environment
                // variable to see if the terminal is wide enough. If COLUMNS
-               // doesn't exist or it has some unparseable value, we assume
+               // doesn't exist or it has some unparsable value, we assume
                // that the terminal is wide enough.
                const char *columns_str = getenv("COLUMNS");
                if (columns_str != NULL) {
@@ -1013,12 +1013,32 @@ message_try_help(void)
 
 
 extern void
+message_memlimit(void)
+{
+       if (opt_robot)
+               printf("%" PRIu64 "\n", hardware_memlimit_get());
+       else
+               printf(_("%s MiB (%s bytes)\n"),
+                       uint64_to_str(hardware_memlimit_get() >> 20, 0),
+                       uint64_to_str(hardware_memlimit_get(), 1));
+
+       tuklib_exit(E_SUCCESS, E_ERROR, verbosity != V_SILENT);
+}
+
+
+extern void
 message_version(void)
 {
        // It is possible that liblzma version is different than the command
        // line tool version, so print both.
-       printf("xz (" PACKAGE_NAME ") " LZMA_VERSION_STRING "\n");
-       printf("liblzma %s\n", lzma_version_string());
+       if (opt_robot) {
+               printf("XZ_VERSION=%d\nLIBLZMA_VERSION=%d\n",
+                               LZMA_VERSION, lzma_version_number());
+       } else {
+               printf("xz (" PACKAGE_NAME ") " LZMA_VERSION_STRING "\n");
+               printf("liblzma %s\n", lzma_version_string());
+       }
+
        tuklib_exit(E_SUCCESS, E_ERROR, verbosity != V_SILENT);
 }
 
@@ -1137,22 +1157,25 @@ message_help(bool long_help)
 "  -q, --quiet         suppress warnings; specify twice to suppress errors too\n"
 "  -v, --verbose       be verbose; specify twice for even more verbose"));
 
-       if (long_help)
+       if (long_help) {
                puts(_(
 "  -Q, --no-warn       make warnings not affect the exit status"));
-
-       if (long_help)
                puts(_(
-"\n"
+"      --robot         use machine-parsable messages (useful for scripts)"));
+               puts("");
+               puts(_(
+"      --info-memory   display the memory usage limit and exit"));
+               puts(_(
 "  -h, --help          display the short help (lists only the basic options)\n"
-"  -H, --long-help     display this long help"));
-       else
+"  -H, --long-help     display this long help and exit"));
+       } else {
                puts(_(
-"  -h, --help          display this short help\n"
+"  -h, --help          display this short help and exit\n"
 "  -H, --long-help     display the long help (lists also the advanced options)"));
+       }
 
        puts(_(
-"  -V, --version       display the version number"));
+"  -V, --version       display the version number and exit"));
 
        puts(_("\nWith no FILE, or when FILE is -, read standard input.\n"));
 
index 2b1ab91..d9edb7c 100644 (file)
@@ -96,6 +96,10 @@ extern void message_filters(
 extern void message_try_help(void);
 
 
+/// Print the memory usage limit and exit.
+extern void message_memlimit(void) lzma_attribute((noreturn));
+
+
 /// Prints the version number to stdout and exits with exit status SUCCESS.
 extern void message_version(void) lzma_attribute((noreturn));
 
index 150aef0..b811562 100644 (file)
@@ -5,7 +5,7 @@
 .\" This file has been put into the public domain.
 .\" You can do whatever you want with this file.
 .\"
-.TH XZ 1 "2009-11-14" "Tukaani" "XZ Utils"
+.TH XZ 1 "2009-11-16" "Tukaani" "XZ Utils"
 .SH NAME
 xz, unxz, xzcat, lzma, unlzma, lzcat \- Compress or decompress .xz and .lzma files
 .SH SYNOPSIS
@@ -219,8 +219,9 @@ but it is possible that a block later in the file will exceed the memory usage
 limit, and an error about too low memory usage limit gets displayed after some
 data has already been decompressed.
 .PP
-The absolute value of the active memory usage limit can be seen near
-the bottom of the output of
+The absolute value of the active memory usage limit can be seen with
+.B \-\-info-memory
+or near the bottom of the output of
 .BR \-\-long\-help .
 The default limit can be overriden with
 \fB\-\-memory=\fIlimit\fR.
@@ -1052,6 +1053,34 @@ and
 .B \-\-no\-warn
 have to be used to not display warnings and to not alter the exit status.
 .TP
+.B \-\-robot
+Print messages in a machine-parsable format. This is intended to ease
+writing frontends that want to use
+.B xz
+instead of liblzma, which may be the case with various scripts. The output
+with this option enabled is meant to be stable across
+.B xz
+releases. Currently
+.B \-\-robot
+is implemented only for
+.B \-\-info\-memory
+and
+.BR \-\-version ,
+but the idea is to make it usable for actual compression
+and decompression too.
+.TP
+.BR \-\-info-memory
+Display the current memory usage limit in human-readable format on
+a single line, and exit successfully. To see how much RAM
+.B xz
+thinks your system has, use
+.BR "\-\-memory=100% \-\-info\-memory" .
+To get machine-parsable output
+(memory usage limit as bytes without thousand separators), specify
+.B \-\-robot
+before
+.BR \-\-info-memory .
+.TP
 .BR \-h ", " \-\-help
 Display a help message describing the most commonly used options,
 and exit successfully.
@@ -1064,7 +1093,10 @@ and exit successfully
 .BR \-V ", " \-\-version
 Display the version number of
 .B xz
-and liblzma.
+and liblzma in human readable format. To get machine-parsable output, specify
+.B \-\-robot
+before
+.BR \-\-version .
 .SH "EXIT STATUS"
 .TP
 .B 0