From 61c4ff8b2ddc3841050c17a5f87791653dbd2b7b Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 3 Apr 2023 10:17:09 +0200 Subject: Adding upstream version 2.4+really2.3. This reverts commit f42531334c05b7f49ae43c0a27e347a487fb2667. --- util/argconfig.c | 365 +++++++++++++++++++++++++++---------------------------- util/argconfig.h | 11 +- util/crc32.c | 99 --------------- util/crc32.h | 11 -- util/json.c | 14 --- util/json.h | 10 +- util/meson.build | 10 +- util/suffix.c | 170 ++++++++------------------ util/suffix.h | 4 +- util/types.c | 40 ++---- util/types.h | 1 - 11 files changed, 246 insertions(+), 489 deletions(-) delete mode 100644 util/crc32.c delete mode 100644 util/crc32.h (limited to 'util') diff --git a/util/argconfig.c b/util/argconfig.c index 3eb885f..231a704 100644 --- a/util/argconfig.c +++ b/util/argconfig.c @@ -42,12 +42,6 @@ #include #include -#if __has_attribute(__fallthrough__) -#define fallthrough __attribute__((__fallthrough__)) -#else -#define fallthrough do {} while (0) -#endif - static argconfig_help_func *help_funcs[MAX_HELP_FUNC] = { NULL }; static char END_DEFAULT[] = "__end_default__"; @@ -128,197 +122,69 @@ static void show_option(const struct argconfig_commandline_options *option) } void argconfig_print_help(const char *program_desc, - struct argconfig_commandline_options *s) + const struct argconfig_commandline_options *options) { + const struct argconfig_commandline_options *s; + fprintf(stderr, "\033[1mUsage: %s\033[0m\n\n", append_usage_str); print_word_wrapped(program_desc, 0, 0, stderr); fprintf(stderr, "\n"); - if (!s || !s->option) + if (!options || !options->option) return; fprintf(stderr, "\n\033[1mOptions:\033[0m\n"); - for (; s && s->option; s++) + for (s = options; (s != NULL) && (s->option != NULL); s++) show_option(s); } -static int argconfig_error(char *type, const char *opt, const char *arg) -{ - fprintf(stderr, "Expected %s argument for '%s' but got '%s'!\n", type, opt, arg); - return -EINVAL; -} - int argconfig_parse_byte(const char *opt, const char *str, unsigned char *val) { char *endptr; unsigned long tmp = strtoul(str, &endptr, 0); - if (errno || tmp >= 1 << 8 || str == endptr) - return argconfig_error("byte", opt, str); + if (errno || tmp >= 1 << 8 || str == endptr) { + fprintf(stderr, + "Expected byte argument for '%s' but got '%s'!\n", opt, + str); + return -EINVAL; + } *val = tmp; return 0; } -static int argconfig_parse_type(struct argconfig_commandline_options *s, struct option *option, - int index) -{ - void *value = (void *)(char *)s->default_value; - char *endptr; - const char *fopts = NULL; - FILE *f; - int ret = 0; - char **opts = ((char **)value); - int remaining_space = CFG_MAX_SUBOPTS - 2; - - switch (s->config_type) { - case CFG_STRING: - *((char **)value) = optarg; - break; - case CFG_SIZE: - *((size_t *)value) = strtol(optarg, &endptr, 0); - if (errno || optarg == endptr) - ret = argconfig_error("integer", option[index].name, optarg); - break; - case CFG_INT: - *((int *)value) = strtol(optarg, &endptr, 0); - if (errno || optarg == endptr) - ret = argconfig_error("integer", option[index].name, optarg); - break; - case CFG_BOOL: { - int tmp = strtol(optarg, &endptr, 0); - if (errno || tmp < 0 || tmp > 1 || optarg == endptr) - ret = argconfig_error("0 or 1", option[index].name, optarg); - else - *((int *)value) = tmp; - break; - } - case CFG_BYTE: - ret = argconfig_parse_byte(option[index].name, optarg, (uint8_t *)value); - break; - case CFG_SHORT: { - unsigned long tmp = strtoul(optarg, &endptr, 0); - if (errno || tmp >= 1 << 16 || optarg == endptr) - ret = argconfig_error("short", option[index].name, optarg); - else - *((uint16_t *)value) = tmp; - break; - } - case CFG_POSITIVE: { - uint32_t tmp = strtoul(optarg, &endptr, 0); - if (errno || optarg == endptr) - ret = argconfig_error("word", option[index].name, optarg); - else - *((uint32_t *)value) = tmp; - break; - } - case CFG_INCREMENT: - *((int *)value) += 1; - break; - case CFG_LONG: - *((unsigned long *)value) = strtoul(optarg, &endptr, 0); - if (errno || optarg == endptr) - ret = argconfig_error("long integer", option[index].name, optarg); - break; - case CFG_LONG_SUFFIX: - ret = suffix_binary_parse(optarg, &endptr, (uint64_t*)value); - if (ret) - argconfig_error("long suffixed integer", option[index].name, optarg); - break; - case CFG_DOUBLE: - *((double *)value) = strtod(optarg, &endptr); - if (errno || optarg == endptr) - ret = argconfig_error("float", option[index].name, optarg); - break; - case CFG_SUBOPTS: - *opts = END_DEFAULT; - opts += 2; - ret = argconfig_parse_subopt_string(optarg, opts, remaining_space); - if (ret) { - if (ret == 2) - fprintf(stderr, "Error Parsing Sub-Options: Too many options!\n"); - else - fprintf(stderr, "Error Parsing Sub-Options\n"); - ret = -EINVAL; - } - break; - case CFG_FILE_A: - fopts = "a"; - fallthrough; - case CFG_FILE_R: - if (!fopts) - fopts = "r"; - fallthrough; - case CFG_FILE_W: - if (!fopts) - fopts = "w"; - fallthrough; - case CFG_FILE_AP: - if (!fopts) - fopts = "a+"; - fallthrough; - case CFG_FILE_RP: - if (!fopts) - fopts = "r+"; - fallthrough; - case CFG_FILE_WP: - if (!fopts) - fopts = "w+"; - f = fopen(optarg, fopts); - if (!f) { - fprintf(stderr, "Unable to open %s file: %s\n", s->option, optarg); - ret = -EINVAL; - } else { - *((FILE **)value) = f; - } - break; - case CFG_FLAG: - *((bool *)value) = true; - break; - default: - break; - } - - return ret; -} - -bool argconfig_output_format_json(bool set) -{ - static bool output_format_json = false; - - if (set) - output_format_json = true; - - return output_format_json; -} - int argconfig_parse(int argc, char *argv[], const char *program_desc, - struct argconfig_commandline_options *options) + const struct argconfig_commandline_options *options) { char *short_opts; + char *endptr; struct option *long_opts; - struct argconfig_commandline_options *s; + const struct argconfig_commandline_options *s; int c, option_index = 0, short_index = 0, options_count = 0; - int ret = 0; + void *value_addr; + int ret = -EINVAL; errno = 0; - for (s = options; s->option; s++) + for (s = options; s->option != NULL; s++) options_count++; - long_opts = calloc(1, sizeof(struct option) * (options_count + 3)); - short_opts = calloc(1, sizeof(*short_opts) * (options_count * 3 + 5)); + long_opts = malloc(sizeof(struct option) * (options_count + 2)); + short_opts = malloc(sizeof(*short_opts) * (options_count * 3 + 4)); if (!long_opts || !short_opts) { - fprintf(stderr, "failed to allocate memory for opts: %s\n", strerror(errno)); + fprintf(stderr, "failed to allocate memory for opts: %s\n", + strerror(errno)); ret = -errno; goto out; } - for (s = options; s->option && option_index < options_count; s++) { - if (s->short_option) { + for (s = options; (s->option != NULL) && (option_index < options_count); + s++) { + if (s->short_option != 0) { short_opts[short_index++] = s->short_option; if (s->argument_type == required_argument || s->argument_type == optional_argument) @@ -329,32 +195,35 @@ int argconfig_parse(int argc, char *argv[], const char *program_desc, if (s->option && strlen(s->option)) { long_opts[option_index].name = s->option; long_opts[option_index].has_arg = s->argument_type; + long_opts[option_index].flag = NULL; + long_opts[option_index].val = 0; } - s->seen = false; option_index++; } long_opts[option_index].name = "help"; - long_opts[option_index++].val = 'h'; + long_opts[option_index].flag = NULL; + long_opts[option_index].val = 'h'; + option_index++; - long_opts[option_index].name = "json"; - long_opts[option_index].val = 'j'; + long_opts[option_index].name = NULL; + long_opts[option_index].flag = NULL; + long_opts[option_index].val = 0; short_opts[short_index++] = '?'; short_opts[short_index++] = 'h'; - short_opts[short_index] = 'j'; + short_opts[short_index] = 0; optind = 0; - while ((c = getopt_long_only(argc, argv, short_opts, long_opts, &option_index)) != -1) { - if (c) { + while ((c = getopt_long_only(argc, argv, short_opts, long_opts, + &option_index)) != -1) { + if (c != 0) { if (c == '?' || c == 'h') { argconfig_print_help(program_desc, options); - ret = -EINVAL; - break; + goto out; } - if (c == 'j') - argconfig_output_format_json(true); - for (option_index = 0; option_index < options_count; option_index++) { + for (option_index = 0; option_index < options_count; + option_index++) { if (c == options[option_index].short_option) break; } @@ -363,16 +232,147 @@ int argconfig_parse(int argc, char *argv[], const char *program_desc, } s = &options[option_index]; - s->seen = true; + value_addr = (void *)(char *)s->default_value; + if (s->config_type == CFG_STRING) { + *((char **)value_addr) = optarg; + } else if (s->config_type == CFG_SIZE) { + *((size_t *) value_addr) = strtol(optarg, &endptr, 0); + if (errno || optarg == endptr) { + fprintf(stderr, + "Expected integer argument for '%s' but got '%s'!\n", + long_opts[option_index].name, optarg); + goto out; + } + } else if (s->config_type == CFG_INT) { + *((int *)value_addr) = strtol(optarg, &endptr, 0); + if (errno || optarg == endptr) { + fprintf(stderr, + "Expected integer argument for '%s' but got '%s'!\n", + long_opts[option_index].name, optarg); + goto out; + } + } else if (s->config_type == CFG_BOOL) { + int tmp = strtol(optarg, &endptr, 0); + if (errno || tmp < 0 || tmp > 1 || optarg == endptr) { + fprintf(stderr, + "Expected 0 or 1 argument for '%s' but got '%s'!\n", + long_opts[option_index].name, optarg); + goto out; + } + *((int *)value_addr) = tmp; + } else if (s->config_type == CFG_BYTE) { + if (argconfig_parse_byte(long_opts[option_index].name, + optarg, (uint8_t *)value_addr)) + goto out; + } else if (s->config_type == CFG_SHORT) { + unsigned long tmp = strtoul(optarg, &endptr, 0); + if (errno || tmp >= (1 << 16) || optarg == endptr) { + fprintf(stderr, + "Expected short argument for '%s' but got '%s'!\n", + long_opts[option_index].name, optarg); + goto out; + } + *((uint16_t *) value_addr) = tmp; + } else if (s->config_type == CFG_POSITIVE) { + uint32_t tmp = strtoul(optarg, &endptr, 0); + if (errno || optarg == endptr) { + fprintf(stderr, + "Expected word argument for '%s' but got '%s'!\n", + long_opts[option_index].name, optarg); + goto out; + } + *((uint32_t *) value_addr) = tmp; + } else if (s->config_type == CFG_INCREMENT) { + *((int *)value_addr) += 1; + } else if (s->config_type == CFG_LONG) { + *((unsigned long *)value_addr) = strtoul(optarg, &endptr, 0); + if (errno || optarg == endptr) { + fprintf(stderr, + "Expected long integer argument for '%s' but got '%s'!\n", + long_opts[option_index].name, optarg); + goto out; + } + } else if (s->config_type == CFG_LONG_SUFFIX) { + *((uint64_t *)value_addr) = suffix_binary_parse(optarg); + if (errno) { + fprintf(stderr, + "Expected long suffixed integer argument for '%s' but got '%s'!\n", + long_opts[option_index].name, optarg); + goto out; + } + } else if (s->config_type == CFG_DOUBLE) { + *((double *)value_addr) = strtod(optarg, &endptr); + if (errno || optarg == endptr) { + fprintf(stderr, + "Expected float argument for '%s' but got '%s'!\n", + long_opts[option_index].name, optarg); + goto out; + } + } else if (s->config_type == CFG_SUBOPTS) { + char **opts = ((char **)value_addr); + int remaining_space = CFG_MAX_SUBOPTS; + int enddefault = 0; + int r; + while (0 && *opts != NULL) { + if (*opts == END_DEFAULT) + enddefault = 1; + remaining_space--; + opts++; + } - if (!s->default_value) - continue; + if (!enddefault) { + *opts = END_DEFAULT; + remaining_space -= 2; + opts += 2; + } - ret = argconfig_parse_type(s, long_opts,option_index); - if (ret) - break; + r = argconfig_parse_subopt_string(optarg, opts, + remaining_space); + if (r == 2) { + fprintf(stderr, + "Error Parsing Sub-Options: Too many options!\n"); + goto out; + } else if (r) { + fprintf(stderr, "Error Parsing Sub-Options\n"); + goto out; + } + } else if (s->config_type == CFG_FILE_A || + s->config_type == CFG_FILE_R || + s->config_type == CFG_FILE_W || + s->config_type == CFG_FILE_AP || + s->config_type == CFG_FILE_RP || + s->config_type == CFG_FILE_WP) { + const char *fopts = ""; + FILE *f; + if (s->config_type == CFG_FILE_A) + fopts = "a"; + else if (s->config_type == CFG_FILE_R) + fopts = "r"; + else if (s->config_type == CFG_FILE_W) + fopts = "w"; + else if (s->config_type == CFG_FILE_AP) + fopts = "a+"; + else if (s->config_type == CFG_FILE_RP) + fopts = "r+"; + else if (s->config_type == CFG_FILE_WP) + fopts = "w+"; + + f = fopen(optarg, fopts); + if (f == NULL) { + fprintf(stderr, "Unable to open %s file: %s\n", + s->option, optarg); + goto out; + } + *((FILE **) value_addr) = f; + } else if (s->config_type == CFG_FLAG) { + *((bool *)value_addr) = true; + } } -out: + free(short_opts); + free(long_opts); + + return 0; + out: free(short_opts); free(long_opts); return ret; @@ -592,14 +592,3 @@ void argconfig_register_help_func(argconfig_help_func * f) } } } - -bool argconfig_parse_seen(struct argconfig_commandline_options *s, - const char *option) -{ - for (; s && s->option; s++) { - if (!strcmp(s->option, option)) - return s->seen; - } - - return false; -} diff --git a/util/argconfig.h b/util/argconfig.h index 81eaaf4..6ef3b6a 100644 --- a/util/argconfig.h +++ b/util/argconfig.h @@ -38,7 +38,6 @@ #include #include #include -#include enum argconfig_types { CFG_FLAG, @@ -63,7 +62,7 @@ enum argconfig_types { }; #define OPT_ARGS(n) \ - struct argconfig_commandline_options n[] + const struct argconfig_commandline_options n[] #define OPT_END() { NULL } @@ -110,7 +109,6 @@ struct argconfig_commandline_options { void *default_value; int argument_type; const char *help; - bool seen; }; #define CFG_MAX_SUBOPTS 500 @@ -119,9 +117,9 @@ struct argconfig_commandline_options { typedef void argconfig_help_func(); void argconfig_append_usage(const char *str); void argconfig_print_help(const char *program_desc, - struct argconfig_commandline_options *options); + const struct argconfig_commandline_options *options); int argconfig_parse(int argc, char *argv[], const char *program_desc, - struct argconfig_commandline_options *options); + const struct argconfig_commandline_options *options); int argconfig_parse_subopt_string(char *string, char **options, size_t max_options); int argconfig_parse_comma_sep_array(char *string, int *ret, @@ -135,7 +133,4 @@ int argconfig_parse_byte(const char *opt, const char *str, unsigned char *val); void argconfig_register_help_func(argconfig_help_func * f); void print_word_wrapped(const char *s, int indent, int start, FILE *stream); -bool argconfig_parse_seen(struct argconfig_commandline_options *options, - const char *option); -bool argconfig_output_format_json(bool set); #endif diff --git a/util/crc32.c b/util/crc32.c deleted file mode 100644 index cc2d8f2..0000000 --- a/util/crc32.c +++ /dev/null @@ -1,99 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -/* Copyright (C) 2002 Red Hat, Inc. - This file is part of elfutils. - - This file is free software; you can redistribute it and/or modify - it under the terms of either - - * the GNU Lesser General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at - your option) any later version - - or - - * the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at - your option) any later version - - or both in parallel, as here. - - elfutils is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received copies of the GNU General Public License and - the GNU Lesser General Public License along with this program. If - not, see . */ - -/* https://sourceware.org/git/?p=elfutils.git;a=blob;f=lib/crc32.c;hb=575198c29a427392823cc8f2400579a23d06a875 */ - -#include "crc32.h" - -/* Table computed with Mark Adler's makecrc.c utility. */ -static const uint32_t crc32_table[256] = -{ - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d -}; - -uint32_t crc32 (uint32_t crc, unsigned char *buf, size_t len) -{ - unsigned char *end; - - crc = ~crc; - for (end = buf + len; buf < end; ++buf) - crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8); - return ~crc; -} diff --git a/util/crc32.h b/util/crc32.h deleted file mode 100644 index e48c97d..0000000 --- a/util/crc32.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#ifndef crc32_H -#define crc32_H - -#include -#include - -uint32_t crc32(uint32_t crc, unsigned char *buf, size_t len); - -#endif diff --git a/util/json.c b/util/json.c index 2de5848..84d43e5 100644 --- a/util/json.c +++ b/util/json.c @@ -35,24 +35,10 @@ struct json_object *util_json_object_new_uint64(uint64_t i) } -static int util_json_object_string_to_number(struct json_object *jso, - struct printbuf *pb, int level, - int flags) -{ - ssize_t len = json_object_get_string_len(jso); - - printbuf_memappend(pb, json_object_get_string(jso), len); - - return 0; -} - struct json_object *util_json_object_new_uint128(nvme_uint128_t val) { struct json_object *obj; - obj = json_object_new_string(uint128_t_to_string(val)); - json_object_set_serializer(obj, util_json_object_string_to_number, NULL, NULL); - return obj; } diff --git a/util/json.h b/util/json.h index c362408..1312cb8 100644 --- a/util/json.h +++ b/util/json.h @@ -2,7 +2,6 @@ #ifndef __JSON__H #define __JSON__H -#ifdef CONFIG_JSONC #include #include "util/types.h" @@ -13,7 +12,7 @@ #define json_free_object(o) json_object_put(o) #define json_free_array(a) json_object_put(a) #define json_object_add_value_uint(o, k, v) \ - json_object_object_add(o, k, json_object_new_uint64(v)) + json_object_object_add(o, k, json_object_new_int(v)) #define json_object_add_value_int(o, k, v) \ json_object_object_add(o, k, json_object_new_int(v)) #ifndef CONFIG_JSONC_14 @@ -49,11 +48,4 @@ struct json_object *util_json_object_new_uint128(nvme_uint128_t val); struct json_object *util_json_object_new_uint128(nvme_uint128_t val); uint64_t util_json_object_get_uint64(struct json_object *obj); - -#else /* !CONFIG_JSONC */ - -struct json_object; - -#endif - #endif diff --git a/util/meson.build b/util/meson.build index f149d03..349c70c 100644 --- a/util/meson.build +++ b/util/meson.build @@ -2,15 +2,9 @@ sources += [ 'util/argconfig.c', - 'util/base64.c', 'util/cleanup.c', - 'util/crc32.c', + 'util/json.c', 'util/suffix.c', + 'util/base64.c', 'util/types.c', ] - -if json_c_dep.found() - sources += [ - 'util/json.c', - ] -endif diff --git a/util/suffix.c b/util/suffix.c index 8ed080d..4106958 100644 --- a/util/suffix.c +++ b/util/suffix.c @@ -31,31 +31,28 @@ */ #include "suffix.h" -#include "common.h" #include #include #include #include -#include -#include -#include static struct si_suffix { long double magnitude; - unsigned int exponent; const char *suffix; } si_suffixes[] = { - {1e30, 30, "Q"}, - {1e27, 27, "R"}, - {1e24, 24, "Y"}, - {1e21, 21, "Z"}, - {1e18, 18, "E"}, - {1e15, 15, "P"}, - {1e12, 12, "T"}, - {1e9, 9, "G"}, - {1e6, 6, "M"}, - {1e3, 3, "k"}, + {1e30, "Q"}, + {1e27, "R"}, + {1e24, "Y"}, + {1e21, "Z"}, + {1e18, "E"}, + {1e15, "P"}, + {1e12, "T"}, + {1e9, "G"}, + {1e6, "M"}, + {1e3, "k"}, + {1e0, ""}, + {0} }; const char *suffix_si_get(double *value) @@ -68,87 +65,36 @@ const char *suffix_si_get(double *value) return suffix; } -int suffix_si_parse(const char *str, char **endptr, uint64_t *val) +uint64_t suffix_si_parse(const char *value, bool *suffixed) { - unsigned long long num, frac; - char *sep, *tmp; - int frac_len, len, i; - - num = strtoull(str, endptr, 0); - if (str == *endptr || - ((num == ULLONG_MAX) && errno == ERANGE)) - return -EINVAL; - - /* simple number, no decimal point not suffix */ - if ((*endptr)[0] == '\0') { - *val = num; - return 0; - } + char *suffix; + double ret; + struct si_suffix *s; - /* get rid of the decimal point */ - sep = localeconv()->decimal_point; - if (sep) - len = strlen(sep); - else - len = 0; + errno = 0; + ret = strtod(value, &suffix); + if (errno) + return 0; - for (i = 0; i < len; i++) { - if (((*endptr)[i] == '\0') || (*endptr)[i] != sep[i]) - return -EINVAL; - } - *endptr += len; - tmp = *endptr; - - /* extract the digits after decimal point */ - frac = strtoull(tmp, endptr, 0); - if (tmp == *endptr || - ((frac == ULLONG_MAX) && errno == ERANGE)) - return -EINVAL; - - /* test that we have max one character as suffix */ - if ((*endptr)[0] != '\0' && (*endptr)[1] != '\0') - return -EINVAL; - - frac_len = *endptr - tmp; - - for (i = 0; i < ARRAY_SIZE(si_suffixes); i++) { - struct si_suffix *s = &si_suffixes[i]; - - if ((*endptr)[0] != s->suffix[0]) - continue; - - /* we should check for overflow */ - for (int j = 0; j < s->exponent; j++) - num *= 10; - - if (s->exponent > frac_len) { - for (int j = 0; j < s->exponent - frac_len; j++) - frac *= 10; - } else if (s->exponent < frac_len) { - for (int j = 0; j < frac_len - s->exponent; j++) - frac /= 10; - } else { - frac = 0; + for (s = si_suffixes; s->magnitude != 0; s++) { + if (suffix[0] == s->suffix[0]) { + if (suffixed && suffix[0] != '\0') + *suffixed = true; + return ret *= s->magnitude; } - - *val = num + frac; - return 0; } - if ((*endptr)[0] != '\0') - return -EINVAL; + if (suffix[0] != '\0') + errno = EINVAL; - *val = num; - return 0; + return (uint64_t)ret; } const char *suffix_si_get_ld(long double *value) { - int i; - - for (i = 0; i < ARRAY_SIZE(si_suffixes); i++) { - struct si_suffix *s = &si_suffixes[i]; + struct si_suffix *s; + for (s = si_suffixes; s->magnitude != 0; s++) { if (*value >= s->magnitude) { *value /= s->magnitude; return s->suffix; @@ -167,15 +113,14 @@ static struct binary_suffix { {30, "Gi"}, {20, "Mi"}, {10, "Ki"}, + {0, ""} }; const char *suffix_binary_get(long long *value) { - int i; - - for (i = 0; i < ARRAY_SIZE(binary_suffixes); i++) { - struct binary_suffix *s = &binary_suffixes[i]; + struct binary_suffix *s; + for (s = binary_suffixes; s->shift != 0; s++) { if (llabs(*value) >= (1LL << s->shift)) { *value = (*value + (1LL << (s->shift - 1))) / (1LL << s->shift); @@ -188,11 +133,9 @@ const char *suffix_binary_get(long long *value) const char *suffix_dbinary_get(double *value) { - int i; - - for (i = 0; i < ARRAY_SIZE(binary_suffixes); i++) { - struct binary_suffix *s = &binary_suffixes[i]; + struct binary_suffix *s; + for (s = binary_suffixes; s->shift != 0; s++) { if (fabs(*value) >= (1LL << s->shift)) { *value = *value / (1LL << s->shift); return s->suffix; @@ -202,41 +145,24 @@ const char *suffix_dbinary_get(double *value) return ""; } -int suffix_binary_parse(const char *str, char **endptr, uint64_t *val) +uint64_t suffix_binary_parse(const char *value) { - uint64_t ret; - int i; - - ret = strtoull(str, endptr, 0); - if (str == *endptr || - ((ret == ULLONG_MAX) && errno == ERANGE)) - return -EINVAL; - - if (str == *endptr) { - *val = ret; - return 0; - } - - /* simple number, no decimal point, no suffix */ - if ((*endptr)[0] == '\0') { - *val = ret; + char *suffix; + errno = 0; + uint64_t ret = strtoull(value, &suffix, 0); + if (errno) return 0; - } - for (i = 0; i < ARRAY_SIZE(binary_suffixes); i++) { - struct binary_suffix *s = &binary_suffixes[i]; - - if (tolower((*endptr)[0]) == tolower(s->suffix[0]) && - (s->suffix[0] != '\0' && - (((*endptr)[0] != '\0' && - (*endptr)[1] != '\0' && - (*endptr)[2] == '\0') && - (tolower((*endptr)[1]) == tolower(s->suffix[1]))))) { + struct binary_suffix *s; + for (s = binary_suffixes; s->shift != 0; s++) { + if (tolower(suffix[0]) == tolower(s->suffix[0])) { ret <<= s->shift; - *val = ret; - return 0; + return ret; } } - return -EINVAL; + if (suffix[0] != '\0') + errno = EINVAL; + + return ret; } diff --git a/util/suffix.h b/util/suffix.h index 5ea58f4..b367ce4 100644 --- a/util/suffix.h +++ b/util/suffix.h @@ -36,10 +36,10 @@ #include const char *suffix_si_get(double *value); -int suffix_si_parse(const char *str, char **endptr, uint64_t *val); +uint64_t suffix_si_parse(const char *value, bool *suffixed); const char *suffix_si_get_ld(long double *value); const char *suffix_binary_get(long long *value); const char *suffix_dbinary_get(double *value); -int suffix_binary_parse(const char *str, char **endptr, uint64_t *val); +uint64_t suffix_binary_parse(const char *value); #endif diff --git a/util/types.c b/util/types.c index daef298..18ced77 100644 --- a/util/types.c +++ b/util/types.c @@ -46,31 +46,14 @@ uint64_t int48_to_long(__u8 *data) return result; } -static long double uint128_t_to_double(nvme_uint128_t data) -{ - int i; - long double result = 0; - - for (i = 0; i < sizeof(data.words) / sizeof(*data.words); i++) { - result *= 4294967296; - result += data.words[i]; - } - - return result; -} - -static char *__uint128_t_to_string(nvme_uint128_t val, bool l10n) +char *uint128_t_to_string(nvme_uint128_t val) { static char str[60]; int idx = 60; __u64 div, rem; - char *sep = NULL; - int i, len = 0; - - if (l10n) { - sep = localeconv()->thousands_sep; - len = strlen(sep); - } + char *sep = localeconv()->thousands_sep; + int len = sep ? strlen(sep) : 0; + int i; /* terminate at the end, and build up from the ones */ str[--idx] = '\0'; @@ -105,14 +88,17 @@ static char *__uint128_t_to_string(nvme_uint128_t val, bool l10n) return str + idx; } -char *uint128_t_to_string(nvme_uint128_t val) +static long double uint128_t_to_double(nvme_uint128_t data) { - return __uint128_t_to_string(val, false); -} + int i; + long double result = 0; -char *uint128_t_to_l10n_string(nvme_uint128_t val) -{ - return __uint128_t_to_string(val, true); + for (i = 0; i < sizeof(data.words) / sizeof(*data.words); i++) { + result *= 4294967296; + result += data.words[i]; + } + + return result; } char *uint128_t_to_si_string(nvme_uint128_t val, __u32 bytes_per_unit) diff --git a/util/types.h b/util/types.h index f7fe9fc..2e88717 100644 --- a/util/types.h +++ b/util/types.h @@ -29,7 +29,6 @@ long double int128_to_double(__u8 *data); uint64_t int48_to_long(__u8 *data); char *uint128_t_to_string(nvme_uint128_t val); -char *uint128_t_to_l10n_string(nvme_uint128_t val); char *uint128_t_to_si_string(nvme_uint128_t val, __u32 bytes_per_unit); const char *util_uuid_to_string(unsigned char uuid[NVME_UUID_LEN]); const char *util_fw_to_string(char *c); -- cgit v1.2.3