Re: [PATCH v3 01/42] parse-options: support --git-completion-helper

2018-12-02 Thread Ævar Arnfjörð Bjarmason


On Fri, Feb 09 2018, Nguyễn Thái Ngọc Duy wrote:

> +static int show_gitcomp(struct parse_opt_ctx_t *ctx,
> + const struct option *opts)
> +{

Says it returns 'static int'...

> [...]
> + exit(0);

Then just exits...

> + /* lone --git-completion-helper is asked by git-completion.bash 
> */
> + if (ctx->total == 1 && !strcmp(arg + 1, 
> "-git-completion-helper"))
> + return show_gitcomp(ctx, options);

This return value is never used.

Whine from SunCC (not fatal, also this was in v2.17.0 so no need to fix
before 2.20, just saw this now):

"parse-options.c", line 520: warning: Function has no return
statement : show_gitcomp


[PATCH v3 01/42] parse-options: support --git-completion-helper

2018-02-09 Thread Nguyễn Thái Ngọc Duy
This option is designed to be used by git-completion.bash. For many
simple cases, what we do in there is usually

__gitcomp "lots of completion options"

which has to be manually updated when a new user-visible option is
added. With support from parse-options, we can write

__gitcomp "$(git command --git-completion-helper)"

and get that list directly from the parser for free. Dangerous/Unpopular
options could be hidden with the new "NOCOMPLETE" flag.

Signed-off-by: Nguyễn Thái Ngọc Duy 
---
 parse-options.c | 44 
 parse-options.h |  5 -
 2 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/parse-options.c b/parse-options.c
index fca7159646..29f4defdd6 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -425,6 +425,46 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
parse_options_check(options);
 }
 
+/*
+ * TODO: we are not completing the --no-XXX form yet because there are
+ * many options that do not suppress it properly.
+ */
+static int show_gitcomp(struct parse_opt_ctx_t *ctx,
+   const struct option *opts)
+{
+   for (; opts->type != OPTION_END; opts++) {
+   const char *suffix = "";
+
+   if (!opts->long_name)
+   continue;
+   if (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE))
+   continue;
+
+   switch (opts->type) {
+   case OPTION_GROUP:
+   continue;
+   case OPTION_STRING:
+   case OPTION_FILENAME:
+   case OPTION_INTEGER:
+   case OPTION_MAGNITUDE:
+   case OPTION_CALLBACK:
+   if (opts->flags & PARSE_OPT_NOARG)
+   break;
+   if (opts->flags & PARSE_OPT_OPTARG)
+   break;
+   if (opts->flags & PARSE_OPT_LASTARG_DEFAULT)
+   break;
+   suffix = "=";
+   break;
+   default:
+   break;
+   }
+   printf(" --%s%s", opts->long_name, suffix);
+   }
+   fputc('\n', stdout);
+   exit(0);
+}
+
 static int usage_with_options_internal(struct parse_opt_ctx_t *,
   const char * const *,
   const struct option *, int, int);
@@ -455,6 +495,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
if (internal_help && ctx->total == 1 && !strcmp(arg + 1, "h"))
goto show_usage;
 
+   /* lone --git-completion-helper is asked by git-completion.bash 
*/
+   if (ctx->total == 1 && !strcmp(arg + 1, 
"-git-completion-helper"))
+   return show_gitcomp(ctx, options);
+
if (arg[1] != '-') {
ctx->opt = arg + 1;
switch (parse_short_opt(ctx, options)) {
diff --git a/parse-options.h b/parse-options.h
index af711227ae..a5caa0bb1d 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -38,7 +38,8 @@ enum parse_opt_option_flags {
PARSE_OPT_LASTARG_DEFAULT = 16,
PARSE_OPT_NODASH = 32,
PARSE_OPT_LITERAL_ARGHELP = 64,
-   PARSE_OPT_SHELL_EVAL = 256
+   PARSE_OPT_SHELL_EVAL = 256,
+   PARSE_OPT_NOCOMPLETE = 512
 };
 
 struct option;
@@ -89,6 +90,8 @@ typedef int parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
  *   PARSE_OPT_LITERAL_ARGHELP: says that argh shouldn't be enclosed in 
brackets
  * (i.e. '') in the help message.
  * Useful for options with multiple parameters.
+ *   PARSE_OPT_NOCOMPLETE: by default all visible options are completable
+ *by git-completion.bash. This option suppresses that.
  *
  * `callback`::
  *   pointer to the callback to use for OPTION_CALLBACK or
-- 
2.16.1.207.gedba492059