diff options
author | Lasse Collin <lasse.collin@tukaani.org> | 2012-07-03 21:16:39 +0300 |
---|---|---|
committer | Lasse Collin <lasse.collin@tukaani.org> | 2012-07-03 21:16:39 +0300 |
commit | 88ccf47205d7f3aa314d358c72ef214f10f68b43 (patch) | |
tree | 9dc89c76bfad5f94d68e1fc80c838602d4271323 /src/xz/args.c | |
parent | xz: Update the man page about the new field in --robot -lvv. (diff) | |
download | xz-88ccf47205d7f3aa314d358c72ef214f10f68b43.tar.xz |
xz: Add incomplete support for --block-list.
It's broken with threads and when also --block-size is used.
Diffstat (limited to 'src/xz/args.c')
-rw-r--r-- | src/xz/args.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/src/xz/args.c b/src/xz/args.c index 54b3ff32..9a4f82be 100644 --- a/src/xz/args.c +++ b/src/xz/args.c @@ -55,6 +55,67 @@ parse_memlimit(const char *name, const char *name_percentage, char *str, static void +parse_block_list(char *str) +{ + // It must be non-empty and not begin with a comma. + if (str[0] == '\0' || str[0] == ',') + message_fatal(_("%s: Invalid argument to --block-list"), str); + + // Count the number of comma-separated strings. + size_t count = 1; + for (size_t i = 0; str[i] != '\0'; ++i) + if (str[i] == ',') + ++count; + + // Prevent an unlikely integer overflow. + if (count > SIZE_MAX / sizeof(uint64_t) - 1) + message_fatal(_("%s: Too many arguments to --block-list"), + str); + + // Allocate memory to hold all the sizes specified. + // If --block-list was specified already, its value is forgotten. + free(opt_block_list); + opt_block_list = xmalloc((count + 1) * sizeof(uint64_t)); + + for (size_t i = 0; i < count; ++i) { + // Locate the next comma and replace it with \0. + char *p = strchr(str, ','); + if (p != NULL) + *p = '\0'; + + if (str[0] == '\0') { + // There is no string, that is, a comma follows + // another comma. Use the previous value. + // + // NOTE: We checked earler that the first char + // of the whole list cannot be a comma. + assert(i > 0); + opt_block_list[i] = opt_block_list[i - 1]; + } else { + opt_block_list[i] = str_to_uint64("block-list", str, + 0, UINT64_MAX); + + // Zero indicates no more new Blocks. + if (opt_block_list[i] == 0) { + if (i + 1 != count) + message_fatal(_("0 can only be used " + "as the last element " + "in --block-list")); + + opt_block_list[i] = UINT64_MAX; + } + } + + str = p + 1; + } + + // Terminate the array. + opt_block_list[count] = 0; + return; +} + + +static void parse_real(args_info *args, int argc, char **argv) { enum { @@ -73,6 +134,7 @@ parse_real(args_info *args, int argc, char **argv) OPT_FILES, OPT_FILES0, OPT_BLOCK_SIZE, + OPT_BLOCK_LIST, OPT_MEM_COMPRESS, OPT_MEM_DECOMPRESS, OPT_NO_ADJUST, @@ -107,6 +169,7 @@ parse_real(args_info *args, int argc, char **argv) { "format", required_argument, NULL, 'F' }, { "check", required_argument, NULL, 'C' }, { "block-size", required_argument, NULL, OPT_BLOCK_SIZE }, + { "block-list", required_argument, NULL, OPT_BLOCK_LIST }, { "memlimit-compress", required_argument, NULL, OPT_MEM_COMPRESS }, { "memlimit-decompress", required_argument, NULL, OPT_MEM_DECOMPRESS }, { "memlimit", required_argument, NULL, 'M' }, @@ -378,6 +441,11 @@ parse_real(args_info *args, int argc, char **argv) 0, LZMA_VLI_MAX); break; + case OPT_BLOCK_LIST: { + parse_block_list(optarg); + break; + } + case OPT_SINGLE_STREAM: opt_single_stream = true; break; @@ -590,3 +658,13 @@ args_parse(args_info *args, int argc, char **argv) return; } + + +#ifndef NDEBUG +extern void +args_free(void) +{ + free(opt_block_list); + return; +} +#endif |