Skip to content

Commit 202fbb3

Browse files
pcloudsgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 1987b0b commit 202fbb3

File tree

2 files changed

+35
-8
lines changed

2 files changed

+35
-8
lines changed

parse-options.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -416,15 +416,24 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
416416
const struct option *options, int flags)
417417
{
418418
memset(ctx, 0, sizeof(*ctx));
419-
ctx->argc = ctx->total = argc - 1;
420-
ctx->argv = argv + 1;
421-
ctx->out = argv;
419+
ctx->argc = argc;
420+
ctx->argv = argv;
421+
if (!(flags & PARSE_OPT_ONE_SHOT)) {
422+
ctx->argc--;
423+
ctx->argv++;
424+
}
425+
ctx->total = ctx->argc;
426+
ctx->out = argv;
422427
ctx->prefix = prefix;
423428
ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
424429
ctx->flags = flags;
425430
if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
426-
(flags & PARSE_OPT_STOP_AT_NON_OPTION))
431+
(flags & PARSE_OPT_STOP_AT_NON_OPTION) &&
432+
!(flags & PARSE_OPT_ONE_SHOT))
427433
BUG("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
434+
if ((flags & PARSE_OPT_ONE_SHOT) &&
435+
(flags & PARSE_OPT_KEEP_ARGV0))
436+
BUG("Can't keep argv0 if you don't have it");
428437
parse_options_check(options);
429438
}
430439

@@ -536,6 +545,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
536545
for (; ctx->argc; ctx->argc--, ctx->argv++) {
537546
const char *arg = ctx->argv[0];
538547

548+
if (ctx->flags & PARSE_OPT_ONE_SHOT &&
549+
ctx->argc != ctx->total)
550+
break;
551+
539552
if (*arg != '-' || !arg[1]) {
540553
if (parse_nodash_opt(ctx, arg, options) == 0)
541554
continue;
@@ -610,6 +623,8 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
610623
}
611624
continue;
612625
unknown:
626+
if (ctx->flags & PARSE_OPT_ONE_SHOT)
627+
break;
613628
if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
614629
return PARSE_OPT_UNKNOWN;
615630
ctx->out[ctx->cpidx++] = ctx->argv[0];
@@ -623,6 +638,9 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
623638

624639
int parse_options_end(struct parse_opt_ctx_t *ctx)
625640
{
641+
if (ctx->flags & PARSE_OPT_ONE_SHOT)
642+
return ctx->total - ctx->argc;
643+
626644
MOVE_ARRAY(ctx->out + ctx->cpidx, ctx->argv, ctx->argc);
627645
ctx->out[ctx->cpidx + ctx->argc] = NULL;
628646
return ctx->cpidx + ctx->argc;

parse-options.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ enum parse_opt_flags {
2727
PARSE_OPT_STOP_AT_NON_OPTION = 2,
2828
PARSE_OPT_KEEP_ARGV0 = 4,
2929
PARSE_OPT_KEEP_UNKNOWN = 8,
30-
PARSE_OPT_NO_INTERNAL_HELP = 16
30+
PARSE_OPT_NO_INTERNAL_HELP = 16,
31+
PARSE_OPT_ONE_SHOT = 32
3132
};
3233

3334
enum parse_opt_option_flags {
@@ -169,10 +170,18 @@ struct option {
169170
N_("no-op (backward compatibility)"), \
170171
PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, parse_opt_noop_cb }
171172

172-
/* parse_options() will filter out the processed options and leave the
173-
* non-option arguments in argv[]. usagestr strings should be marked
174-
* for translation with N_().
173+
/*
174+
* parse_options() will filter out the processed options and leave the
175+
* non-option arguments in argv[]. argv0 is assumed program name and
176+
* skipped.
177+
*
178+
* usagestr strings should be marked for translation with N_().
179+
*
175180
* Returns the number of arguments left in argv[].
181+
*
182+
* In one-shot mode, argv0 is not a program name, argv[] is left
183+
* untouched and parse_options() returns the number of options
184+
* processed.
176185
*/
177186
int parse_options(int argc, const char **argv, const char *prefix,
178187
const struct option *options,

0 commit comments

Comments
 (0)