Please ignore this patch.
I will send the v5 patch set of ndctl monitor which includes this one.

> -----Original Message-----
> From: QI Fuli [mailto:[email protected]]
> Sent: Friday, April 20, 2018 4:28 PM
> To: [email protected]
> Cc: Qi, Fuli/斉 福利 <[email protected]>
> Subject: [PATCH] ndctl, util: add OPTION_FILENAME to parse_opt_type
> 
> This patch borrows the OPTION_FILENAME from git to ndctl to make sure filename
> is correct. Some related refactoring is also included:
>   - adds parse_options_prefix() interface
>   - moves is_absolute from util/help.c to util/util.c
>   - adds a new file util/abspath.c
> 
> Signed-off-by: QI Fuli <[email protected]>
> ---
>  Makefile.am          |  3 ++-
>  util/abspath.c       | 20 ++++++++++++++++
>  util/help.c          |  5 ----
>  util/parse-options.c | 55
> +++++++++++++++++++++++++++++++++++++++-----
>  util/parse-options.h | 11 +++++++--
>  util/util.h          |  6 +++++
>  6 files changed, 86 insertions(+), 14 deletions(-)  create mode 100644
> util/abspath.c
> 
> diff --git a/Makefile.am b/Makefile.am
> index b538b1f..e0c463a 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -69,6 +69,7 @@ libutil_a_SOURCES = \
>       util/strbuf.c \
>       util/wrapper.c \
>       util/filter.c \
> -     util/bitmap.c
> +     util/bitmap.c \
> +     util/abspath.c
> 
>  nobase_include_HEADERS = daxctl/libdaxctl.h diff --git a/util/abspath.c
> b/util/abspath.c new file mode 100644 index 0000000..0a592da
> --- /dev/null
> +++ b/util/abspath.c
> @@ -0,0 +1,20 @@
> +/* originally copied from git */
> +
> +#include <util/util.h>
> +#include <util/strbuf.h>
> +
> +char *prefix_filename(const char *pfx, const char *arg) {
> +     struct strbuf path = STRBUF_INIT;
> +     size_t pfx_len = pfx ? strlen(pfx) : 0;
> +
> +     if (!pfx_len)
> +             ;
> +     else if (is_absolute_path(arg))
> +             pfx_len = 0;
> +     else
> +             strbuf_add(&path, pfx, pfx_len);
> +
> +     strbuf_addstr(&path, arg);
> +     return strbuf_detach(&path, NULL);
> +}
> diff --git a/util/help.c b/util/help.c
> index 8b8f951..2d57fa1 100644
> --- a/util/help.c
> +++ b/util/help.c
> @@ -89,11 +89,6 @@ static char *cmd_to_page(const char *cmd, char **page,
> const char *util_name)
>       return *page;
>  }
> 
> -static int is_absolute_path(const char *path) -{
> -     return path[0] == '/';
> -}
> -
>  static const char *system_path(const char *path)  {
>          static const char *prefix = PREFIX; diff --git a/util/parse-options.c
> b/util/parse-options.c index 751c091..4258c85 100644
> --- a/util/parse-options.c
> +++ b/util/parse-options.c
> @@ -50,11 +50,20 @@ static int get_arg(struct parse_opt_ctx_t *p, const struct
> option *opt,
>       return 0;
>  }
> 
> +static void fix_filename(const char *prefix, const char **file) {
> +     if (!file || !*file || !prefix || is_absolute_path(*file)
> +                     || !strcmp("-", *file))
> +             return;
> +     *file = prefix_filename(prefix, *file); }
> +
>  static int get_value(struct parse_opt_ctx_t *p,
>                    const struct option *opt, int flags)  {
>       const char *s, *arg = NULL;
>       const int unset = flags & OPT_UNSET;
> +     int err;
> 
>       if (unset && p->opt)
>               return opterror(opt, "takes no value", flags); @@ -77,6 +86,7
> @@ static int get_value(struct parse_opt_ctx_t *p,
>               case OPTION_ARGUMENT:
>               case OPTION_GROUP:
>               case OPTION_STRING:
> +             case OPTION_FILENAME:
>               case OPTION_INTEGER:
>               case OPTION_UINTEGER:
>               case OPTION_LONG:
> @@ -121,6 +131,19 @@ static int get_value(struct parse_opt_ctx_t *p,
>                       return get_arg(p, opt, flags, (const char 
> **)opt->value);
>               return 0;
> 
> +     case OPTION_FILENAME:
> +             err = 0;
> +             if (unset)
> +                     *(const char **)opt->value = NULL;
> +             else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
> +                     *(const char **)opt->value = (const char
> *)opt->defval;
> +             else
> +                     err = get_arg(p, opt, flags, (const char **)opt->value);
> +
> +             if (!err)
> +                     fix_filename(p->prefix, (const char **)opt->value);
> +             return err;
> +
>       case OPTION_CALLBACK:
>               if (unset)
>                       return (*opt->callback)(opt, NULL, 1) ? (-1) : 0; @@
> -339,13 +362,14 @@ static void check_typos(const char *arg, const struct 
> option
> *options)
>       }
>  }
> 
> -void parse_options_start(struct parse_opt_ctx_t *ctx,
> -                      int argc, const char **argv, int flags)
> +void parse_options_start(struct parse_opt_ctx_t *ctx, int argc,
> +                     const char **argv, const char *prefix, int flags)
>  {
>       memset(ctx, 0, sizeof(*ctx));
>       ctx->argc = argc - 1;
>       ctx->argv = argv + 1;
>       ctx->out  = argv;
> +     ctx->prefix = prefix;
>       ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
>       ctx->flags = flags;
>       if ((flags & PARSE_OPT_KEEP_UNKNOWN) && @@ -453,8 +477,10 @@
> int parse_options_end(struct parse_opt_ctx_t *ctx)
>       return ctx->cpidx + ctx->argc;
>  }
> 
> -int parse_options_subcommand(int argc, const char **argv, const struct option
> *options,
> -                     const char *const subcommands[], const char
> *usagestr[], int flags)
> +static int parse_options_subcommand_prefix(int argc, const char **argv,
> +                     const char *prefix, const struct option *options,
> +                     const char *const subcommands[],
> +                     const char *usagestr[], int flags)
>  {
>       struct parse_opt_ctx_t ctx;
> 
> @@ -474,7 +500,7 @@ int parse_options_subcommand(int argc, const char
> **argv, const struct option *o
>               strbuf_release(&buf);
>       }
> 
> -     parse_options_start(&ctx, argc, argv, flags);
> +     parse_options_start(&ctx, argc, argv, prefix, flags);
>       switch (parse_options_step(&ctx, options, usagestr)) {
>       case PARSE_OPT_HELP:
>               exit(129);
> @@ -503,10 +529,26 @@ int parse_options_subcommand(int argc, const char
> **argv, const struct option *o
>       return parse_options_end(&ctx);
>  }
> 
> +int parse_options_subcommand(int argc, const char **argv,
> +             const struct option *options, const char *const subcommands[],
> +             const char *usagestr[], int flags)
> +{
> +     return parse_options_subcommand_prefix(argc, argv, NULL, options,
> +                                     subcommands, usagestr, flags);
> +}
> +
> +int parse_options_prefix(int argc, const char **argv, const char *prefix,
> +                     const struct option *options,
> +                     const char * const usagestr[], int flags) {
> +     return parse_options_subcommand_prefix(argc, argv, prefix, options,
> +                             NULL, (const char **) usagestr, flags); }
> +
>  int parse_options(int argc, const char **argv, const struct option *options,
>                 const char * const usagestr[], int flags)  {
> -     return parse_options_subcommand(argc, argv, options, NULL,
> +     return parse_options_subcommand_prefix(argc, argv, NULL, options,
> +NULL,
>                                       (const char **) usagestr, flags);
>  }
> 
> @@ -557,6 +599,7 @@ static void print_option_help(const struct option *opts, 
> int
> full)
>               if (opts->flags & PARSE_OPT_NOARG)
>                       break;
>               /* FALLTHROUGH */
> +     case OPTION_FILENAME:
>       case OPTION_STRING:
>               if (opts->argh) {
>                       if (opts->flags & PARSE_OPT_OPTARG)
> diff --git a/util/parse-options.h b/util/parse-options.h index 
> 6fd6b24..fc5015a
> 100644
> --- a/util/parse-options.h
> +++ b/util/parse-options.h
> @@ -38,6 +38,7 @@ enum parse_opt_type {
>       OPTION_CALLBACK,
>       OPTION_U64,
>       OPTION_UINTEGER,
> +     OPTION_FILENAME,
>  };
> 
>  enum parse_opt_flags {
> @@ -135,6 +136,7 @@ struct option {
>  #define OPT_LONG(s, l, v, h)        { .type = OPTION_LONG, .short_name =
> (s), .long_name = (l), .value = check_vtype(v, long *), .help = (h) }
>  #define OPT_U64(s, l, v, h)         { .type = OPTION_U64, .short_name =
> (s), .long_name = (l), .value = check_vtype(v, u64 *), .help = (h) }
>  #define OPT_STRING(s, l, v, a, h)   { .type = OPTION_STRING,  .short_name =
> (s), .long_name = (l), .value = check_vtype(v, const char **), (a), .help = 
> (h) }
> +#define OPT_FILENAME(s, l, v, a, h) { .type = OPTION_FILENAME,
> +.short_name = (s), .long_name = (l), .value = check_vtype(v, const char
> +**), (a), .help = (h) }
>  #define OPT_DATE(s, l, v, h) \
>       { .type = OPTION_CALLBACK, .short_name = (s), .long_name =
> (l), .value = (v), .argh = "time", .help = (h), .callback =
> parse_opt_approxidate_cb }  #define OPT_CALLBACK(s, l, v, a, h, f) \ @@ -156,6
> +158,10 @@ extern int parse_options(int argc, const char **argv,
>                           const struct option *options,
>                           const char * const usagestr[], int flags);
> 
> +extern int parse_options_prefix(int argc, const char **argv,
> +                     const char *prefix, const struct option *options,
> +                     const char * const usagestr[], int flags);
> +
>  extern int parse_options_subcommand(int argc, const char **argv,
>                               const struct option *options,
>                               const char *const subcommands[],
> @@ -185,6 +191,7 @@ struct parse_opt_ctx_t {
>       int argc, cpidx;
>       const char *opt;
>       int flags;
> +     const char *prefix;
>  };
> 
>  extern int parse_options_usage(const char * const *usagestr, @@ -192,8 +199,8
> @@ extern int parse_options_usage(const char * const *usagestr,
>                              const char *optstr,
>                              bool short_opt);
> 
> -extern void parse_options_start(struct parse_opt_ctx_t *ctx,
> -                             int argc, const char **argv, int flags);
> +extern void parse_options_start(struct parse_opt_ctx_t *ctx, int argc,
> +                     const char **argv, const char *prefix, int flags);
> 
>  extern int parse_options_step(struct parse_opt_ctx_t *ctx,
>                             const struct option *options,
> diff --git a/util/util.h b/util/util.h
> index 162aade..c281e8f 100644
> --- a/util/util.h
> +++ b/util/util.h
> @@ -79,6 +79,11 @@ static inline const char *skip_prefix(const char *str, 
> const
> char *prefix)
>          return strncmp(str, prefix, len) ? NULL : str + len;  }
> 
> +static inline int is_absolute_path(const char *path) {
> +     return path[0] == '/';
> +}
> +
>  void usage(const char *err) NORETURN;
>  void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 
> 2)));
> int error(const char *err, ...) __attribute__((format (printf, 1, 2))); @@ 
> -87,5
> +92,6 @@ void set_die_routine(void (*routine)(const char *err, va_list params)
> NORETURN);  char *xstrdup(const char *str);  void *xrealloc(void *ptr, size_t
> size);  int prefixcmp(const char *str, const char *prefix);
> +char *prefix_filename(const char *pfx, const char *arg);
> 
>  #endif /* __UTIL_H__ */
> --
> 2.17.0.140.g0b0cc9f86


_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm

Reply via email to