parse-options.con commit Merge branch 'sg/asciidoctor-in-ci' (bac754e)
   1#include "git-compat-util.h"
   2#include "parse-options.h"
   3#include "cache.h"
   4#include "config.h"
   5#include "commit.h"
   6#include "color.h"
   7#include "utf8.h"
   8
   9#define OPT_SHORT 1
  10#define OPT_UNSET 2
  11
  12int optbug(const struct option *opt, const char *reason)
  13{
  14        if (opt->long_name) {
  15                if (opt->short_name)
  16                        return error("BUG: switch '%c' (--%s) %s",
  17                                     opt->short_name, opt->long_name, reason);
  18                return error("BUG: option '%s' %s", opt->long_name, reason);
  19        }
  20        return error("BUG: switch '%c' %s", opt->short_name, reason);
  21}
  22
  23static enum parse_opt_result get_arg(struct parse_opt_ctx_t *p,
  24                                     const struct option *opt,
  25                                     int flags, const char **arg)
  26{
  27        if (p->opt) {
  28                *arg = p->opt;
  29                p->opt = NULL;
  30        } else if (p->argc == 1 && (opt->flags & PARSE_OPT_LASTARG_DEFAULT)) {
  31                *arg = (const char *)opt->defval;
  32        } else if (p->argc > 1) {
  33                p->argc--;
  34                *arg = *++p->argv;
  35        } else
  36                return error(_("%s requires a value"), optname(opt, flags));
  37        return 0;
  38}
  39
  40static void fix_filename(const char *prefix, const char **file)
  41{
  42        if (!file || !*file || !prefix || is_absolute_path(*file)
  43            || !strcmp("-", *file))
  44                return;
  45        *file = prefix_filename(prefix, *file);
  46}
  47
  48static enum parse_opt_result opt_command_mode_error(
  49        const struct option *opt,
  50        const struct option *all_opts,
  51        int flags)
  52{
  53        const struct option *that;
  54        struct strbuf that_name = STRBUF_INIT;
  55
  56        /*
  57         * Find the other option that was used to set the variable
  58         * already, and report that this is not compatible with it.
  59         */
  60        for (that = all_opts; that->type != OPTION_END; that++) {
  61                if (that == opt ||
  62                    that->type != OPTION_CMDMODE ||
  63                    that->value != opt->value ||
  64                    that->defval != *(int *)opt->value)
  65                        continue;
  66
  67                if (that->long_name)
  68                        strbuf_addf(&that_name, "--%s", that->long_name);
  69                else
  70                        strbuf_addf(&that_name, "-%c", that->short_name);
  71                error(_("%s is incompatible with %s"),
  72                      optname(opt, flags), that_name.buf);
  73                strbuf_release(&that_name);
  74                return PARSE_OPT_ERROR;
  75        }
  76        return error(_("%s : incompatible with something else"),
  77                     optname(opt, flags));
  78}
  79
  80static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
  81                                       const struct option *opt,
  82                                       const struct option *all_opts,
  83                                       int flags)
  84{
  85        const char *s, *arg;
  86        const int unset = flags & OPT_UNSET;
  87        int err;
  88
  89        if (unset && p->opt)
  90                return error(_("%s takes no value"), optname(opt, flags));
  91        if (unset && (opt->flags & PARSE_OPT_NONEG))
  92                return error(_("%s isn't available"), optname(opt, flags));
  93        if (!(flags & OPT_SHORT) && p->opt && (opt->flags & PARSE_OPT_NOARG))
  94                return error(_("%s takes no value"), optname(opt, flags));
  95
  96        switch (opt->type) {
  97        case OPTION_LOWLEVEL_CALLBACK:
  98                return opt->ll_callback(p, opt, NULL, unset);
  99
 100        case OPTION_BIT:
 101                if (unset)
 102                        *(int *)opt->value &= ~opt->defval;
 103                else
 104                        *(int *)opt->value |= opt->defval;
 105                return 0;
 106
 107        case OPTION_NEGBIT:
 108                if (unset)
 109                        *(int *)opt->value |= opt->defval;
 110                else
 111                        *(int *)opt->value &= ~opt->defval;
 112                return 0;
 113
 114        case OPTION_BITOP:
 115                if (unset)
 116                        BUG("BITOP can't have unset form");
 117                *(int *)opt->value &= ~opt->extra;
 118                *(int *)opt->value |= opt->defval;
 119                return 0;
 120
 121        case OPTION_COUNTUP:
 122                if (*(int *)opt->value < 0)
 123                        *(int *)opt->value = 0;
 124                *(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
 125                return 0;
 126
 127        case OPTION_SET_INT:
 128                *(int *)opt->value = unset ? 0 : opt->defval;
 129                return 0;
 130
 131        case OPTION_CMDMODE:
 132                /*
 133                 * Giving the same mode option twice, although is unnecessary,
 134                 * is not a grave error, so let it pass.
 135                 */
 136                if (*(int *)opt->value && *(int *)opt->value != opt->defval)
 137                        return opt_command_mode_error(opt, all_opts, flags);
 138                *(int *)opt->value = opt->defval;
 139                return 0;
 140
 141        case OPTION_STRING:
 142                if (unset)
 143                        *(const char **)opt->value = NULL;
 144                else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
 145                        *(const char **)opt->value = (const char *)opt->defval;
 146                else
 147                        return get_arg(p, opt, flags, (const char **)opt->value);
 148                return 0;
 149
 150        case OPTION_FILENAME:
 151                err = 0;
 152                if (unset)
 153                        *(const char **)opt->value = NULL;
 154                else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
 155                        *(const char **)opt->value = (const char *)opt->defval;
 156                else
 157                        err = get_arg(p, opt, flags, (const char **)opt->value);
 158
 159                if (!err)
 160                        fix_filename(p->prefix, (const char **)opt->value);
 161                return err;
 162
 163        case OPTION_CALLBACK:
 164        {
 165                const char *p_arg = NULL;
 166                int p_unset;
 167
 168                if (unset)
 169                        p_unset = 1;
 170                else if (opt->flags & PARSE_OPT_NOARG)
 171                        p_unset = 0;
 172                else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
 173                        p_unset = 0;
 174                else if (get_arg(p, opt, flags, &arg))
 175                        return -1;
 176                else {
 177                        p_unset = 0;
 178                        p_arg = arg;
 179                }
 180                if (opt->callback)
 181                        return (*opt->callback)(opt, p_arg, p_unset) ? (-1) : 0;
 182                else
 183                        return (*opt->ll_callback)(p, opt, p_arg, p_unset);
 184        }
 185        case OPTION_INTEGER:
 186                if (unset) {
 187                        *(int *)opt->value = 0;
 188                        return 0;
 189                }
 190                if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
 191                        *(int *)opt->value = opt->defval;
 192                        return 0;
 193                }
 194                if (get_arg(p, opt, flags, &arg))
 195                        return -1;
 196                *(int *)opt->value = strtol(arg, (char **)&s, 10);
 197                if (*s)
 198                        return error(_("%s expects a numerical value"),
 199                                     optname(opt, flags));
 200                return 0;
 201
 202        case OPTION_MAGNITUDE:
 203                if (unset) {
 204                        *(unsigned long *)opt->value = 0;
 205                        return 0;
 206                }
 207                if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
 208                        *(unsigned long *)opt->value = opt->defval;
 209                        return 0;
 210                }
 211                if (get_arg(p, opt, flags, &arg))
 212                        return -1;
 213                if (!git_parse_ulong(arg, opt->value))
 214                        return error(_("%s expects a non-negative integer value"
 215                                       " with an optional k/m/g suffix"),
 216                                     optname(opt, flags));
 217                return 0;
 218
 219        default:
 220                BUG("opt->type %d should not happen", opt->type);
 221        }
 222}
 223
 224static enum parse_opt_result parse_short_opt(struct parse_opt_ctx_t *p,
 225                                             const struct option *options)
 226{
 227        const struct option *all_opts = options;
 228        const struct option *numopt = NULL;
 229
 230        for (; options->type != OPTION_END; options++) {
 231                if (options->short_name == *p->opt) {
 232                        p->opt = p->opt[1] ? p->opt + 1 : NULL;
 233                        return get_value(p, options, all_opts, OPT_SHORT);
 234                }
 235
 236                /*
 237                 * Handle the numerical option later, explicit one-digit
 238                 * options take precedence over it.
 239                 */
 240                if (options->type == OPTION_NUMBER)
 241                        numopt = options;
 242        }
 243        if (numopt && isdigit(*p->opt)) {
 244                size_t len = 1;
 245                char *arg;
 246                int rc;
 247
 248                while (isdigit(p->opt[len]))
 249                        len++;
 250                arg = xmemdupz(p->opt, len);
 251                p->opt = p->opt[len] ? p->opt + len : NULL;
 252                if (numopt->callback)
 253                        rc = (*numopt->callback)(numopt, arg, 0) ? (-1) : 0;
 254                else
 255                        rc = (*numopt->ll_callback)(p, numopt, arg, 0);
 256                free(arg);
 257                return rc;
 258        }
 259        return PARSE_OPT_UNKNOWN;
 260}
 261
 262static enum parse_opt_result parse_long_opt(
 263        struct parse_opt_ctx_t *p, const char *arg,
 264        const struct option *options)
 265{
 266        const struct option *all_opts = options;
 267        const char *arg_end = strchrnul(arg, '=');
 268        const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
 269        int abbrev_flags = 0, ambiguous_flags = 0;
 270
 271        for (; options->type != OPTION_END; options++) {
 272                const char *rest, *long_name = options->long_name;
 273                int flags = 0, opt_flags = 0;
 274
 275                if (!long_name)
 276                        continue;
 277
 278again:
 279                if (!skip_prefix(arg, long_name, &rest))
 280                        rest = NULL;
 281                if (options->type == OPTION_ARGUMENT) {
 282                        if (!rest)
 283                                continue;
 284                        if (*rest == '=')
 285                                return error(_("%s takes no value"),
 286                                             optname(options, flags));
 287                        if (*rest)
 288                                continue;
 289                        p->out[p->cpidx++] = arg - 2;
 290                        return PARSE_OPT_DONE;
 291                }
 292                if (!rest) {
 293                        /* abbreviated? */
 294                        if (!(p->flags & PARSE_OPT_KEEP_UNKNOWN) &&
 295                            !strncmp(long_name, arg, arg_end - arg)) {
 296is_abbreviated:
 297                                if (abbrev_option) {
 298                                        /*
 299                                         * If this is abbreviated, it is
 300                                         * ambiguous. So when there is no
 301                                         * exact match later, we need to
 302                                         * error out.
 303                                         */
 304                                        ambiguous_option = abbrev_option;
 305                                        ambiguous_flags = abbrev_flags;
 306                                }
 307                                if (!(flags & OPT_UNSET) && *arg_end)
 308                                        p->opt = arg_end + 1;
 309                                abbrev_option = options;
 310                                abbrev_flags = flags ^ opt_flags;
 311                                continue;
 312                        }
 313                        /* negation allowed? */
 314                        if (options->flags & PARSE_OPT_NONEG)
 315                                continue;
 316                        /* negated and abbreviated very much? */
 317                        if (starts_with("no-", arg)) {
 318                                flags |= OPT_UNSET;
 319                                goto is_abbreviated;
 320                        }
 321                        /* negated? */
 322                        if (!starts_with(arg, "no-")) {
 323                                if (starts_with(long_name, "no-")) {
 324                                        long_name += 3;
 325                                        opt_flags |= OPT_UNSET;
 326                                        goto again;
 327                                }
 328                                continue;
 329                        }
 330                        flags |= OPT_UNSET;
 331                        if (!skip_prefix(arg + 3, long_name, &rest)) {
 332                                /* abbreviated and negated? */
 333                                if (starts_with(long_name, arg + 3))
 334                                        goto is_abbreviated;
 335                                else
 336                                        continue;
 337                        }
 338                }
 339                if (*rest) {
 340                        if (*rest != '=')
 341                                continue;
 342                        p->opt = rest + 1;
 343                }
 344                return get_value(p, options, all_opts, flags ^ opt_flags);
 345        }
 346
 347        if (ambiguous_option) {
 348                error(_("ambiguous option: %s "
 349                        "(could be --%s%s or --%s%s)"),
 350                        arg,
 351                        (ambiguous_flags & OPT_UNSET) ?  "no-" : "",
 352                        ambiguous_option->long_name,
 353                        (abbrev_flags & OPT_UNSET) ?  "no-" : "",
 354                        abbrev_option->long_name);
 355                return PARSE_OPT_HELP;
 356        }
 357        if (abbrev_option)
 358                return get_value(p, abbrev_option, all_opts, abbrev_flags);
 359        return PARSE_OPT_UNKNOWN;
 360}
 361
 362static int parse_nodash_opt(struct parse_opt_ctx_t *p, const char *arg,
 363                            const struct option *options)
 364{
 365        const struct option *all_opts = options;
 366
 367        for (; options->type != OPTION_END; options++) {
 368                if (!(options->flags & PARSE_OPT_NODASH))
 369                        continue;
 370                if (options->short_name == arg[0] && arg[1] == '\0')
 371                        return get_value(p, options, all_opts, OPT_SHORT);
 372        }
 373        return -2;
 374}
 375
 376static void check_typos(const char *arg, const struct option *options)
 377{
 378        if (strlen(arg) < 3)
 379                return;
 380
 381        if (starts_with(arg, "no-")) {
 382                error(_("did you mean `--%s` (with two dashes ?)"), arg);
 383                exit(129);
 384        }
 385
 386        for (; options->type != OPTION_END; options++) {
 387                if (!options->long_name)
 388                        continue;
 389                if (starts_with(options->long_name, arg)) {
 390                        error(_("did you mean `--%s` (with two dashes ?)"), arg);
 391                        exit(129);
 392                }
 393        }
 394}
 395
 396static void parse_options_check(const struct option *opts)
 397{
 398        int err = 0;
 399        char short_opts[128];
 400
 401        memset(short_opts, '\0', sizeof(short_opts));
 402        for (; opts->type != OPTION_END; opts++) {
 403                if ((opts->flags & PARSE_OPT_LASTARG_DEFAULT) &&
 404                    (opts->flags & PARSE_OPT_OPTARG))
 405                        err |= optbug(opts, "uses incompatible flags "
 406                                        "LASTARG_DEFAULT and OPTARG");
 407                if (opts->short_name) {
 408                        if (0x7F <= opts->short_name)
 409                                err |= optbug(opts, "invalid short name");
 410                        else if (short_opts[opts->short_name]++)
 411                                err |= optbug(opts, "short name already used");
 412                }
 413                if (opts->flags & PARSE_OPT_NODASH &&
 414                    ((opts->flags & PARSE_OPT_OPTARG) ||
 415                     !(opts->flags & PARSE_OPT_NOARG) ||
 416                     !(opts->flags & PARSE_OPT_NONEG) ||
 417                     opts->long_name))
 418                        err |= optbug(opts, "uses feature "
 419                                        "not supported for dashless options");
 420                switch (opts->type) {
 421                case OPTION_COUNTUP:
 422                case OPTION_BIT:
 423                case OPTION_NEGBIT:
 424                case OPTION_SET_INT:
 425                case OPTION_NUMBER:
 426                        if ((opts->flags & PARSE_OPT_OPTARG) ||
 427                            !(opts->flags & PARSE_OPT_NOARG))
 428                                err |= optbug(opts, "should not accept an argument");
 429                        break;
 430                case OPTION_CALLBACK:
 431                        if (!opts->callback && !opts->ll_callback)
 432                                BUG("OPTION_CALLBACK needs one callback");
 433                        if (opts->callback && opts->ll_callback)
 434                                BUG("OPTION_CALLBACK can't have two callbacks");
 435                        break;
 436                case OPTION_LOWLEVEL_CALLBACK:
 437                        if (!opts->ll_callback)
 438                                BUG("OPTION_LOWLEVEL_CALLBACK needs a callback");
 439                        if (opts->callback)
 440                                BUG("OPTION_LOWLEVEL_CALLBACK needs no high level callback");
 441                        break;
 442                default:
 443                        ; /* ok. (usually accepts an argument) */
 444                }
 445                if (opts->argh &&
 446                    strcspn(opts->argh, " _") != strlen(opts->argh))
 447                        err |= optbug(opts, "multi-word argh should use dash to separate words");
 448        }
 449        if (err)
 450                exit(128);
 451}
 452
 453void parse_options_start(struct parse_opt_ctx_t *ctx,
 454                         int argc, const char **argv, const char *prefix,
 455                         const struct option *options, int flags)
 456{
 457        memset(ctx, 0, sizeof(*ctx));
 458        ctx->argc = argc;
 459        ctx->argv = argv;
 460        if (!(flags & PARSE_OPT_ONE_SHOT)) {
 461                ctx->argc--;
 462                ctx->argv++;
 463        }
 464        ctx->total = ctx->argc;
 465        ctx->out   = argv;
 466        ctx->prefix = prefix;
 467        ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
 468        ctx->flags = flags;
 469        if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
 470            (flags & PARSE_OPT_STOP_AT_NON_OPTION) &&
 471            !(flags & PARSE_OPT_ONE_SHOT))
 472                BUG("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
 473        if ((flags & PARSE_OPT_ONE_SHOT) &&
 474            (flags & PARSE_OPT_KEEP_ARGV0))
 475                BUG("Can't keep argv0 if you don't have it");
 476        parse_options_check(options);
 477}
 478
 479static void show_negated_gitcomp(const struct option *opts, int nr_noopts)
 480{
 481        int printed_dashdash = 0;
 482
 483        for (; opts->type != OPTION_END; opts++) {
 484                int has_unset_form = 0;
 485                const char *name;
 486
 487                if (!opts->long_name)
 488                        continue;
 489                if (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE))
 490                        continue;
 491                if (opts->flags & PARSE_OPT_NONEG)
 492                        continue;
 493
 494                switch (opts->type) {
 495                case OPTION_STRING:
 496                case OPTION_FILENAME:
 497                case OPTION_INTEGER:
 498                case OPTION_MAGNITUDE:
 499                case OPTION_CALLBACK:
 500                case OPTION_BIT:
 501                case OPTION_NEGBIT:
 502                case OPTION_COUNTUP:
 503                case OPTION_SET_INT:
 504                        has_unset_form = 1;
 505                        break;
 506                default:
 507                        break;
 508                }
 509                if (!has_unset_form)
 510                        continue;
 511
 512                if (skip_prefix(opts->long_name, "no-", &name)) {
 513                        if (nr_noopts < 0)
 514                                printf(" --%s", name);
 515                } else if (nr_noopts >= 0) {
 516                        if (nr_noopts && !printed_dashdash) {
 517                                printf(" --");
 518                                printed_dashdash = 1;
 519                        }
 520                        printf(" --no-%s", opts->long_name);
 521                        nr_noopts++;
 522                }
 523        }
 524}
 525
 526static int show_gitcomp(struct parse_opt_ctx_t *ctx,
 527                        const struct option *opts)
 528{
 529        const struct option *original_opts = opts;
 530        int nr_noopts = 0;
 531
 532        for (; opts->type != OPTION_END; opts++) {
 533                const char *suffix = "";
 534
 535                if (!opts->long_name)
 536                        continue;
 537                if (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE))
 538                        continue;
 539
 540                switch (opts->type) {
 541                case OPTION_GROUP:
 542                        continue;
 543                case OPTION_STRING:
 544                case OPTION_FILENAME:
 545                case OPTION_INTEGER:
 546                case OPTION_MAGNITUDE:
 547                case OPTION_CALLBACK:
 548                        if (opts->flags & PARSE_OPT_NOARG)
 549                                break;
 550                        if (opts->flags & PARSE_OPT_OPTARG)
 551                                break;
 552                        if (opts->flags & PARSE_OPT_LASTARG_DEFAULT)
 553                                break;
 554                        suffix = "=";
 555                        break;
 556                default:
 557                        break;
 558                }
 559                if (opts->flags & PARSE_OPT_COMP_ARG)
 560                        suffix = "=";
 561                if (starts_with(opts->long_name, "no-"))
 562                        nr_noopts++;
 563                printf(" --%s%s", opts->long_name, suffix);
 564        }
 565        show_negated_gitcomp(original_opts, -1);
 566        show_negated_gitcomp(original_opts, nr_noopts);
 567        fputc('\n', stdout);
 568        return PARSE_OPT_COMPLETE;
 569}
 570
 571static int usage_with_options_internal(struct parse_opt_ctx_t *,
 572                                       const char * const *,
 573                                       const struct option *, int, int);
 574
 575int parse_options_step(struct parse_opt_ctx_t *ctx,
 576                       const struct option *options,
 577                       const char * const usagestr[])
 578{
 579        int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
 580
 581        /* we must reset ->opt, unknown short option leave it dangling */
 582        ctx->opt = NULL;
 583
 584        for (; ctx->argc; ctx->argc--, ctx->argv++) {
 585                const char *arg = ctx->argv[0];
 586
 587                if (ctx->flags & PARSE_OPT_ONE_SHOT &&
 588                    ctx->argc != ctx->total)
 589                        break;
 590
 591                if (*arg != '-' || !arg[1]) {
 592                        if (parse_nodash_opt(ctx, arg, options) == 0)
 593                                continue;
 594                        if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
 595                                return PARSE_OPT_NON_OPTION;
 596                        ctx->out[ctx->cpidx++] = ctx->argv[0];
 597                        continue;
 598                }
 599
 600                /* lone -h asks for help */
 601                if (internal_help && ctx->total == 1 && !strcmp(arg + 1, "h"))
 602                        goto show_usage;
 603
 604                /* lone --git-completion-helper is asked by git-completion.bash */
 605                if (ctx->total == 1 && !strcmp(arg + 1, "-git-completion-helper"))
 606                        return show_gitcomp(ctx, options);
 607
 608                if (arg[1] != '-') {
 609                        ctx->opt = arg + 1;
 610                        switch (parse_short_opt(ctx, options)) {
 611                        case PARSE_OPT_ERROR:
 612                                return PARSE_OPT_ERROR;
 613                        case PARSE_OPT_UNKNOWN:
 614                                if (ctx->opt)
 615                                        check_typos(arg + 1, options);
 616                                if (internal_help && *ctx->opt == 'h')
 617                                        goto show_usage;
 618                                goto unknown;
 619                        case PARSE_OPT_NON_OPTION:
 620                        case PARSE_OPT_HELP:
 621                        case PARSE_OPT_COMPLETE:
 622                                BUG("parse_short_opt() cannot return these");
 623                        case PARSE_OPT_DONE:
 624                                break;
 625                        }
 626                        if (ctx->opt)
 627                                check_typos(arg + 1, options);
 628                        while (ctx->opt) {
 629                                switch (parse_short_opt(ctx, options)) {
 630                                case PARSE_OPT_ERROR:
 631                                        return PARSE_OPT_ERROR;
 632                                case PARSE_OPT_UNKNOWN:
 633                                        if (internal_help && *ctx->opt == 'h')
 634                                                goto show_usage;
 635
 636                                        /* fake a short option thing to hide the fact that we may have
 637                                         * started to parse aggregated stuff
 638                                         *
 639                                         * This is leaky, too bad.
 640                                         */
 641                                        ctx->argv[0] = xstrdup(ctx->opt - 1);
 642                                        *(char *)ctx->argv[0] = '-';
 643                                        goto unknown;
 644                                case PARSE_OPT_NON_OPTION:
 645                                case PARSE_OPT_COMPLETE:
 646                                case PARSE_OPT_HELP:
 647                                        BUG("parse_short_opt() cannot return these");
 648                                case PARSE_OPT_DONE:
 649                                        break;
 650                                }
 651                        }
 652                        continue;
 653                }
 654
 655                if (!arg[2]) { /* "--" */
 656                        if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
 657                                ctx->argc--;
 658                                ctx->argv++;
 659                        }
 660                        break;
 661                }
 662
 663                if (internal_help && !strcmp(arg + 2, "help-all"))
 664                        return usage_with_options_internal(ctx, usagestr, options, 1, 0);
 665                if (internal_help && !strcmp(arg + 2, "help"))
 666                        goto show_usage;
 667                switch (parse_long_opt(ctx, arg + 2, options)) {
 668                case PARSE_OPT_ERROR:
 669                        return PARSE_OPT_ERROR;
 670                case PARSE_OPT_UNKNOWN:
 671                        goto unknown;
 672                case PARSE_OPT_HELP:
 673                        goto show_usage;
 674                case PARSE_OPT_NON_OPTION:
 675                case PARSE_OPT_COMPLETE:
 676                        BUG("parse_long_opt() cannot return these");
 677                case PARSE_OPT_DONE:
 678                        break;
 679                }
 680                continue;
 681unknown:
 682                if (ctx->flags & PARSE_OPT_ONE_SHOT)
 683                        break;
 684                if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
 685                        return PARSE_OPT_UNKNOWN;
 686                ctx->out[ctx->cpidx++] = ctx->argv[0];
 687                ctx->opt = NULL;
 688        }
 689        return PARSE_OPT_DONE;
 690
 691 show_usage:
 692        return usage_with_options_internal(ctx, usagestr, options, 0, 0);
 693}
 694
 695int parse_options_end(struct parse_opt_ctx_t *ctx)
 696{
 697        if (ctx->flags & PARSE_OPT_ONE_SHOT)
 698                return ctx->total - ctx->argc;
 699
 700        MOVE_ARRAY(ctx->out + ctx->cpidx, ctx->argv, ctx->argc);
 701        ctx->out[ctx->cpidx + ctx->argc] = NULL;
 702        return ctx->cpidx + ctx->argc;
 703}
 704
 705int parse_options(int argc, const char **argv, const char *prefix,
 706                  const struct option *options, const char * const usagestr[],
 707                  int flags)
 708{
 709        struct parse_opt_ctx_t ctx;
 710
 711        parse_options_start(&ctx, argc, argv, prefix, options, flags);
 712        switch (parse_options_step(&ctx, options, usagestr)) {
 713        case PARSE_OPT_HELP:
 714        case PARSE_OPT_ERROR:
 715                exit(129);
 716        case PARSE_OPT_COMPLETE:
 717                exit(0);
 718        case PARSE_OPT_NON_OPTION:
 719        case PARSE_OPT_DONE:
 720                break;
 721        default: /* PARSE_OPT_UNKNOWN */
 722                if (ctx.argv[0][1] == '-') {
 723                        error(_("unknown option `%s'"), ctx.argv[0] + 2);
 724                } else if (isascii(*ctx.opt)) {
 725                        error(_("unknown switch `%c'"), *ctx.opt);
 726                } else {
 727                        error(_("unknown non-ascii option in string: `%s'"),
 728                              ctx.argv[0]);
 729                }
 730                usage_with_options(usagestr, options);
 731        }
 732
 733        precompose_argv(argc, argv);
 734        return parse_options_end(&ctx);
 735}
 736
 737static int usage_argh(const struct option *opts, FILE *outfile)
 738{
 739        const char *s;
 740        int literal = (opts->flags & PARSE_OPT_LITERAL_ARGHELP) ||
 741                !opts->argh || !!strpbrk(opts->argh, "()<>[]|");
 742        if (opts->flags & PARSE_OPT_OPTARG)
 743                if (opts->long_name)
 744                        s = literal ? "[=%s]" : "[=<%s>]";
 745                else
 746                        s = literal ? "[%s]" : "[<%s>]";
 747        else
 748                s = literal ? " %s" : " <%s>";
 749        return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
 750}
 751
 752#define USAGE_OPTS_WIDTH 24
 753#define USAGE_GAP         2
 754
 755static int usage_with_options_internal(struct parse_opt_ctx_t *ctx,
 756                                       const char * const *usagestr,
 757                                       const struct option *opts, int full, int err)
 758{
 759        FILE *outfile = err ? stderr : stdout;
 760        int need_newline;
 761
 762        if (!usagestr)
 763                return PARSE_OPT_HELP;
 764
 765        if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
 766                fprintf(outfile, "cat <<\\EOF\n");
 767
 768        fprintf_ln(outfile, _("usage: %s"), _(*usagestr++));
 769        while (*usagestr && **usagestr)
 770                /*
 771                 * TRANSLATORS: the colon here should align with the
 772                 * one in "usage: %s" translation.
 773                 */
 774                fprintf_ln(outfile, _("   or: %s"), _(*usagestr++));
 775        while (*usagestr) {
 776                if (**usagestr)
 777                        fprintf_ln(outfile, _("    %s"), _(*usagestr));
 778                else
 779                        fputc('\n', outfile);
 780                usagestr++;
 781        }
 782
 783        need_newline = 1;
 784
 785        for (; opts->type != OPTION_END; opts++) {
 786                size_t pos;
 787                int pad;
 788
 789                if (opts->type == OPTION_GROUP) {
 790                        fputc('\n', outfile);
 791                        need_newline = 0;
 792                        if (*opts->help)
 793                                fprintf(outfile, "%s\n", _(opts->help));
 794                        continue;
 795                }
 796                if (!full && (opts->flags & PARSE_OPT_HIDDEN))
 797                        continue;
 798
 799                if (need_newline) {
 800                        fputc('\n', outfile);
 801                        need_newline = 0;
 802                }
 803
 804                pos = fprintf(outfile, "    ");
 805                if (opts->short_name) {
 806                        if (opts->flags & PARSE_OPT_NODASH)
 807                                pos += fprintf(outfile, "%c", opts->short_name);
 808                        else
 809                                pos += fprintf(outfile, "-%c", opts->short_name);
 810                }
 811                if (opts->long_name && opts->short_name)
 812                        pos += fprintf(outfile, ", ");
 813                if (opts->long_name)
 814                        pos += fprintf(outfile, "--%s", opts->long_name);
 815                if (opts->type == OPTION_NUMBER)
 816                        pos += utf8_fprintf(outfile, _("-NUM"));
 817
 818                if ((opts->flags & PARSE_OPT_LITERAL_ARGHELP) ||
 819                    !(opts->flags & PARSE_OPT_NOARG))
 820                        pos += usage_argh(opts, outfile);
 821
 822                if (pos <= USAGE_OPTS_WIDTH)
 823                        pad = USAGE_OPTS_WIDTH - pos;
 824                else {
 825                        fputc('\n', outfile);
 826                        pad = USAGE_OPTS_WIDTH;
 827                }
 828                fprintf(outfile, "%*s%s\n", pad + USAGE_GAP, "", _(opts->help));
 829        }
 830        fputc('\n', outfile);
 831
 832        if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
 833                fputs("EOF\n", outfile);
 834
 835        return PARSE_OPT_HELP;
 836}
 837
 838void NORETURN usage_with_options(const char * const *usagestr,
 839                        const struct option *opts)
 840{
 841        usage_with_options_internal(NULL, usagestr, opts, 0, 1);
 842        exit(129);
 843}
 844
 845void NORETURN usage_msg_opt(const char *msg,
 846                   const char * const *usagestr,
 847                   const struct option *options)
 848{
 849        fprintf(stderr, "fatal: %s\n\n", msg);
 850        usage_with_options(usagestr, options);
 851}
 852
 853const char *optname(const struct option *opt, int flags)
 854{
 855        static struct strbuf sb = STRBUF_INIT;
 856
 857        strbuf_reset(&sb);
 858        if (flags & OPT_SHORT)
 859                strbuf_addf(&sb, "switch `%c'", opt->short_name);
 860        else if (flags & OPT_UNSET)
 861                strbuf_addf(&sb, "option `no-%s'", opt->long_name);
 862        else
 863                strbuf_addf(&sb, "option `%s'", opt->long_name);
 864
 865        return sb.buf;
 866}