On Mon, Dec 6, 2021 at 2:28 PM Vishal Verma <[email protected]> wrote: > > From: QI Fuli <[email protected]> > > Add parse-config util to help ndctl commands parse ndctl global > configuration files.
Can this add a bit more description / quick summary of how these APIs are used? > > Link: https://lore.kernel.org/r/[email protected] This link is pointing to the original posting I would expect that this gets deleted and replaced with the final Link: to the version of the patch that eventually gets applied. I assume you just pulled the patches down and this link get appended in the resend. > Signed-off-by: QI Fuli <[email protected]> > Signed-off-by: Vishal Verma <[email protected]> > --- > Makefile.am | 2 ++ > util/parse-configs.h | 34 ++++++++++++++++++ > util/parse-configs.c | 82 ++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 118 insertions(+) > create mode 100644 util/parse-configs.h > create mode 100644 util/parse-configs.c > > diff --git a/Makefile.am b/Makefile.am > index 235c362..af55f0e 100644 > --- a/Makefile.am > +++ b/Makefile.am > @@ -70,6 +70,8 @@ noinst_LIBRARIES += libutil.a > libutil_a_SOURCES = \ > util/parse-options.c \ > util/parse-options.h \ > + util/parse-configs.c \ > + util/parse-configs.h \ > util/usage.c \ > util/size.c \ > util/main.c \ > diff --git a/util/parse-configs.h b/util/parse-configs.h > new file mode 100644 > index 0000000..f70f58f > --- /dev/null > +++ b/util/parse-configs.h > @@ -0,0 +1,34 @@ > +// SPDX-License-Identifier: GPL-2.0 > +// Copyright (C) 2021, FUJITSU LIMITED. ALL rights reserved. > + > +#include <stdbool.h> > +#include <stdint.h> > +#include <util/util.h> > + > +enum parse_conf_type { > + CONFIG_STRING, > + CONFIG_END, > + MONITOR_CALLBACK, > +}; > + > +struct config; > +typedef int parse_conf_cb(const struct config *, const char *config_file); > + > +struct config { > + enum parse_conf_type type; > + const char *key; > + void *value; > + void *defval; > + parse_conf_cb *callback; > +}; > + > +#define check_vtype(v, type) ( > BUILD_BUG_ON_ZERO(!__builtin_types_compatible_p(typeof(v), type)) + v ) > + > +#define CONF_END() { .type = CONFIG_END } > +#define CONF_STR(k,v,d) \ > + { .type = CONFIG_STRING, .key = (k), .value = check_vtype(v, const > char **), .defval = (d) } > +#define CONF_MONITOR(k,f) \ > + { .type = MONITOR_CALLBACK, .key = (k), .callback = (f)} > + > +int parse_configs_prefix(const char *__config_file, const char *prefix, > + const struct config *configs); > diff --git a/util/parse-configs.c b/util/parse-configs.c > new file mode 100644 > index 0000000..44dcff4 > --- /dev/null > +++ b/util/parse-configs.c > @@ -0,0 +1,82 @@ > +// SPDX-License-Identifier: GPL-2.0 > +// Copyright (C) 2021, FUJITSU LIMITED. ALL rights reserved. > + > +#include <errno.h> > +#include <util/parse-configs.h> > +#include <util/strbuf.h> > +#include <util/iniparser.h> > + > +static void set_str_val(const char **value, const char *val) > +{ > + struct strbuf buf = STRBUF_INIT; > + size_t len = *value ? strlen(*value) : 0; > + > + if (!val) > + return; > + > + if (len) { > + strbuf_add(&buf, *value, len); > + strbuf_addstr(&buf, " "); > + } > + strbuf_addstr(&buf, val); > + *value = strbuf_detach(&buf, NULL); > +} > + > +static int parse_config_file(const char *config_file, > + const struct config *configs) > +{ > + dictionary *dic; > + > + dic = iniparser_load(config_file); > + if (!dic) > + return -errno; > + > + for (; configs->type != CONFIG_END; configs++) { > + switch (configs->type) { > + case CONFIG_STRING: > + set_str_val((const char **)configs->value, > + iniparser_getstring(dic, > + configs->key, configs->defval)); > + break; > + case MONITOR_CALLBACK: > + case CONFIG_END: > + break; > + } > + } > + > + iniparser_freedict(dic); > + return 0; > +} > + > +int parse_configs_prefix(const char *__config_files, const char *prefix, > + const struct config *configs) > +{ > + char *config_files, *save; > + const char *config_file; > + int rc; > + > + config_files = strdup(__config_files); > + if (!config_files) > + return -ENOMEM; > + > + for (config_file = strtok_r(config_files, " ", &save); config_file; > + config_file = strtok_r(NULL, " ", &save)) { > + > + if (strncmp(config_file, "./", 2) != 0) > + fix_filename(prefix, &config_file); > + > + if ((configs->type == MONITOR_CALLBACK) && > + (strcmp(config_file, configs->key) == 0)) > + rc = configs->callback(configs, configs->key); > + else > + rc = parse_config_file(config_file, configs); > + > + if (rc) > + goto end; > + } > + > + end: > + free(config_files); > + return rc; > + > +} > -- > 2.33.1 >
