From d053eb8096a790d81b67c844d918341e797c2659 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Mon, 6 Jan 2020 03:28:28 +0100 Subject: Cleanup: use parse_size function to parse compressor options The XZ option parser had a similar function to parse_size. This commit removes the other implementation and extends parse_size with the one missing feature, i.e. allowing a '%' suffix for a relative value. Signed-off-by: David Oberhollenzer --- include/common.h | 6 +++++- lib/common/comp_opt.c | 47 ++++++----------------------------------------- lib/common/parse_size.c | 12 +++++++++++- mkfs/options.c | 4 ++-- tar/tar2sqfs.c | 6 ++++-- 5 files changed, 28 insertions(+), 47 deletions(-) diff --git a/include/common.h b/include/common.h index 5f768c1..386d8fd 100644 --- a/include/common.h +++ b/include/common.h @@ -164,7 +164,11 @@ sqfs_compressor_t *lzo_compressor_create(const sqfs_compressor_config_t *cfg); an error message to stderr and returns -1 on failure, 0 on success. The "what" string is used to prefix error messages (perror style). + + If reference is non-zero, the suffix '%' can be used to compute the result as + a multiple of the reference value. */ -int parse_size(const char *what, size_t *out, const char *str); +int parse_size(const char *what, size_t *out, const char *str, + size_t reference); #endif /* COMMON_H */ diff --git a/lib/common/comp_opt.c b/lib/common/comp_opt.c index f257036..66d562e 100644 --- a/lib/common/comp_opt.c +++ b/lib/common/comp_opt.c @@ -74,39 +74,6 @@ static int find_lzo_alg(sqfs_compressor_config_t *cfg, const char *name) return -1; } -static int get_size_value(const char *value, sqfs_u32 *out, sqfs_u32 block_size) -{ - int i; - - for (i = 0; isdigit(value[i]) && i < 9; ++i) - ; - - if (i < 1 || i > 9) - return -1; - - *out = atol(value); - - switch (value[i]) { - case '\0': - break; - case 'm': - case 'M': - *out <<= 20; - break; - case 'k': - case 'K': - *out <<= 10; - break; - case '%': - *out = (*out * block_size) / 100; - break; - default: - return -1; - } - - return 0; -} - enum { OPT_WINDOW = 0, OPT_LEVEL, @@ -125,7 +92,7 @@ int compressor_cfg_init_options(sqfs_compressor_config_t *cfg, E_SQFS_COMPRESSOR id, size_t block_size, char *options) { - size_t num_flags = 0, min_level = 0, max_level = 0, level; + size_t num_flags = 0, min_level = 0, max_level = 0, level, dict_size; const flag_t *flags = NULL; char *subopts, *value; int i, opt; @@ -234,10 +201,12 @@ int compressor_cfg_init_options(sqfs_compressor_config_t *cfg, if (value == NULL) goto fail_value; - if (get_size_value(value, &cfg->opt.xz.dict_size, - cfg->block_size)) { - goto fail_dict; + if (parse_size("Parsing XZ dictionary size", + &dict_size, value, cfg->block_size)) { + return -1; } + + cfg->opt.xz.dict_size = dict_size; break; default: if (set_flag(cfg, value, flags, num_flags)) @@ -265,10 +234,6 @@ fail_value: fprintf(stderr, "Missing value for compressor option '%s'.\n", token[opt]); return -1; -fail_dict: - fputs("Dictionary size must be a number with the optional " - "suffix 'm','k' or '%'.\n", stderr); - return -1; } typedef void (*compressor_help_fun_t)(void); diff --git a/lib/common/parse_size.c b/lib/common/parse_size.c index aede38a..1285d3b 100644 --- a/lib/common/parse_size.c +++ b/lib/common/parse_size.c @@ -9,7 +9,8 @@ #include #include -int parse_size(const char *what, size_t *out, const char *str) +int parse_size(const char *what, size_t *out, const char *str, + size_t reference) { const char *in = str; size_t acc = 0, x; @@ -49,6 +50,15 @@ int parse_size(const char *what, size_t *out, const char *str) acc <<= 30; ++in; break; + case '%': + if (reference == 0) + goto fail_suffix; + + if (SZ_MUL_OV(acc, reference, &acc)) + goto fail_ov; + + acc /= 100; + break; case '\0': break; default: diff --git a/mkfs/options.c b/mkfs/options.c index 1fe6081..c063e7c 100644 --- a/mkfs/options.c +++ b/mkfs/options.c @@ -186,7 +186,7 @@ void process_command_line(options_t *opt, int argc, char **argv) break; case 'b': if (parse_size("Block size", &opt->cfg.block_size, - optarg)) { + optarg, 0)) { exit(EXIT_FAILURE); } break; @@ -198,7 +198,7 @@ void process_command_line(options_t *opt, int argc, char **argv) break; case 'B': if (parse_size("Device block size", - &opt->cfg.devblksize, optarg)) { + &opt->cfg.devblksize, optarg, 0)) { exit(EXIT_FAILURE); } if (opt->cfg.devblksize < 1024) { diff --git a/tar/tar2sqfs.c b/tar/tar2sqfs.c index facef07..12055c3 100644 --- a/tar/tar2sqfs.c +++ b/tar/tar2sqfs.c @@ -124,12 +124,14 @@ static void process_args(int argc, char **argv) no_tail_pack = true; break; case 'b': - if (parse_size("Block size", &cfg.block_size, optarg)) + if (parse_size("Block size", &cfg.block_size, + optarg, 0)) { exit(EXIT_FAILURE); + } break; case 'B': if (parse_size("Device block size", &cfg.devblksize, - optarg)) { + optarg, 0)) { exit(EXIT_FAILURE); } if (cfg.devblksize < 1024) { -- cgit v1.2.3