Skip to content

Commit 47e9cd2

Browse files
trastgitster
authored andcommitted
parseopt: wrap rev-parse --parseopt usage for eval consumption
9c7304e (print the usage string on stdout instead of stderr, 2010-05-17) broke rev-parse --parseopt: when run with -h, the usage notice on stdout ended up in the shell eval. Wrap the usage in a cat <<\EOF ... EOF block when printing to stdout. I do not expect any usage lines to ever start with EOF so this shouldn't be an undue burden. Signed-off-by: Thomas Rast <trast@student.ethz.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 9c7304e commit 47e9cd2

File tree

4 files changed

+30
-16
lines changed

4 files changed

+30
-16
lines changed

builtin/rev-parse.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,8 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
408408
memset(opts + onb, 0, sizeof(opts[onb]));
409409
argc = parse_options(argc, argv, prefix, opts, usage,
410410
keep_dashdash ? PARSE_OPT_KEEP_DASHDASH : 0 |
411-
stop_at_non_option ? PARSE_OPT_STOP_AT_NON_OPTION : 0);
411+
stop_at_non_option ? PARSE_OPT_STOP_AT_NON_OPTION : 0 |
412+
PARSE_OPT_SHELL_EVAL);
412413

413414
strbuf_addf(&parsed, " --");
414415
sq_quote_argv(&parsed, argv, 0);

parse-options.c

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
#include "commit.h"
55
#include "color.h"
66

7-
static int parse_options_usage(const char * const *usagestr,
7+
static int parse_options_usage(struct parse_opt_ctx_t *ctx,
8+
const char * const *usagestr,
89
const struct option *opts, int err);
910

1011
#define OPT_SHORT 1
@@ -351,7 +352,8 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
351352
die("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
352353
}
353354

354-
static int usage_with_options_internal(const char * const *,
355+
static int usage_with_options_internal(struct parse_opt_ctx_t *,
356+
const char * const *,
355357
const struct option *, int, int);
356358

357359
int parse_options_step(struct parse_opt_ctx_t *ctx,
@@ -380,21 +382,21 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
380382
if (arg[1] != '-') {
381383
ctx->opt = arg + 1;
382384
if (internal_help && *ctx->opt == 'h')
383-
return parse_options_usage(usagestr, options, 0);
385+
return parse_options_usage(ctx, usagestr, options, 0);
384386
switch (parse_short_opt(ctx, options)) {
385387
case -1:
386-
return parse_options_usage(usagestr, options, 1);
388+
return parse_options_usage(ctx, usagestr, options, 1);
387389
case -2:
388390
goto unknown;
389391
}
390392
if (ctx->opt)
391393
check_typos(arg + 1, options);
392394
while (ctx->opt) {
393395
if (internal_help && *ctx->opt == 'h')
394-
return parse_options_usage(usagestr, options, 0);
396+
return parse_options_usage(ctx, usagestr, options, 0);
395397
switch (parse_short_opt(ctx, options)) {
396398
case -1:
397-
return parse_options_usage(usagestr, options, 1);
399+
return parse_options_usage(ctx, usagestr, options, 1);
398400
case -2:
399401
/* fake a short option thing to hide the fact that we may have
400402
* started to parse aggregated stuff
@@ -418,12 +420,12 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
418420
}
419421

420422
if (internal_help && !strcmp(arg + 2, "help-all"))
421-
return usage_with_options_internal(usagestr, options, 1, 0);
423+
return usage_with_options_internal(ctx, usagestr, options, 1, 0);
422424
if (internal_help && !strcmp(arg + 2, "help"))
423-
return parse_options_usage(usagestr, options, 0);
425+
return parse_options_usage(ctx, usagestr, options, 0);
424426
switch (parse_long_opt(ctx, arg + 2, options)) {
425427
case -1:
426-
return parse_options_usage(usagestr, options, 1);
428+
return parse_options_usage(ctx, usagestr, options, 1);
427429
case -2:
428430
goto unknown;
429431
}
@@ -485,14 +487,18 @@ static int usage_argh(const struct option *opts, FILE *outfile)
485487
#define USAGE_OPTS_WIDTH 24
486488
#define USAGE_GAP 2
487489

488-
static int usage_with_options_internal(const char * const *usagestr,
489-
const struct option *opts, int full, int err)
490+
static int usage_with_options_internal(struct parse_opt_ctx_t *ctx,
491+
const char * const *usagestr,
492+
const struct option *opts, int full, int err)
490493
{
491494
FILE *outfile = err ? stderr : stdout;
492495

493496
if (!usagestr)
494497
return PARSE_OPT_HELP;
495498

499+
if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
500+
fprintf(outfile, "cat <<\\EOF\n");
501+
496502
fprintf(outfile, "usage: %s\n", *usagestr++);
497503
while (*usagestr && **usagestr)
498504
fprintf(outfile, " or: %s\n", *usagestr++);
@@ -548,13 +554,16 @@ static int usage_with_options_internal(const char * const *usagestr,
548554
}
549555
fputc('\n', outfile);
550556

557+
if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
558+
fputs("EOF\n", outfile);
559+
551560
return PARSE_OPT_HELP;
552561
}
553562

554563
void usage_with_options(const char * const *usagestr,
555564
const struct option *opts)
556565
{
557-
usage_with_options_internal(usagestr, opts, 0, 1);
566+
usage_with_options_internal(NULL, usagestr, opts, 0, 1);
558567
exit(129);
559568
}
560569

@@ -566,10 +575,11 @@ void usage_msg_opt(const char *msg,
566575
usage_with_options(usagestr, options);
567576
}
568577

569-
static int parse_options_usage(const char * const *usagestr,
578+
static int parse_options_usage(struct parse_opt_ctx_t *ctx,
579+
const char * const *usagestr,
570580
const struct option *opts, int err)
571581
{
572-
return usage_with_options_internal(usagestr, opts, 0, err);
582+
return usage_with_options_internal(ctx, usagestr, opts, 0, err);
573583
}
574584

575585

parse-options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ enum parse_opt_option_flags {
3737
PARSE_OPT_NODASH = 32,
3838
PARSE_OPT_LITERAL_ARGHELP = 64,
3939
PARSE_OPT_NEGHELP = 128,
40+
PARSE_OPT_SHELL_EVAL = 256
4041
};
4142

4243
struct option;

t/t1502-rev-parse-parseopt.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
test_description='test git rev-parse --parseopt'
44
. ./test-lib.sh
55

6-
cat > expect <<EOF
6+
cat > expect <<\END_EXPECT
7+
cat <<\EOF
78
usage: some-command [options] <args>...
89
910
some-command does foo and bar!
@@ -19,6 +20,7 @@ Extras
1920
--extra1 line above used to cause a segfault but no longer does
2021
2122
EOF
23+
END_EXPECT
2224

2325
cat > optionspec << EOF
2426
some-command [options] <args>...

0 commit comments

Comments
 (0)