Merge branch 'br/commit-tree-parseopt'
authorJunio C Hamano <gitster@pobox.com>
Wed, 20 Mar 2019 06:16:08 +0000 (15:16 +0900)
committerJunio C Hamano <gitster@pobox.com>
Wed, 20 Mar 2019 06:16:08 +0000 (15:16 +0900)
The command line parser of "git commit-tree" has been rewritten to
use the parse-options API.

* br/commit-tree-parseopt:
commit-tree: utilize parse-options api

1  2 
parse-options.h
diff --combined parse-options.h
index 7d83e2971d9afa11b11d6187bd96afb88cbb6118,3a442eee26c4d3c7e4fa50405bbd3cadb896fa6e..74cce4e7fce74237292e0b34bec2b02e0e945ca7
@@@ -10,7 -10,6 +10,7 @@@ enum parse_opt_type 
        /* options with no arguments */
        OPTION_BIT,
        OPTION_NEGBIT,
 +      OPTION_BITOP,
        OPTION_COUNTUP,
        OPTION_SET_INT,
        OPTION_CMDMODE,
@@@ -28,8 -27,7 +28,8 @@@ enum parse_opt_flags 
        PARSE_OPT_STOP_AT_NON_OPTION = 2,
        PARSE_OPT_KEEP_ARGV0 = 4,
        PARSE_OPT_KEEP_UNKNOWN = 8,
 -      PARSE_OPT_NO_INTERNAL_HELP = 16
 +      PARSE_OPT_NO_INTERNAL_HELP = 16,
 +      PARSE_OPT_ONE_SHOT = 32
  };
  
  enum parse_opt_option_flags {
@@@ -49,9 -47,8 +49,9 @@@ struct option
  typedef int parse_opt_cb(const struct option *, const char *arg, int unset);
  
  struct parse_opt_ctx_t;
 -typedef int parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
 -                              const struct option *opt, int unset);
 +typedef enum parse_opt_result parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
 +                                            const struct option *opt,
 +                                            const char *arg, int unset);
  
  /*
   * `type`::
   *                     the option takes optional argument.
   *
   * `callback`::
 - *   pointer to the callback to use for OPTION_CALLBACK or
 - *   OPTION_LOWLEVEL_CALLBACK.
 + *   pointer to the callback to use for OPTION_CALLBACK
   *
   * `defval`::
   *   default value to fill (*->value) with for PARSE_OPT_OPTARG.
   *   OPTION_{BIT,SET_INT} store the {mask,integer} to put in the value when met.
   *   CALLBACKS can use it like they want.
 + *
 + * `ll_callback`::
 + *   pointer to the callback to use for OPTION_LOWLEVEL_CALLBACK
 + *
   */
  struct option {
        enum parse_opt_type type;
        int flags;
        parse_opt_cb *callback;
        intptr_t defval;
 +      parse_opt_ll_cb *ll_callback;
 +      intptr_t extra;
  };
  
  #define OPT_BIT_F(s, l, v, h, b, f) { OPTION_BIT, (s), (l), (v), NULL, (h), \
  #define OPT_SET_INT_F(s, l, v, h, i, f) { OPTION_SET_INT, (s), (l), (v), NULL, \
                                          (h), PARSE_OPT_NOARG | (f), NULL, (i) }
  #define OPT_BOOL_F(s, l, v, h, f)   OPT_SET_INT_F(s, l, v, h, 1, f)
 +#define OPT_CALLBACK_F(s, l, v, a, h, f, cb)                  \
 +      { OPTION_CALLBACK, (s), (l), (v), (a), (h), (f), (cb) }
  
  #define OPT_END()                   { OPTION_END }
  #define OPT_ARGUMENT(l, h)          { OPTION_ARGUMENT, 0, (l), NULL, NULL, \
                                      (h), PARSE_OPT_NOARG}
  #define OPT_GROUP(h)                { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
  #define OPT_BIT(s, l, v, h, b)      OPT_BIT_F(s, l, v, h, b, 0)
 +#define OPT_BITOP(s, l, v, h, set, clear) { OPTION_BITOP, (s), (l), (v), NULL, (h), \
 +                                          PARSE_OPT_NOARG|PARSE_OPT_NONEG, NULL, \
 +                                          (set), NULL, (clear) }
  #define OPT_NEGBIT(s, l, v, h, b)   { OPTION_NEGBIT, (s), (l), (v), NULL, \
                                      (h), PARSE_OPT_NOARG, NULL, (b) }
  #define OPT_COUNTUP(s, l, v, h)     OPT_COUNTUP_F(s, l, v, h, 0)
  #define OPT_EXPIRY_DATE(s, l, v, h) \
        { OPTION_CALLBACK, (s), (l), (v), N_("expiry-date"),(h), 0,     \
          parse_opt_expiry_date_cb }
 -#define OPT_CALLBACK(s, l, v, a, h, f) \
 -      { OPTION_CALLBACK, (s), (l), (v), (a), (h), 0, (f) }
 +#define OPT_CALLBACK(s, l, v, a, h, f) OPT_CALLBACK_F(s, l, v, a, h, 0, f)
  #define OPT_NUMBER_CALLBACK(v, h, f) \
        { OPTION_NUMBER, 0, NULL, (v), NULL, (h), \
          PARSE_OPT_NOARG | PARSE_OPT_NONEG, (f) }
          N_("no-op (backward compatibility)"),         \
          PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, parse_opt_noop_cb }
  
 -/* parse_options() will filter out the processed options and leave the
 - * non-option arguments in argv[]. usagestr strings should be marked
 - * for translation with N_().
 +/*
 + * parse_options() will filter out the processed options and leave the
 + * non-option arguments in argv[]. argv0 is assumed program name and
 + * skipped.
 + *
 + * usagestr strings should be marked for translation with N_().
 + *
   * Returns the number of arguments left in argv[].
 + *
 + * In one-shot mode, argv0 is not a program name, argv[] is left
 + * untouched and parse_options() returns the number of options
 + * processed.
   */
 -extern int parse_options(int argc, const char **argv, const char *prefix,
 -                       const struct option *options,
 -                       const char * const usagestr[], int flags);
 +int parse_options(int argc, const char **argv, const char *prefix,
 +                const struct option *options,
 +                const char * const usagestr[], int flags);
  
 -extern NORETURN void usage_with_options(const char * const *usagestr,
 -                                      const struct option *options);
 +NORETURN void usage_with_options(const char * const *usagestr,
 +                               const struct option *options);
  
 -extern NORETURN void usage_msg_opt(const char *msg,
 -                                 const char * const *usagestr,
 -                                 const struct option *options);
 +NORETURN void usage_msg_opt(const char *msg,
 +                          const char * const *usagestr,
 +                          const struct option *options);
  
 -extern int optbug(const struct option *opt, const char *reason);
 +int optbug(const struct option *opt, const char *reason);
  const char *optname(const struct option *opt, int flags);
  
  /*
                BUG("option callback does not expect an argument"); \
  } while (0)
  
+ /*
+  * Similar to the assertions above, but checks that "arg" is always non-NULL.
+  * This assertion also implies BUG_ON_OPT_NEG(), letting you declare both
+  * assertions in a single line.
+  */
+ #define BUG_ON_OPT_NEG_NOARG(unset, arg) do { \
+       BUG_ON_OPT_NEG(unset); \
+       if(!(arg)) \
+               BUG("option callback expects an argument"); \
+ } while(0)
  /*----- incremental advanced APIs -----*/
  
 -enum {
 -      PARSE_OPT_COMPLETE = -2,
 -      PARSE_OPT_HELP = -1,
 -      PARSE_OPT_DONE,
 +enum parse_opt_result {
 +      PARSE_OPT_COMPLETE = -3,
 +      PARSE_OPT_HELP = -2,
 +      PARSE_OPT_ERROR = -1,   /* must be the same as error() */
 +      PARSE_OPT_DONE = 0,     /* fixed so that "return 0" works */
        PARSE_OPT_NON_OPTION,
 -      PARSE_OPT_ERROR,
        PARSE_OPT_UNKNOWN
  };
  
@@@ -247,31 -238,31 +258,31 @@@ struct parse_opt_ctx_t 
        const char *prefix;
  };
  
 -extern void parse_options_start(struct parse_opt_ctx_t *ctx,
 -                              int argc, const char **argv, const char *prefix,
 -                              const struct option *options, int flags);
 +void parse_options_start(struct parse_opt_ctx_t *ctx,
 +                       int argc, const char **argv, const char *prefix,
 +                       const struct option *options, int flags);
  
 -extern int parse_options_step(struct parse_opt_ctx_t *ctx,
 -                            const struct option *options,
 -                            const char * const usagestr[]);
 +int parse_options_step(struct parse_opt_ctx_t *ctx,
 +                     const struct option *options,
 +                     const char * const usagestr[]);
  
 -extern int parse_options_end(struct parse_opt_ctx_t *ctx);
 +int parse_options_end(struct parse_opt_ctx_t *ctx);
  
 -extern struct option *parse_options_concat(struct option *a, struct option *b);
 +struct option *parse_options_concat(struct option *a, struct option *b);
  
  /*----- some often used options -----*/
 -extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
 -extern int parse_opt_expiry_date_cb(const struct option *, const char *, int);
 -extern int parse_opt_color_flag_cb(const struct option *, const char *, int);
 -extern int parse_opt_verbosity_cb(const struct option *, const char *, int);
 -extern int parse_opt_object_name(const struct option *, const char *, int);
 -extern int parse_opt_commits(const struct option *, const char *, int);
 -extern int parse_opt_tertiary(const struct option *, const char *, int);
 -extern int parse_opt_string_list(const struct option *, const char *, int);
 -extern int parse_opt_noop_cb(const struct option *, const char *, int);
 -extern int parse_opt_unknown_cb(const struct option *, const char *, int);
 -extern int parse_opt_passthru(const struct option *, const char *, int);
 -extern int parse_opt_passthru_argv(const struct option *, const char *, int);
 +int parse_opt_abbrev_cb(const struct option *, const char *, int);
 +int parse_opt_expiry_date_cb(const struct option *, const char *, int);
 +int parse_opt_color_flag_cb(const struct option *, const char *, int);
 +int parse_opt_verbosity_cb(const struct option *, const char *, int);
 +int parse_opt_object_name(const struct option *, const char *, int);
 +int parse_opt_commits(const struct option *, const char *, int);
 +int parse_opt_tertiary(const struct option *, const char *, int);
 +int parse_opt_string_list(const struct option *, const char *, int);
 +int parse_opt_noop_cb(const struct option *, const char *, int);
 +int parse_opt_unknown_cb(struct parse_opt_ctx_t *ctx, const struct option *, const char *, int);
 +int parse_opt_passthru(const struct option *, const char *, int);
 +int parse_opt_passthru_argv(const struct option *, const char *, int);
  
  #define OPT__VERBOSE(var, h)  OPT_COUNTUP('v', "verbose", (var), (h))
  #define OPT__QUIET(var, h)    OPT_COUNTUP('q', "quiet",   (var), (h))