@ -181,16 +181,49 @@ func (c *Command) parseFlags(args Args) (*flag.FlagSet, error) {
return set , set . Parse ( append ( [ ] string { "--" } , args ... ) )
return set , set . Parse ( append ( [ ] string { "--" } , args ... ) )
}
}
if c . UseShortOptionHandling {
args = translateShortOptions ( args )
}
if ! c . SkipArgReorder {
if ! c . SkipArgReorder {
args = reorderArgs ( args )
args = reorderArgs ( args )
}
}
PARSE :
err = set . Parse ( args )
err = set . Parse ( args )
if err != nil {
if err != nil {
if c . UseShortOptionHandling {
// To enable short-option handling (e.g., "-it" vs "-i -t")
// we have to iteratively catch parsing errors. This way
// we achieve LR parsing without transforming any arguments.
// Otherwise, there is no way we can discriminate combined
// short options from common arguments that should be left
// untouched.
errStr := err . Error ( )
trimmed := strings . TrimPrefix ( errStr , "flag provided but not defined: " )
if errStr == trimmed {
return nil , err
}
// regenerate the initial args with the split short opts
newArgs := Args { }
for i , arg := range args {
if arg != trimmed {
newArgs = append ( newArgs , arg )
continue
}
shortOpts := translateShortOptions ( set , Args { trimmed } )
if len ( shortOpts ) == 1 {
return nil , err
}
// add each short option and all remaining arguments
newArgs = append ( newArgs , shortOpts ... )
newArgs = append ( newArgs , args [ i + 1 : ] ... )
args = newArgs
// now reset the flagset parse again
set , err = flagSet ( c . Name , c . Flags )
if err != nil {
return nil , err
}
set . SetOutput ( ioutil . Discard )
goto PARSE
}
}
return nil , err
return nil , err
}
}
@ -232,11 +265,25 @@ func reorderArgs(args []string) []string {
return append ( flags , nonflags ... )
return append ( flags , nonflags ... )
}
}
func translateShortOptions ( flagArgs Args ) [ ] string {
func translateShortOptions ( set * flag . FlagSet , flagArgs Args ) [ ] string {
allCharsFlags := func ( s string ) bool {
for i := range s {
f := set . Lookup ( string ( s [ i ] ) )
if f == nil {
return false
}
}
return true
}
// separate combined flags
// separate combined flags
var flagArgsSeparated [ ] string
var flagArgsSeparated [ ] string
for _ , flagArg := range flagArgs {
for _ , flagArg := range flagArgs {
if strings . HasPrefix ( flagArg , "-" ) && strings . HasPrefix ( flagArg , "--" ) == false && len ( flagArg ) > 2 {
if strings . HasPrefix ( flagArg , "-" ) && strings . HasPrefix ( flagArg , "--" ) == false && len ( flagArg ) > 2 {
if ! allCharsFlags ( flagArg [ 1 : ] ) {
flagArgsSeparated = append ( flagArgsSeparated , flagArg )
continue
}
for _ , flagChar := range flagArg [ 1 : ] {
for _ , flagChar := range flagArg [ 1 : ] {
flagArgsSeparated = append ( flagArgsSeparated , "-" + string ( flagChar ) )
flagArgsSeparated = append ( flagArgsSeparated , "-" + string ( flagChar ) )
}
}