Skip to content

Commit

Permalink
parse-options: add subcommand that takes a repository argument
Browse files Browse the repository at this point in the history
The process of migrating away from using the global variable
the_repository may involve subcommands that also take a repository
argument. Allow this by adding a new function pointer type and enums.

Signed-off-by: John Cai <[email protected]>
  • Loading branch information
john-cai committed Sep 24, 2024
1 parent 6258f68 commit d9c07a4
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
14 changes: 10 additions & 4 deletions parse-options.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,13 +470,19 @@ static enum parse_opt_result parse_nodash_opt(struct parse_opt_ctx_t *p,
static enum parse_opt_result parse_subcommand(const char *arg,
const struct option *options)
{
for (; options->type != OPTION_END; options++)
for (; options->type != OPTION_END; options++) {
if (options->type == OPTION_SUBCOMMAND &&
!strcmp(options->long_name, arg)) {
*(parse_opt_subcommand_fn **)options->value = options->subcommand_fn;
return PARSE_OPT_SUBCOMMAND;
}

if (options->type == OPTION_REPO_SUBCOMMAND &&
!strcmp(options->long_name, arg)) {
*(parse_opt_subcommand_repo_fn **)options->value = options->subcommand_repo_fn;
return PARSE_OPT_SUBCOMMAND;
}
}
return PARSE_OPT_UNKNOWN;
}

Expand Down Expand Up @@ -575,7 +581,8 @@ static void parse_options_check(const struct option *opts)
static int has_subcommands(const struct option *options)
{
for (; options->type != OPTION_END; options++)
if (options->type == OPTION_SUBCOMMAND)
if (options->type == OPTION_SUBCOMMAND ||
options->type == OPTION_REPO_SUBCOMMAND)
return 1;
return 0;
}
Expand All @@ -598,8 +605,7 @@ static void parse_options_start_1(struct parse_opt_ctx_t *ctx,
ctx->flags = flags;
ctx->has_subcommands = has_subcommands(options);
if (!ctx->has_subcommands && (flags & PARSE_OPT_SUBCOMMAND_OPTIONAL))

Check failure on line 607 in parse-options.c

View workflow job for this annotation

GitHub Actions / linux-musl (alpine)

parse-options.c:607:9: this 'if' clause does not guard... [-Werror=misleading-indentation]

Check failure on line 607 in parse-options.c

View workflow job for this annotation

GitHub Actions / pedantic (fedora)

parse-options.c:607:9: this 'if' clause does not guard... [-Werror=misleading-indentation]

Check failure on line 607 in parse-options.c

View workflow job for this annotation

GitHub Actions / linux-gcc-default (ubuntu-latest)

parse-options.c:607:9: this ‘if’ clause does not guard... [-Werror=misleading-indentation]

Check failure on line 607 in parse-options.c

View workflow job for this annotation

GitHub Actions / linux-leaks (ubuntu-latest)

parse-options.c:607:9: this ‘if’ clause does not guard... [-Werror=misleading-indentation]

Check failure on line 607 in parse-options.c

View workflow job for this annotation

GitHub Actions / linux-reftable-leaks (ubuntu-latest)

parse-options.c:607:9: this ‘if’ clause does not guard... [-Werror=misleading-indentation]

Check failure on line 607 in parse-options.c

View workflow job for this annotation

GitHub Actions / win build

parse-options.c:607:9: this 'if' clause does not guard... [-Werror=misleading-indentation]
BUG("Using PARSE_OPT_SUBCOMMAND_OPTIONAL without subcommands");
if (ctx->has_subcommands) {
BUG("Using PARSE_OPT_SUBCOMMAND_OPTIONAL without subcommands"); if (ctx->has_subcommands) {
if (flags & PARSE_OPT_STOP_AT_NON_OPTION)
BUG("subcommands are incompatible with PARSE_OPT_STOP_AT_NON_OPTION");
if (!(flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)) {
Expand Down
18 changes: 18 additions & 0 deletions parse-options.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define PARSE_OPTIONS_H

#include "gettext.h"
#include "repository.h"

/**
* Refer to Documentation/technical/api-parse-options.txt for the API doc.
Expand All @@ -14,6 +15,7 @@ enum parse_opt_type {
OPTION_NUMBER,
OPTION_ALIAS,
OPTION_SUBCOMMAND,
OPTION_REPO_SUBCOMMAND,
/* options with no arguments */
OPTION_BIT,
OPTION_NEGBIT,
Expand Down Expand Up @@ -75,6 +77,11 @@ typedef enum parse_opt_result parse_opt_ll_cb(struct parse_opt_ctx_t *ctx,
typedef int parse_opt_subcommand_fn(int argc, const char **argv,
const char *prefix);

typedef int parse_opt_subcommand_repo_fn(struct repository *repo,
int argc, const char **argv,
const char *prefix);


/*
* `type`::
* holds the type of the option, you must have an OPTION_END last in your
Expand Down Expand Up @@ -158,6 +165,7 @@ struct option {
parse_opt_ll_cb *ll_callback;
intptr_t extra;
parse_opt_subcommand_fn *subcommand_fn;
parse_opt_subcommand_repo_fn *subcommand_repo_fn;
};

#define OPT_BIT_F(s, l, v, h, b, f) { \
Expand Down Expand Up @@ -367,6 +375,16 @@ struct option {
}
#define OPT_SUBCOMMAND(l, v, fn) OPT_SUBCOMMAND_F((l), (v), (fn), 0)

#define OPT_SUBCOMMAND_REPO_F(l, v, repo_fn) { \
.type = OPTION_REPO_SUBCOMMAND, \
.long_name = (l), \
.value = (v), \
.flags = 0, \
.subcommand_repo_fn = (repo_fn), \
}
#define OPT_REPO_SUBCOMMAND(l, v, repo_fn) OPT_SUBCOMMAND_REPO_F((l), (v), (repo_fn))


/*
* parse_options() will filter out the processed options and leave the
* non-option arguments in argv[]. argv0 is assumed program name and
Expand Down

0 comments on commit d9c07a4

Please sign in to comment.