зеркало из https://github.com/microsoft/git.git
parse-options: add one-shot mode
This is to help reimplement diff_opt_parse() using parse_options(). The behavior of parse_options() is changed to be the same as the other: - no argv0 in argv[], everything can be processed - argv[] must not be updated, it's the caller's job to do that - return the number of arguments processed - leave all unknown options / non-options alone (this one can already be achieved with PARSE_OPT_KEEP_UNKNOWN and PARSE_OPT_STOP_AT_NON_OPTION) This mode is NOT supposed to stay here for long. It's to help converting diff/rev option parsing. Once that work is over and we can just use parse_options() throughout the code base, this will be deleted. Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
1987b0b20f
Коммит
202fbb3315
|
@ -416,15 +416,24 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
|
|||
const struct option *options, int flags)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
ctx->argc = ctx->total = argc - 1;
|
||||
ctx->argv = argv + 1;
|
||||
ctx->out = argv;
|
||||
ctx->argc = argc;
|
||||
ctx->argv = argv;
|
||||
if (!(flags & PARSE_OPT_ONE_SHOT)) {
|
||||
ctx->argc--;
|
||||
ctx->argv++;
|
||||
}
|
||||
ctx->total = ctx->argc;
|
||||
ctx->out = argv;
|
||||
ctx->prefix = prefix;
|
||||
ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
|
||||
ctx->flags = flags;
|
||||
if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
|
||||
(flags & PARSE_OPT_STOP_AT_NON_OPTION))
|
||||
(flags & PARSE_OPT_STOP_AT_NON_OPTION) &&
|
||||
!(flags & PARSE_OPT_ONE_SHOT))
|
||||
BUG("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
|
||||
if ((flags & PARSE_OPT_ONE_SHOT) &&
|
||||
(flags & PARSE_OPT_KEEP_ARGV0))
|
||||
BUG("Can't keep argv0 if you don't have it");
|
||||
parse_options_check(options);
|
||||
}
|
||||
|
||||
|
@ -536,6 +545,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
|
|||
for (; ctx->argc; ctx->argc--, ctx->argv++) {
|
||||
const char *arg = ctx->argv[0];
|
||||
|
||||
if (ctx->flags & PARSE_OPT_ONE_SHOT &&
|
||||
ctx->argc != ctx->total)
|
||||
break;
|
||||
|
||||
if (*arg != '-' || !arg[1]) {
|
||||
if (parse_nodash_opt(ctx, arg, options) == 0)
|
||||
continue;
|
||||
|
@ -610,6 +623,8 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
|
|||
}
|
||||
continue;
|
||||
unknown:
|
||||
if (ctx->flags & PARSE_OPT_ONE_SHOT)
|
||||
break;
|
||||
if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
|
||||
return PARSE_OPT_UNKNOWN;
|
||||
ctx->out[ctx->cpidx++] = ctx->argv[0];
|
||||
|
@ -623,6 +638,9 @@ unknown:
|
|||
|
||||
int parse_options_end(struct parse_opt_ctx_t *ctx)
|
||||
{
|
||||
if (ctx->flags & PARSE_OPT_ONE_SHOT)
|
||||
return ctx->total - ctx->argc;
|
||||
|
||||
MOVE_ARRAY(ctx->out + ctx->cpidx, ctx->argv, ctx->argc);
|
||||
ctx->out[ctx->cpidx + ctx->argc] = NULL;
|
||||
return ctx->cpidx + ctx->argc;
|
||||
|
|
|
@ -27,7 +27,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 {
|
||||
|
@ -169,10 +170,18 @@ struct option {
|
|||
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.
|
||||
*/
|
||||
int parse_options(int argc, const char **argv, const char *prefix,
|
||||
const struct option *options,
|
||||
|
|
Загрузка…
Ссылка в новой задаче