Index: src/xz/args.c |
=================================================================== |
--- src/xz/args.c (revision 50504) |
+++ src/xz/args.c (working copy) |
@@ -25,10 +25,36 @@ |
// We don't modify or free() this, but we need to assign it in some |
// non-const pointers. |
-const char *stdin_filename = "(stdin)"; |
+const char stdin_filename[] = "(stdin)"; |
+/// Parse and set the memory usage limit for compression and/or decompression. |
static void |
+parse_memlimit(const char *name, const char *name_percentage, char *str, |
+ bool set_compress, bool set_decompress) |
+{ |
+ bool is_percentage = false; |
+ uint64_t value; |
+ |
+ const size_t len = strlen(str); |
+ if (len > 0 && str[len - 1] == '%') { |
+ str[len - 1] = '\0'; |
+ is_percentage = true; |
+ value = str_to_uint64(name_percentage, str, 1, 100); |
+ } else { |
+ // On 32-bit systems, SIZE_MAX would make more sense than |
+ // UINT64_MAX. But use UINT64_MAX still so that scripts |
+ // that assume > 4 GiB values don't break. |
+ value = str_to_uint64(name, str, 0, UINT64_MAX); |
+ } |
+ |
+ hardware_memlimit_set( |
+ value, set_compress, set_decompress, is_percentage); |
+ return; |
+} |
+ |
+ |
+static void |
parse_real(args_info *args, int argc, char **argv) |
{ |
enum { |
@@ -45,6 +71,8 @@ |
OPT_NO_SPARSE, |
OPT_FILES, |
OPT_FILES0, |
+ OPT_MEM_COMPRESS, |
+ OPT_MEM_DECOMPRESS, |
OPT_NO_ADJUST, |
OPT_INFO_MEMORY, |
OPT_ROBOT, |
@@ -75,8 +103,11 @@ |
// Basic compression settings |
{ "format", required_argument, NULL, 'F' }, |
{ "check", required_argument, NULL, 'C' }, |
+ { "memlimit-compress", required_argument, NULL, OPT_MEM_COMPRESS }, |
+ { "memlimit-decompress", required_argument, NULL, OPT_MEM_DECOMPRESS }, |
+ { "memlimit", required_argument, NULL, 'M' }, |
+ { "memory", required_argument, NULL, 'M' }, // Old alias |
{ "no-adjust", no_argument, NULL, OPT_NO_ADJUST }, |
- { "memory", required_argument, NULL, 'M' }, |
{ "threads", required_argument, NULL, 'T' }, |
{ "extreme", no_argument, NULL, 'e' }, |
@@ -104,7 +135,7 @@ |
{ "long-help", no_argument, NULL, 'H' }, |
{ "version", no_argument, NULL, 'V' }, |
- { NULL, 0, NULL, 0 } |
+ { NULL, 0, NULL, 0 } |
}; |
int c; |
@@ -118,29 +149,26 @@ |
coder_set_preset(c - '0'); |
break; |
- // --memory |
- case 'M': { |
- // Support specifying the limit as a percentage of |
- // installed physical RAM. |
- size_t len = strlen(optarg); |
- if (len > 0 && optarg[len - 1] == '%') { |
- optarg[len - 1] = '\0'; |
- hardware_memlimit_set_percentage( |
- str_to_uint64( |
- "memory%", optarg, 1, 100)); |
- } else { |
- // On 32-bit systems, SIZE_MAX would make more |
- // sense than UINT64_MAX. But use UINT64_MAX |
- // still so that scripts that assume > 4 GiB |
- // values don't break. |
- hardware_memlimit_set(str_to_uint64( |
- "memory", optarg, |
- 0, UINT64_MAX)); |
- } |
+ // --memlimit-compress |
+ case OPT_MEM_COMPRESS: |
+ parse_memlimit("memlimit-compress", |
+ "memlimit-compress%", optarg, |
+ true, false); |
+ break; |
+ // --memlimit-decompress |
+ case OPT_MEM_DECOMPRESS: |
+ parse_memlimit("memlimit-decompress", |
+ "memlimit-decompress%", optarg, |
+ false, true); |
break; |
- } |
+ // --memlimit |
+ case 'M': |
+ parse_memlimit("memlimit", "memlimit%", optarg, |
+ true, true); |
+ break; |
+ |
// --suffix |
case 'S': |
suffix_set(optarg); |
@@ -179,7 +207,7 @@ |
// --info-memory |
case OPT_INFO_MEMORY: |
// This doesn't return. |
- message_memlimit(); |
+ hardware_memlimit_show(); |
// --help |
case 'h': |
@@ -384,9 +412,9 @@ |
static void |
-parse_environment(args_info *args, char *argv0) |
+parse_environment(args_info *args, char *argv0, const char *varname) |
{ |
- char *env = getenv("XZ_OPT"); |
+ char *env = getenv(varname); |
if (env == NULL) |
return; |
@@ -415,8 +443,8 @@ |
if (++argc == my_min( |
INT_MAX, SIZE_MAX / sizeof(char *))) |
message_fatal(_("The environment variable " |
- "XZ_OPT contains too many " |
- "arguments")); |
+ "%s contains too many " |
+ "arguments"), varname); |
} |
} |
@@ -504,8 +532,9 @@ |
} |
} |
- // First the flags from environment |
- parse_environment(args, argv[0]); |
+ // First the flags from the environment |
+ parse_environment(args, argv[0], "XZ_DEFAULTS"); |
+ parse_environment(args, argv[0], "XZ_OPT"); |
// Then from the command line |
parse_real(args, argc, argv); |