From: ilya.bobyr@gmail.com Date: Sun, 12 Jul 2015 09:39:50 GMT Subject: [PATCH] rev-parse --parseopt: allow [*=?!] in argument hints Message-ID: <1436693990-2908-1-git-send-email-ilya.bobyr@gmail.com> From: Ilya Bobyr It is not very likely that any of the "*=?!" Characters would be useful in the argument short or long names. On the other hand, there are already argument hints that contain the "=" sign. It used to be impossible to include any of the "*=?!" signs in the arguments hints before. Added test case with equals sign in the argument hint and updated the test to perform all the operations in test_expect_success matching the t\README requirements and allowing commands like ./t1502-rev-parse-parseopt.sh --run=1-2 to stop at the test case 2 without any further modification of the test state area. Signed-off-by: Ilya Bobyr --- builtin/rev-parse.c | 36 ++++++++-------- t/t1502-rev-parse-parseopt.sh | 97 ++++++++++++++++++++++++++----------------- 2 files changed, 77 insertions(+), 56 deletions(-) diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index b623239..205ea67 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -423,17 +423,25 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix) o->flags = PARSE_OPT_NOARG; o->callback = &parseopt_dump; - /* Possible argument name hint */ + /* parse names, type and the hint */ end = s; - while (s > sb.buf && strchr("*=?!", s[-1]) == NULL) - --s; - if (s != sb.buf && s != end) - o->argh = xmemdupz(s, end - s); - if (s == sb.buf) - s = end; + s = sb.buf; + + /* name(s) */ + while (s < end && strchr("*=?!", *s) == NULL) + ++s; + + if (s - sb.buf == 1) /* short option only */ + o->short_name = *sb.buf; + else if (sb.buf[1] != ',') /* long option only */ + o->long_name = xmemdupz(sb.buf, s - sb.buf); + else { + o->short_name = *sb.buf; + o->long_name = xmemdupz(sb.buf + 2, s - sb.buf - 2); + } - while (s > sb.buf && strchr("*=?!", s[-1])) { - switch (*--s) { + while (s < end && strchr("*=?!", *s)) { + switch (*s++) { case '=': o->flags &= ~PARSE_OPT_NOARG; break; @@ -450,14 +458,8 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix) } } - if (s - sb.buf == 1) /* short option only */ - o->short_name = *sb.buf; - else if (sb.buf[1] != ',') /* long option only */ - o->long_name = xmemdupz(sb.buf, s - sb.buf); - else { - o->short_name = *sb.buf; - o->long_name = xmemdupz(sb.buf + 2, s - sb.buf - 2); - } + if (s < end) + o->argh = xmemdupz(s, end - s); } strbuf_release(&sb); diff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh index ebe7c3b..d5e5720 100755 --- a/t/t1502-rev-parse-parseopt.sh +++ b/t/t1502-rev-parse-parseopt.sh @@ -3,7 +3,39 @@ test_description='test git rev-parse --parseopt' . ./test-lib.sh -sed -e 's/^|//' >expect <<\END_EXPECT +test_expect_success 'setup optionspec' ' + sed -e "s/^|//" >optionspec <<\EOF +|some-command [options] ... +| +|some-command does foo and bar! +|-- +|h,help show the help +| +|foo some nifty option --foo +|bar= some cool option --bar with an argument +|b,baz a short and long option +| +| An option group Header +|C? option C with an optional argument +|d,data? short and long option with an optional argument +| +| Argument hints +|B=arg short option required argument +|bar2=arg long option required argument +|e,fuz=with-space short and long option required argument +|s?some short option optional argument +|long?data long option optional argument +|g,fluf?path short and long option optional argument +|longest=very-long-argument-hint a very long argument hint +|pair=key=value with an equals sign in the hint +| +|Extras +|extra1 line above used to cause a segfault but no longer does +EOF +' + +test_expect_success 'test --parseopt help output' ' + sed -e "s/^|//" >expect <<\END_EXPECT && |cat <<\EOF |usage: some-command [options] ... | @@ -28,49 +60,22 @@ sed -e 's/^|//' >expect <<\END_EXPECT | -g, --fluf[=] short and long option optional argument | --longest | a very long argument hint +| --pair with an equals sign in the hint | |Extras | --extra1 line above used to cause a segfault but no longer does | |EOF END_EXPECT - -sed -e 's/^|//' >optionspec <<\EOF -|some-command [options] ... -| -|some-command does foo and bar! -|-- -|h,help show the help -| -|foo some nifty option --foo -|bar= some cool option --bar with an argument -|b,baz a short and long option -| -| An option group Header -|C? option C with an optional argument -|d,data? short and long option with an optional argument -| -| Argument hints -|B=arg short option required argument -|bar2=arg long option required argument -|e,fuz=with-space short and long option required argument -|s?some short option optional argument -|long?data long option optional argument -|g,fluf?path short and long option optional argument -|longest=very-long-argument-hint a very long argument hint -| -|Extras -|extra1 line above used to cause a segfault but no longer does -EOF - -test_expect_success 'test --parseopt help output' ' test_expect_code 129 git rev-parse --parseopt -- -h > output < optionspec && test_i18ncmp expect output ' -cat > expect < expect < output && @@ -82,9 +87,11 @@ test_expect_success 'test --parseopt with mixed options and arguments' ' test_cmp expect output ' -cat > expect < expect < output && @@ -96,54 +103,66 @@ test_expect_success 'test --parseopt --stop-at-non-option' ' test_cmp expect output ' -cat > expect < expect < output && test_cmp expect output ' -cat >expect <expect <output && test_cmp expect output ' -cat > expect < expect <output && test_cmp expect output ' -cat > expect < expect <output && test_cmp expect output ' -cat > expect < expect <output && test_cmp expect output ' -cat > expect < expect <output && -- 2.4.5