@matheusbsbs / matheus-bagliano / commits / 47e9cd28f8
Fork 0

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>

Thomas Rast committed Jun 12, 2010 at 14:57 UTC 47e9cd28f8a404a0d6293935252ddca5fc243931
4 files changed +30 -16
builtin/rev-parse.c
+2 -1
@@ -408,7 +408,8 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix)
408 memset(opts + onb, 0, sizeof(opts[onb]));
409 argc = parse_options(argc, argv, prefix, opts, usage,
410 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);
413
414 strbuf_addf(&parsed, " --");
415 sq_quote_argv(&parsed, argv, 0);
parse-options.c
+24 -14
@@ -4,7 +4,8 @@
4 #include "commit.h"
5 #include "color.h"
6
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,
9 const struct option *opts, int err);
10
11 #define OPT_SHORT 1
@@ -351,7 +352,8 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
352 die("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
353 }
354
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 *,
357 const struct option *, int, int);
358
359 int parse_options_step(struct parse_opt_ctx_t *ctx,
@@ -380,10 +382,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
382 if (arg[1] != '-') {
383 ctx->opt = arg + 1;
384 if (internal_help && *ctx->opt == 'h')
383 - return parse_options_usage(usagestr, options, 0);
385 + return parse_options_usage(ctx, usagestr, options, 0);
386 switch (parse_short_opt(ctx, options)) {
387 case -1:
386 - return parse_options_usage(usagestr, options, 1);
388 + return parse_options_usage(ctx, usagestr, options, 1);
389 case -2:
390 goto unknown;
391 }
@@ -391,10 +393,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
393 check_typos(arg + 1, options);
394 while (ctx->opt) {
395 if (internal_help && *ctx->opt == 'h')
394 - return parse_options_usage(usagestr, options, 0);
396 + return parse_options_usage(ctx, usagestr, options, 0);
397 switch (parse_short_opt(ctx, options)) {
398 case -1:
397 - return parse_options_usage(usagestr, options, 1);
399 + return parse_options_usage(ctx, usagestr, options, 1);
400 case -2:
401 /* fake a short option thing to hide the fact that we may have
402 * started to parse aggregated stuff
@@ -418,12 +420,12 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
420 }
421
422 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);
424 if (internal_help && !strcmp(arg + 2, "help"))
423 - return parse_options_usage(usagestr, options, 0);
425 + return parse_options_usage(ctx, usagestr, options, 0);
426 switch (parse_long_opt(ctx, arg + 2, options)) {
427 case -1:
426 - return parse_options_usage(usagestr, options, 1);
428 + return parse_options_usage(ctx, usagestr, options, 1);
429 case -2:
430 goto unknown;
431 }
@@ -485,14 +487,18 @@ static int usage_argh(const struct option *opts, FILE *outfile)
487 #define USAGE_OPTS_WIDTH 24
488 #define USAGE_GAP 2
489
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)
493 {
494 FILE *outfile = err ? stderr : stdout;
495
496 if (!usagestr)
497 return PARSE_OPT_HELP;
498
499 + if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
500 + fprintf(outfile, "cat <<\\EOF\n");
501 +
502 fprintf(outfile, "usage: %s\n", *usagestr++);
503 while (*usagestr && **usagestr)
504 fprintf(outfile, " or: %s\n", *usagestr++);
@@ -548,13 +554,16 @@ static int usage_with_options_internal(const char * const *usagestr,
554 }
555 fputc('\n', outfile);
556
557 + if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
558 + fputs("EOF\n", outfile);
559 +
560 return PARSE_OPT_HELP;
561 }
562
563 void usage_with_options(const char * const *usagestr,
564 const struct option *opts)
565 {
557 - usage_with_options_internal(usagestr, opts, 0, 1);
566 + usage_with_options_internal(NULL, usagestr, opts, 0, 1);
567 exit(129);
568 }
569
@@ -566,10 +575,11 @@ void usage_msg_opt(const char *msg,
575 usage_with_options(usagestr, options);
576 }
577
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,
580 const struct option *opts, int err)
581 {
572 - return usage_with_options_internal(usagestr, opts, 0, err);
582 + return usage_with_options_internal(ctx, usagestr, opts, 0, err);
583 }
584
585
parse-options.h
+1
@@ -37,6 +37,7 @@ enum parse_opt_option_flags {
37 PARSE_OPT_NODASH = 32,
38 PARSE_OPT_LITERAL_ARGHELP = 64,
39 PARSE_OPT_NEGHELP = 128,
40 + PARSE_OPT_SHELL_EVAL = 256
41 };
42
43 struct option;
t/t1502-rev-parse-parseopt.sh
+3 -1
@@ -3,7 +3,8 @@
3 test_description='test git rev-parse --parseopt'
4 . ./test-lib.sh
5
6 -cat > expect <<EOF
6 +cat > expect <<\END_EXPECT
7 +cat <<\EOF
8 usage: some-command [options] <args>...
9
10 some-command does foo and bar!
@@ -19,6 +20,7 @@ Extras
20 --extra1 line above used to cause a segfault but no longer does
21
22 EOF
23 +END_EXPECT
24
25 cat > optionspec << EOF
26 some-command [options] <args>...