@matheusbsbs / matheus-bagliano / commits / 9c7304e3e3
Fork 0

print the usage string on stdout instead of stderr

When -h is used, print usage messages on stdout. If a command is invoked with wrong arguments then print the usage messages on stderr. Signed-off-by: Giuseppe Scrivano <gscrivano@gnu.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Giuseppe Scrivano committed May 17, 2010 at 17:34 UTC 9c7304e3e39ed397b3cc6566573333e2698a52b4
3 files changed +41 -37
parse-options.c
+33 -31
@@ -5,7 +5,7 @@
5 #include "color.h"
6
7 static int parse_options_usage(const char * const *usagestr,
8 - const struct option *opts);
8 + const struct option *opts, int err);
9
10 #define OPT_SHORT 1
11 #define OPT_UNSET 2
@@ -352,7 +352,7 @@ void parse_options_start(struct parse_opt_ctx_t *ctx,
352 }
353
354 static int usage_with_options_internal(const char * const *,
355 - const struct option *, int);
355 + const struct option *, int, int);
356
357 int parse_options_step(struct parse_opt_ctx_t *ctx,
358 const struct option *options,
@@ -380,10 +380,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
380 if (arg[1] != '-') {
381 ctx->opt = arg + 1;
382 if (internal_help && *ctx->opt == 'h')
383 - return parse_options_usage(usagestr, options);
383 + return parse_options_usage(usagestr, options, 0);
384 switch (parse_short_opt(ctx, options)) {
385 case -1:
386 - return parse_options_usage(usagestr, options);
386 + return parse_options_usage(usagestr, options, 1);
387 case -2:
388 goto unknown;
389 }
@@ -391,10 +391,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
391 check_typos(arg + 1, options);
392 while (ctx->opt) {
393 if (internal_help && *ctx->opt == 'h')
394 - return parse_options_usage(usagestr, options);
394 + return parse_options_usage(usagestr, options, 0);
395 switch (parse_short_opt(ctx, options)) {
396 case -1:
397 - return parse_options_usage(usagestr, options);
397 + return parse_options_usage(usagestr, options, 1);
398 case -2:
399 /* fake a short option thing to hide the fact that we may have
400 * started to parse aggregated stuff
@@ -418,12 +418,12 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
418 }
419
420 if (internal_help && !strcmp(arg + 2, "help-all"))
421 - return usage_with_options_internal(usagestr, options, 1);
421 + return usage_with_options_internal(usagestr, options, 1, 0);
422 if (internal_help && !strcmp(arg + 2, "help"))
423 - return parse_options_usage(usagestr, options);
423 + return parse_options_usage(usagestr, options, 0);
424 switch (parse_long_opt(ctx, arg + 2, options)) {
425 case -1:
426 - return parse_options_usage(usagestr, options);
426 + return parse_options_usage(usagestr, options, 1);
427 case -2:
428 goto unknown;
429 }
@@ -468,7 +468,7 @@ int parse_options(int argc, const char **argv, const char *prefix,
468 return parse_options_end(&ctx);
469 }
470
471 -static int usage_argh(const struct option *opts)
471 +static int usage_argh(const struct option *opts, FILE *outfile)
472 {
473 const char *s;
474 int literal = (opts->flags & PARSE_OPT_LITERAL_ARGHELP) || !opts->argh;
@@ -479,72 +479,74 @@ static int usage_argh(const struct option *opts)
479 s = literal ? "[%s]" : "[<%s>]";
480 else
481 s = literal ? " %s" : " <%s>";
482 - return fprintf(stderr, s, opts->argh ? opts->argh : "...");
482 + return fprintf(outfile, s, opts->argh ? opts->argh : "...");
483 }
484
485 #define USAGE_OPTS_WIDTH 24
486 #define USAGE_GAP 2
487
488 static int usage_with_options_internal(const char * const *usagestr,
489 - const struct option *opts, int full)
489 + const struct option *opts, int full, int err)
490 {
491 + FILE *outfile = err ? stderr : stdout;
492 +
493 if (!usagestr)
494 return PARSE_OPT_HELP;
495
494 - fprintf(stderr, "usage: %s\n", *usagestr++);
496 + fprintf(outfile, "usage: %s\n", *usagestr++);
497 while (*usagestr && **usagestr)
496 - fprintf(stderr, " or: %s\n", *usagestr++);
498 + fprintf(outfile, " or: %s\n", *usagestr++);
499 while (*usagestr) {
498 - fprintf(stderr, "%s%s\n",
500 + fprintf(outfile, "%s%s\n",
501 **usagestr ? " " : "",
502 *usagestr);
503 usagestr++;
504 }
505
506 if (opts->type != OPTION_GROUP)
505 - fputc('\n', stderr);
507 + fputc('\n', outfile);
508
509 for (; opts->type != OPTION_END; opts++) {
510 size_t pos;
511 int pad;
512
513 if (opts->type == OPTION_GROUP) {
512 - fputc('\n', stderr);
514 + fputc('\n', outfile);
515 if (*opts->help)
514 - fprintf(stderr, "%s\n", opts->help);
516 + fprintf(outfile, "%s\n", opts->help);
517 continue;
518 }
519 if (!full && (opts->flags & PARSE_OPT_HIDDEN))
520 continue;
521
520 - pos = fprintf(stderr, " ");
522 + pos = fprintf(outfile, " ");
523 if (opts->short_name && !(opts->flags & PARSE_OPT_NEGHELP)) {
524 if (opts->flags & PARSE_OPT_NODASH)
523 - pos += fprintf(stderr, "%c", opts->short_name);
525 + pos += fprintf(outfile, "%c", opts->short_name);
526 else
525 - pos += fprintf(stderr, "-%c", opts->short_name);
527 + pos += fprintf(outfile, "-%c", opts->short_name);
528 }
529 if (opts->long_name && opts->short_name)
528 - pos += fprintf(stderr, ", ");
530 + pos += fprintf(outfile, ", ");
531 if (opts->long_name)
530 - pos += fprintf(stderr, "--%s%s",
532 + pos += fprintf(outfile, "--%s%s",
533 (opts->flags & PARSE_OPT_NEGHELP) ? "no-" : "",
534 opts->long_name);
535 if (opts->type == OPTION_NUMBER)
534 - pos += fprintf(stderr, "-NUM");
536 + pos += fprintf(outfile, "-NUM");
537
538 if (!(opts->flags & PARSE_OPT_NOARG))
537 - pos += usage_argh(opts);
539 + pos += usage_argh(opts, outfile);
540
541 if (pos <= USAGE_OPTS_WIDTH)
542 pad = USAGE_OPTS_WIDTH - pos;
543 else {
542 - fputc('\n', stderr);
544 + fputc('\n', outfile);
545 pad = USAGE_OPTS_WIDTH;
546 }
545 - fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
547 + fprintf(outfile, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
548 }
547 - fputc('\n', stderr);
549 + fputc('\n', outfile);
550
551 return PARSE_OPT_HELP;
552 }
@@ -552,7 +554,7 @@ static int usage_with_options_internal(const char * const *usagestr,
554 void usage_with_options(const char * const *usagestr,
555 const struct option *opts)
556 {
555 - usage_with_options_internal(usagestr, opts, 0);
557 + usage_with_options_internal(usagestr, opts, 0, 1);
558 exit(129);
559 }
560
@@ -565,9 +567,9 @@ void usage_msg_opt(const char *msg,
567 }
568
569 static int parse_options_usage(const char * const *usagestr,
568 - const struct option *opts)
570 + const struct option *opts, int err)
571 {
570 - return usage_with_options_internal(usagestr, opts, 0);
572 + return usage_with_options_internal(usagestr, opts, 0, err);
573 }
574
575
t/t0040-parse-options.sh
+5 -3
@@ -7,7 +7,7 @@ test_description='our own option parser'
7
8 . ./test-lib.sh
9
10 -cat > expect.err << EOF
10 +cat > expect << EOF
11 usage: test-parse-options <options>
12
13 -b, --boolean get a boolean
@@ -46,10 +46,12 @@ EOF
46
47 test_expect_success 'test help' '
48 test_must_fail test-parse-options -h > output 2> output.err &&
49 - test ! -s output &&
50 - test_cmp expect.err output.err
49 + test ! -s output.err &&
50 + test_cmp expect output
51 '
52
53 +mv expect expect.err
54 +
55 cat > expect << EOF
56 boolean: 2
57 integer: 1729
t/t1502-rev-parse-parseopt.sh
+3 -3
@@ -3,7 +3,7 @@
3 test_description='test git rev-parse --parseopt'
4 . ./test-lib.sh
5
6 -cat > expect.err <<EOF
6 +cat > expect <<EOF
7 usage: some-command [options] <args>...
8
9 some-command does foo and bar!
@@ -38,8 +38,8 @@ extra1 line above used to cause a segfault but no longer does
38 EOF
39
40 test_expect_success 'test --parseopt help output' '
41 - git rev-parse --parseopt -- -h 2> output.err < optionspec
42 - test_cmp expect.err output.err
41 + git rev-parse --parseopt -- -h > output < optionspec
42 + test_cmp expect output
43 '
44
45 cat > expect <<EOF