| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 | 
							- package cli
 
- import (
 
- 	"flag"
 
- 	"strings"
 
- )
 
- type iterativeParser interface {
 
- 	newFlagSet() (*flag.FlagSet, error)
 
- 	useShortOptionHandling() bool
 
- }
 
- // 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.
 
- func parseIter(ip iterativeParser, args []string) (*flag.FlagSet, error) {
 
- 	for {
 
- 		set, err := ip.newFlagSet()
 
- 		if err != nil {
 
- 			return nil, err
 
- 		}
 
- 		err = set.Parse(args)
 
- 		if !ip.useShortOptionHandling() || err == nil {
 
- 			return set, err
 
- 		}
 
- 		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 := []string{}
 
- 		for i, arg := range args {
 
- 			if arg != trimmed {
 
- 				newArgs = append(newArgs, arg)
 
- 				continue
 
- 			}
 
- 			shortOpts := splitShortOptions(set, 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
 
- 		}
 
- 	}
 
- }
 
- func splitShortOptions(set *flag.FlagSet, arg string) []string {
 
- 	shortFlagsExist := func(s string) bool {
 
- 		for _, c := range s[1:] {
 
- 			if f := set.Lookup(string(c)); f == nil {
 
- 				return false
 
- 			}
 
- 		}
 
- 		return true
 
- 	}
 
- 	if !isSplittable(arg) || !shortFlagsExist(arg) {
 
- 		return []string{arg}
 
- 	}
 
- 	separated := make([]string, 0, len(arg)-1)
 
- 	for _, flagChar := range arg[1:] {
 
- 		separated = append(separated, "-"+string(flagChar))
 
- 	}
 
- 	return separated
 
- }
 
- func isSplittable(flagArg string) bool {
 
- 	return strings.HasPrefix(flagArg, "-") && !strings.HasPrefix(flagArg, "--") && len(flagArg) > 2
 
- }
 
 
  |