From d315ca4930ff96e1428c6021c96f209e1abdd83e Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Mon, 16 Nov 2009 18:16:45 +0200 Subject: [PATCH] Add support for --info-memory and --robot to xz. 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 | 85 ++++++++++++++++++++++++++++-------------------- src/xz/args.h | 1 + src/xz/main.c | 11 ++++--- src/xz/message.c | 47 +++++++++++++++++++------- src/xz/message.h | 4 +++ src/xz/xz.1 | 40 ++++++++++++++++++++--- 6 files changed, 133 insertions(+), 55 deletions(-) diff --git a/src/xz/args.c b/src/xz/args.c index b35a5b63..75b62205 100644 --- a/src/xz/args.c +++ b/src/xz/args.c @@ -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; diff --git a/src/xz/args.h b/src/xz/args.h index 91e43ad6..ac5959b5 100644 --- a/src/xz/args.h +++ b/src/xz/args.h @@ -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; diff --git a/src/xz/main.c b/src/xz/main.c index 3295bba3..b197ca43 100644 --- a/src/xz/main.c +++ b/src/xz/main.c @@ -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. diff --git a/src/xz/message.c b/src/xz/message.c index fcbf5967..be7c3fac 100644 --- a/src/xz/message.c +++ b/src/xz/message.c @@ -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) { @@ -1012,13 +1012,33 @@ 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")); diff --git a/src/xz/message.h b/src/xz/message.h index 2b1ab919..d9edb7c0 100644 --- a/src/xz/message.h +++ b/src/xz/message.h @@ -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)); diff --git a/src/xz/xz.1 b/src/xz/xz.1 index 150aef0b..b8115624 100644 --- a/src/xz/xz.1 +++ b/src/xz/xz.1 @@ -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