packaging: Add contrib installation
[platform/upstream/git.git] / parse-options.c
index c278aff..f050743 100644 (file)
@@ -61,7 +61,7 @@ static enum parse_opt_result opt_command_mode_error(
         */
        for (that = all_opts; that->type != OPTION_END; that++) {
                if (that == opt ||
-                   that->type != OPTION_CMDMODE ||
+                   !(that->flags & PARSE_OPT_CMDMODE) ||
                    that->value != opt->value ||
                    that->defval != *(int *)opt->value)
                        continue;
@@ -95,6 +95,14 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
        if (!(flags & OPT_SHORT) && p->opt && (opt->flags & PARSE_OPT_NOARG))
                return error(_("%s takes no value"), optname(opt, flags));
 
+       /*
+        * Giving the same mode option twice, although unnecessary,
+        * is not a grave error, so let it pass.
+        */
+       if ((opt->flags & PARSE_OPT_CMDMODE) &&
+           *(int *)opt->value && *(int *)opt->value != opt->defval)
+               return opt_command_mode_error(opt, all_opts, flags);
+
        switch (opt->type) {
        case OPTION_LOWLEVEL_CALLBACK:
                return opt->ll_callback(p, opt, NULL, unset);
@@ -130,16 +138,6 @@ static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
                *(int *)opt->value = unset ? 0 : opt->defval;
                return 0;
 
-       case OPTION_CMDMODE:
-               /*
-                * Giving the same mode option twice, although is unnecessary,
-                * is not a grave error, so let it pass.
-                */
-               if (*(int *)opt->value && *(int *)opt->value != opt->defval)
-                       return opt_command_mode_error(opt, all_opts, flags);
-               *(int *)opt->value = opt->defval;
-               return 0;
-
        case OPTION_STRING:
                if (unset)
                        *(const char **)opt->value = NULL;
@@ -357,8 +355,7 @@ is_abbreviated:
                        }
                        /* negated? */
                        if (!starts_with(arg, "no-")) {
-                               if (starts_with(long_name, "no-")) {
-                                       long_name += 3;
+                               if (skip_prefix(long_name, "no-", &long_name)) {
                                        opt_flags |= OPT_UNSET;
                                        goto again;
                                }
@@ -528,7 +525,8 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
        parse_options_start_1(ctx, argc, argv, prefix, options, flags);
 }
 
-static void show_negated_gitcomp(const struct option *opts, int nr_noopts)
+static void show_negated_gitcomp(const struct option *opts, int show_all,
+                                int nr_noopts)
 {
        int printed_dashdash = 0;
 
@@ -538,7 +536,8 @@ static void show_negated_gitcomp(const struct option *opts, int nr_noopts)
 
                if (!opts->long_name)
                        continue;
-               if (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE))
+               if (!show_all &&
+                       (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE)))
                        continue;
                if (opts->flags & PARSE_OPT_NONEG)
                        continue;
@@ -575,7 +574,7 @@ static void show_negated_gitcomp(const struct option *opts, int nr_noopts)
        }
 }
 
-static int show_gitcomp(const struct option *opts)
+static int show_gitcomp(const struct option *opts, int show_all)
 {
        const struct option *original_opts = opts;
        int nr_noopts = 0;
@@ -585,7 +584,8 @@ static int show_gitcomp(const struct option *opts)
 
                if (!opts->long_name)
                        continue;
-               if (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE))
+               if (!show_all &&
+                       (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE)))
                        continue;
 
                switch (opts->type) {
@@ -613,8 +613,8 @@ static int show_gitcomp(const struct option *opts)
                        nr_noopts++;
                printf(" --%s%s", opts->long_name, suffix);
        }
-       show_negated_gitcomp(original_opts, -1);
-       show_negated_gitcomp(original_opts, nr_noopts);
+       show_negated_gitcomp(original_opts, show_all, -1);
+       show_negated_gitcomp(original_opts, show_all, nr_noopts);
        fputc('\n', stdout);
        return PARSE_OPT_COMPLETE;
 }
@@ -651,6 +651,7 @@ static struct option *preprocess_options(struct parse_opt_ctx_t *ctx,
                int short_name;
                const char *long_name;
                const char *source;
+               struct strbuf help = STRBUF_INIT;
                int j;
 
                if (newopt[i].type != OPTION_ALIAS)
@@ -662,6 +663,7 @@ static struct option *preprocess_options(struct parse_opt_ctx_t *ctx,
 
                if (!long_name)
                        BUG("An alias must have long option name");
+               strbuf_addf(&help, _("alias of --%s"), source);
 
                for (j = 0; j < nr; j++) {
                        const char *name = options[j].long_name;
@@ -672,15 +674,10 @@ static struct option *preprocess_options(struct parse_opt_ctx_t *ctx,
                        if (options[j].type == OPTION_ALIAS)
                                BUG("No please. Nested aliases are not supported.");
 
-                       /*
-                        * NEEDSWORK: this is a bit inconsistent because
-                        * usage_with_options() on the original options[] will print
-                        * help string as "alias of %s" but "git cmd -h" will
-                        * print the original help string.
-                        */
                        memcpy(newopt + i, options + j, sizeof(*newopt));
                        newopt[i].short_name = short_name;
                        newopt[i].long_name = long_name;
+                       newopt[i].help = strbuf_detach(&help, NULL);
                        break;
                }
 
@@ -729,9 +726,14 @@ 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(options);
+               /*
+                * lone --git-completion-helper and --git-completion-helper-all
+                * are asked by git-completion.bash
+                */
+               if (ctx->total == 1 && !strcmp(arg, "--git-completion-helper"))
+                       return show_gitcomp(options, 0);
+               if (ctx->total == 1 && !strcmp(arg, "--git-completion-helper-all"))
+                       return show_gitcomp(options, 1);
 
                if (arg[1] != '-') {
                        ctx->opt = arg + 1;