Allow remaining arguments consisting of only an option prefix
This patch considers - not to be an option, unless followed by
another character. Similarly for --, except when PassDoubleDash
is in the parser options since -- takes on a special meaning
in this case.
Fixes #119.
diff --git a/completion.go b/completion.go
index cb7aed6..d0adfe0 100644
--- a/completion.go
+++ b/completion.go
@@ -234,7 +234,7 @@
if opt != nil {
// Completion for the argument of 'opt'
ret = c.completeValue(opt.value, "", lastarg)
- } else if argumentIsOption(lastarg) {
+ } else if argumentStartsOption(lastarg) {
// Complete the option
prefix, optname, islong := stripOptionPrefix(lastarg)
optname, split, argument := splitOption(prefix, optname, islong)
diff --git a/optstyle_other.go b/optstyle_other.go
index 794de23..29ca4b6 100644
--- a/optstyle_other.go
+++ b/optstyle_other.go
@@ -12,10 +12,22 @@
defaultNameArgDelimiter = '='
)
-func argumentIsOption(arg string) bool {
+func argumentStartsOption(arg string) bool {
return len(arg) > 0 && arg[0] == '-'
}
+func argumentIsOption(arg string) bool {
+ if len(arg) > 1 && arg[0] == '-' && arg[1] != '-' {
+ return true
+ }
+
+ if len(arg) > 2 && arg[0] == '-' && arg[1] == '-' && arg[2] != '-' {
+ return true
+ }
+
+ return false
+}
+
// stripOptionPrefix returns the option without the prefix and whether or
// not the option is a long option or not.
func stripOptionPrefix(optname string) (prefix string, name string, islong bool) {
diff --git a/optstyle_windows.go b/optstyle_windows.go
index 096bbff..a51de9c 100644
--- a/optstyle_windows.go
+++ b/optstyle_windows.go
@@ -12,10 +12,26 @@
defaultNameArgDelimiter = ':'
)
+func argumentStartsOption(arg string) bool {
+ return len(arg) > 0 && (arg[0] == '-' || arg[0] == '/')
+}
+
func argumentIsOption(arg string) bool {
// Windows-style options allow front slash for the option
// delimiter.
- return len(arg) > 0 && (arg[0] == '-' || arg[0] == '/')
+ if len(arg) > 1 && arg[0] == '/' {
+ return true
+ }
+
+ if len(arg) > 1 && arg[0] == '-' && arg[1] != '-' {
+ return true
+ }
+
+ if len(arg) > 2 && arg[0] == '-' && arg[1] == '-' && arg[2] != '-' {
+ return true
+ }
+
+ return false
}
// stripOptionPrefix returns the option without the prefix and whether or
diff --git a/parser_private.go b/parser_private.go
index 6ee506f..76be4a7 100644
--- a/parser_private.go
+++ b/parser_private.go
@@ -171,10 +171,10 @@
} else {
arg = s.pop()
- // Accept any single character arguments including '-'.
- // '-' is the special file name for the standard input or the standard output in many cases.
- if len(arg) > 1 && argumentIsOption(arg) {
+ if argumentIsOption(arg) {
return newErrorf(ErrExpectedArgument, "expected argument for flag `%s', but got option `%s'", option, arg)
+ } else if p.Options&PassDoubleDash != 0 && arg == "--" {
+ return newErrorf(ErrExpectedArgument, "expected argument for flag `%s', but got double dash `--'", option)
}
}
diff --git a/parser_test.go b/parser_test.go
index 64fbd69..5792872 100644
--- a/parser_test.go
+++ b/parser_test.go
@@ -313,6 +313,7 @@
expectError bool
errType ErrorType
errMsg string
+ rest []string
}{
{
// short option must not be accepted as argument
@@ -333,7 +334,7 @@
args: []string{"--string-slice", "--"},
expectError: true,
errType: ErrExpectedArgument,
- errMsg: "expected argument for flag `--string-slice', but got option `--'",
+ errMsg: "expected argument for flag `--string-slice', but got double dash `--'",
},
{
// quoted and appended option should be accepted as argument (even if it looks like an option)
@@ -343,6 +344,10 @@
// Accept any single character arguments including '-'
args: []string{"--string-slice", "-"},
},
+ {
+ args: []string{"-o", "-", "-"},
+ rest: []string{"-", "-"},
+ },
}
var opts struct {
StringSlice []string `long:"string-slice"`
@@ -353,7 +358,9 @@
if test.expectError {
assertParseFail(t, test.errType, test.errMsg, &opts, test.args...)
} else {
- assertParseSuccess(t, &opts, test.args...)
+ args := assertParseSuccess(t, &opts, test.args...)
+
+ assertStringArray(t, args, test.rest)
}
}
}