t0040,t1502: Demonstrate parse_options bugs
PATCH 1/3 t0040,t1502: Demonstrate parse_options bugs
When the option spec contains no switches or only hidden switches, parse_options will emit an extra blank line at the end of help output so that the help text will end in two blank lines instead of one.
When parse_options produces internal help output after an error has occurred it will emit blank lines within the usage string to stdout instead of stderr.
Update t/helper/test-parse-options.c to have a description body in the usage string to exercise this second bug and mark tests as failing in t0040.
Add tests to t1502 to demonstrate both of these problems.
---
Notes:
FYI: this is built on top of bc/rev-parse-parseopt-fix (697bc88) merged into next.
t/helper/test-parse-options.c | 2 + t/t0040-parse-options.sh | 8 ++-- t/t1502-rev-parse-parseopt.sh | 100 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 3 deletions(-)
t/helper/test-parse-options.c +2 -0
@@ -99,6 +99,8 @@ int cmd_main(int argc, const char **argv)const char *prefix ="prefix/" ;const char *usage[] = {"test-parse-options <options>" , +"" , +"A helper function for the parse-options API." ,NULL };struct string_list expect =STRING_LIST_INIT_NODUP ;
t/t0040-parse-options.sh +5 -3
@@ -10,6 +10,8 @@ test_description='our own option parser' cat >expect <<\EOF usage: test-parse-options <options> + A helper function for the parse-options API. + --yes get a boolean -D, --no-doubt begins with 'no-' -B, --no-fear be brave
@@ -90,8 +92,8 @@ test_expect_success 'OPT_BOOL() is idempotent #2' 'check boolean: 1 -DB' test_expect_success 'OPT_BOOL() negation #1' 'check boolean: 0 -D --no-yes' test_expect_success 'OPT_BOOL() negation #2' 'check boolean: 0 -D --no-no-doubt' -test_expect_success 'OPT_BOOL() no negation #1' 'check_unknown_i18n --fear' -test_expect_success 'OPT_BOOL() no negation #2' 'check_unknown_i18n --no-no-fear' +test_expect_failure 'OPT_BOOL() no negation #1' 'check_unknown_i18n --fear' +test_expect_failure 'OPT_BOOL() no negation #2' 'check_unknown_i18n --no-no-fear' test_expect_success 'OPT_BOOL() positivation' 'check boolean: 0 -D --doubt'
@@ -286,7 +288,7 @@ test_expect_success 'OPT_CALLBACK() and OPT_BIT() work' ' >expect -test_expect_success 'OPT_CALLBACK() and callback errors work' ' +test_expect_failure 'OPT_CALLBACK() and callback errors work' ' test_must_fail test-parse-options --no-length >output 2>output.err && test_i18ncmp expect output && test_i18ncmp expect.err output.err
t/t1502-rev-parse-parseopt.sh +100 -0
112 lines not on this page · raw message
Signature · 1 line
2.2.0.rc3
PATCH 2/3 parse-options: write blank line to correct output stream
When commit 54e6dc7 added translation support to parse-options, an fprintf was mistakenly replaced by a call to putchar(). Let's use fputc instead.
Fixes t0040.11, t0040.12, t0040.33, and t1502.8.
--- parse-options.c | 2 +- t/t0040-parse-options.sh | 6 +++--- t/t1502-rev-parse-parseopt.sh | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-)
parse-options.c +1 -1
@@ -599,7 +599,7 @@ static int usage_with_options_internal(struct parse_opt_ctx_t *ctx,if (**usagestr)fprintf_ln (outfile,_ (" %s" ),_ (*usagestr));else -putchar ('\n' ); +fputc ('\n' , outfile); usagestr++; }
t/t0040-parse-options.sh +3 -3
@@ -92,8 +92,8 @@ test_expect_success 'OPT_BOOL() is idempotent #2' 'check boolean: 1 -DB' test_expect_success 'OPT_BOOL() negation #1' 'check boolean: 0 -D --no-yes' test_expect_success 'OPT_BOOL() negation #2' 'check boolean: 0 -D --no-no-doubt' -test_expect_failure 'OPT_BOOL() no negation #1' 'check_unknown_i18n --fear' -test_expect_failure 'OPT_BOOL() no negation #2' 'check_unknown_i18n --no-no-fear' +test_expect_success 'OPT_BOOL() no negation #1' 'check_unknown_i18n --fear' +test_expect_success 'OPT_BOOL() no negation #2' 'check_unknown_i18n --no-no-fear' test_expect_success 'OPT_BOOL() positivation' 'check boolean: 0 -D --doubt'
@@ -288,7 +288,7 @@ test_expect_success 'OPT_CALLBACK() and OPT_BIT() work' ' >expect -test_expect_failure 'OPT_CALLBACK() and callback errors work' ' +test_expect_success 'OPT_CALLBACK() and callback errors work' ' test_must_fail test-parse-options --no-length >output 2>output.err && test_i18ncmp expect output && test_i18ncmp expect.err output.err
t/t1502-rev-parse-parseopt.sh +1 -1
@@ -139,7 +139,7 @@ END_EXPECT test_i18ncmp expect output ' -test_expect_failure 'test --parseopt invalid switch help output' ' +test_expect_success 'test --parseopt invalid switch help output' ' sed -e "s/^|//" >expect <<\END_EXPECT && |error: unknown option `does-not-exist'\'' |usage: some-command [options] <args>...
Signature · 1 line
2.2.0.rc3
PATCH 3/3 parse-options: only insert newline in help text if needed
In reply to Brandon CaseyCurrently, when parse_options() produces a help message it always emits a blank line after the usage text to separate it from the options text. If the option spec does not define any switches, or only defines hidden switches that will not be displayed, then the help text will end up with two trailing blank lines instead of one. Let's defer emitting the blank line between the usage text and the options text until it is clear that the options section will not be empty.
Fixes t1502.5, t1502.6.
--- parse-options.c | 10 ++++++++-- t/t1502-rev-parse-parseopt.sh | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-)
parse-options.c +8 -2
@@ -581,6 +581,7 @@ static int usage_with_options_internal(struct parse_opt_ctx_t *ctx, const struct option *opts, int full, int err) { FILE *outfile = err ? stderr : stdout; +int need_newline;if (!usagestr)return PARSE_OPT_HELP ;
@@ -603,8 +604,7 @@ static int usage_with_options_internal(struct parse_opt_ctx_t *ctx, usagestr++; } -if (opts->type !=OPTION_GROUP ) -fputc ('\n' , outfile); + need_newline =1 ;for (; opts->type !=OPTION_END ; opts++) {size_t pos;
@@ -612,6 +612,7 @@ static int usage_with_options_internal(struct parse_opt_ctx_t *ctx,if (opts->type ==OPTION_GROUP ) {fputc ('\n' , outfile); + need_newline =0 ;if (*opts->help)fprintf (outfile,"%s\n" ,_ (opts->help));continue ;
@@ -619,6 +620,11 @@ static int usage_with_options_internal(struct parse_opt_ctx_t *ctx,if (!full && (opts->flags &PARSE_OPT_HIDDEN ))continue ; +if (need_newline) { +fputc ('\n' , outfile); + need_newline =0 ; + } + pos =fprintf (outfile," " );if (opts->short_name) {if (opts->flags &PARSE_OPT_NODASH )
t/t1502-rev-parse-parseopt.sh +2 -2
@@ -98,7 +98,7 @@ END_EXPECT test_i18ncmp expect output ' -test_expect_failure 'test --parseopt help output no switches' ' +test_expect_success 'test --parseopt help output no switches' ' sed -e "s/^|//" >expect <<\END_EXPECT && |cat <<\EOF |usage: some-command [options] <args>...
@@ -111,7 +111,7 @@ END_EXPECT test_i18ncmp expect output ' -test_expect_failure 'test --parseopt help output hidden switches' ' +test_expect_success 'test --parseopt help output hidden switches' ' sed -e "s/^|//" >expect <<\END_EXPECT && |cat <<\EOF |usage: some-command [options] <args>...
Signature · 1 line
2.2.0.rc3
Re: [PATCH 3/3] parse-options: only insert newline in help text if needed
Quoted 7 lines · Brandon Casey
Currently, when
parse_options()produces a help message it always emits a blank line after the usage text to separate it from the options text. If the option spec does not define any switches, or only defines hidden switches that will not be displayed, then the help text will end up with two trailing blank lines instead of one. Let's defer emitting the blank line between the usage text and the options text until it is clear that the options section will not be empty.
This somehow looks familiar. I think (together with the fix in 2/3) this makes it definitely better.
I also wonder if we want the final blank line, but that is sort-of a different issue.
Thanks.
Re: [PATCH 3/3] parse-options: only insert newline in help text if needed
Quoted 10 lines · Junio C Hamano
Quoted 7 lines · Brandon Casey
Currently, when
parse_options()produces a help message it always emits a blank line after the usage text to separate it from the options text. If the option spec does not define any switches, or only defines hidden switches that will not be displayed, then the help text will end up with two trailing blank lines instead of one. Let's defer emitting the blank line between the usage text and the options text until it is clear that the options section will not be empty.
Quoted 7 lines
This somehow looks familiar. I think (together with the fix in 2/3) this makes it definitely better.
I also wonder if we want the final blank line, but that is sort-of a different issue.
Thanks.
Oh, no wonder that this looked familiar. It solves the same issue as 48b8d3cf ("usage_with_options: omit double new line on empty option list", 2017-08-25) and of course it conflicts with it.
I find the solution presented with this patch is more direct and straightforward, leaving less chance to future breakage. Besides it comes with tests ;-), so perhaps I should drop the other one.