From c13216f7a66ae470c19c450e5e5d1f44bbbb3dba Mon Sep 17 00:00:00 2001 From: Petr Machata Date: Sat, 2 Jan 2021 01:03:36 +0100 Subject: [PATCH] lib: Generalize parse_mapping() The function parse_mapping() assumes the key is a number, with a single configurable exception, which is using "all" to mean "all possible keys". If a caller wishes to use symbolic names instead of numbers, they cannot reuse this function. To facilitate reuse in these situations, convert parse_mapping() into a helper, parse_mapping_gen(), which instead of an allow-all boolean takes a generic key-parsing callback. Rewrite parse_mapping() in terms of this newly-added helper and add a pair of key parsers, one for just numbers, another for numbers and the keyword "all". Publish the latter as well. Signed-off-by: Petr Machata Signed-off-by: David Ahern --- include/utils.h | 5 +++++ lib/utils.c | 37 +++++++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/include/utils.h b/include/utils.h index 17043925..f1403f73 100644 --- a/include/utils.h +++ b/include/utils.h @@ -331,6 +331,11 @@ int parse_one_of(const char *msg, const char *realval, const char * const *list, size_t len, int *p_err); bool parse_on_off(const char *msg, const char *realval, int *p_err); +int parse_mapping_num_all(__u32 *keyp, const char *key); +int parse_mapping_gen(int *argcp, char ***argvp, + int (*key_cb)(__u32 *keyp, const char *key), + int (*mapping_cb)(__u32 key, char *value, void *data), + void *mapping_cb_data); int parse_mapping(int *argcp, char ***argvp, bool allow_all, int (*mapping_cb)(__u32 key, char *value, void *data), void *mapping_cb_data); diff --git a/lib/utils.c b/lib/utils.c index de875639..90e58fa3 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -1878,9 +1878,10 @@ bool parse_on_off(const char *msg, const char *realval, int *p_err) return parse_one_of(msg, realval, values_on_off, ARRAY_SIZE(values_on_off), p_err); } -int parse_mapping(int *argcp, char ***argvp, bool allow_all, - int (*mapping_cb)(__u32 key, char *value, void *data), - void *mapping_cb_data) +int parse_mapping_gen(int *argcp, char ***argvp, + int (*key_cb)(__u32 *keyp, const char *key), + int (*mapping_cb)(__u32 key, char *value, void *data), + void *mapping_cb_data) { int argc = *argcp; char **argv = *argvp; @@ -1894,9 +1895,7 @@ int parse_mapping(int *argcp, char ***argvp, bool allow_all, break; *colon = '\0'; - if (allow_all && matches(*argv, "all") == 0) { - key = (__u32) -1; - } else if (get_u32(&key, *argv, 0)) { + if (key_cb(&key, *argv)) { ret = 1; break; } @@ -1912,3 +1911,29 @@ int parse_mapping(int *argcp, char ***argvp, bool allow_all, *argvp = argv; return ret; } + +static int parse_mapping_num(__u32 *keyp, const char *key) +{ + return get_u32(keyp, key, 0); +} + +int parse_mapping_num_all(__u32 *keyp, const char *key) +{ + if (matches(key, "all") == 0) { + *keyp = (__u32) -1; + return 0; + } + return parse_mapping_num(keyp, key); +} + +int parse_mapping(int *argcp, char ***argvp, bool allow_all, + int (*mapping_cb)(__u32 key, char *value, void *data), + void *mapping_cb_data) +{ + if (allow_all) + return parse_mapping_gen(argcp, argvp, parse_mapping_num_all, + mapping_cb, mapping_cb_data); + else + return parse_mapping_gen(argcp, argvp, parse_mapping_num, + mapping_cb, mapping_cb_data); +} -- 2.39.2