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
>

Reply via email to