1240 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			1240 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			Go
		
	
	
	
| // Copyright 2009 The Go Authors. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style
 | |
| // license that can be found in the LICENSE file.
 | |
| 
 | |
| /*
 | |
| Package pflag is a drop-in replacement for Go's flag package, implementing
 | |
| POSIX/GNU-style --flags.
 | |
| 
 | |
| pflag is compatible with the GNU extensions to the POSIX recommendations
 | |
| for command-line options. See
 | |
| http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
 | |
| 
 | |
| Usage:
 | |
| 
 | |
| pflag is a drop-in replacement of Go's native flag package. If you import
 | |
| pflag under the name "flag" then all code should continue to function
 | |
| with no changes.
 | |
| 
 | |
| 	import flag "github.com/spf13/pflag"
 | |
| 
 | |
| There is one exception to this: if you directly instantiate the Flag struct
 | |
| there is one more field "Shorthand" that you will need to set.
 | |
| Most code never instantiates this struct directly, and instead uses
 | |
| functions such as String(), BoolVar(), and Var(), and is therefore
 | |
| unaffected.
 | |
| 
 | |
| Define flags using flag.String(), Bool(), Int(), etc.
 | |
| 
 | |
| This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
 | |
| 	var ip = flag.Int("flagname", 1234, "help message for flagname")
 | |
| If you like, you can bind the flag to a variable using the Var() functions.
 | |
| 	var flagvar int
 | |
| 	func init() {
 | |
| 		flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
 | |
| 	}
 | |
| Or you can create custom flags that satisfy the Value interface (with
 | |
| pointer receivers) and couple them to flag parsing by
 | |
| 	flag.Var(&flagVal, "name", "help message for flagname")
 | |
| For such flags, the default value is just the initial value of the variable.
 | |
| 
 | |
| After all flags are defined, call
 | |
| 	flag.Parse()
 | |
| to parse the command line into the defined flags.
 | |
| 
 | |
| Flags may then be used directly. If you're using the flags themselves,
 | |
| they are all pointers; if you bind to variables, they're values.
 | |
| 	fmt.Println("ip has value ", *ip)
 | |
| 	fmt.Println("flagvar has value ", flagvar)
 | |
| 
 | |
| After parsing, the arguments after the flag are available as the
 | |
| slice flag.Args() or individually as flag.Arg(i).
 | |
| The arguments are indexed from 0 through flag.NArg()-1.
 | |
| 
 | |
| The pflag package also defines some new functions that are not in flag,
 | |
| that give one-letter shorthands for flags. You can use these by appending
 | |
| 'P' to the name of any function that defines a flag.
 | |
| 	var ip = flag.IntP("flagname", "f", 1234, "help message")
 | |
| 	var flagvar bool
 | |
| 	func init() {
 | |
| 		flag.BoolVarP(&flagvar, "boolname", "b", true, "help message")
 | |
| 	}
 | |
| 	flag.VarP(&flagval, "varname", "v", "help message")
 | |
| Shorthand letters can be used with single dashes on the command line.
 | |
| Boolean shorthand flags can be combined with other shorthand flags.
 | |
| 
 | |
| Command line flag syntax:
 | |
| 	--flag    // boolean flags only
 | |
| 	--flag=x
 | |
| 
 | |
| Unlike the flag package, a single dash before an option means something
 | |
| different than a double dash. Single dashes signify a series of shorthand
 | |
| letters for flags. All but the last shorthand letter must be boolean flags.
 | |
| 	// boolean flags
 | |
| 	-f
 | |
| 	-abc
 | |
| 	// non-boolean flags
 | |
| 	-n 1234
 | |
| 	-Ifile
 | |
| 	// mixed
 | |
| 	-abcs "hello"
 | |
| 	-abcn1234
 | |
| 
 | |
| Flag parsing stops after the terminator "--". Unlike the flag package,
 | |
| flags can be interspersed with arguments anywhere on the command line
 | |
| before this terminator.
 | |
| 
 | |
| Integer flags accept 1234, 0664, 0x1234 and may be negative.
 | |
| Boolean flags (in their long form) accept 1, 0, t, f, true, false,
 | |
| TRUE, FALSE, True, False.
 | |
| Duration flags accept any input valid for time.ParseDuration.
 | |
| 
 | |
| The default set of command-line flags is controlled by
 | |
| top-level functions.  The FlagSet type allows one to define
 | |
| independent sets of flags, such as to implement subcommands
 | |
| in a command-line interface. The methods of FlagSet are
 | |
| analogous to the top-level functions for the command-line
 | |
| flag set.
 | |
| */
 | |
| package pflag
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"errors"
 | |
| 	goflag "flag"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"os"
 | |
| 	"sort"
 | |
| 	"strings"
 | |
| )
 | |
| 
 | |
| // ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
 | |
| var ErrHelp = errors.New("pflag: help requested")
 | |
| 
 | |
| // ErrorHandling defines how to handle flag parsing errors.
 | |
| type ErrorHandling int
 | |
| 
 | |
| const (
 | |
| 	// ContinueOnError will return an err from Parse() if an error is found
 | |
| 	ContinueOnError ErrorHandling = iota
 | |
| 	// ExitOnError will call os.Exit(2) if an error is found when parsing
 | |
| 	ExitOnError
 | |
| 	// PanicOnError will panic() if an error is found when parsing flags
 | |
| 	PanicOnError
 | |
| )
 | |
| 
 | |
| // ParseErrorsWhitelist defines the parsing errors that can be ignored
 | |
| type ParseErrorsWhitelist struct {
 | |
| 	// UnknownFlags will ignore unknown flags errors and continue parsing rest of the flags
 | |
| 	UnknownFlags bool
 | |
| }
 | |
| 
 | |
| // NormalizedName is a flag name that has been normalized according to rules
 | |
| // for the FlagSet (e.g. making '-' and '_' equivalent).
 | |
| type NormalizedName string
 | |
| 
 | |
| // A FlagSet represents a set of defined flags.
 | |
| type FlagSet struct {
 | |
| 	// Usage is the function called when an error occurs while parsing flags.
 | |
| 	// The field is a function (not a method) that may be changed to point to
 | |
| 	// a custom error handler.
 | |
| 	Usage func()
 | |
| 
 | |
| 	// SortFlags is used to indicate, if user wants to have sorted flags in
 | |
| 	// help/usage messages.
 | |
| 	SortFlags bool
 | |
| 
 | |
| 	// ParseErrorsWhitelist is used to configure a whitelist of errors
 | |
| 	ParseErrorsWhitelist ParseErrorsWhitelist
 | |
| 
 | |
| 	name              string
 | |
| 	parsed            bool
 | |
| 	actual            map[NormalizedName]*Flag
 | |
| 	orderedActual     []*Flag
 | |
| 	sortedActual      []*Flag
 | |
| 	formal            map[NormalizedName]*Flag
 | |
| 	orderedFormal     []*Flag
 | |
| 	sortedFormal      []*Flag
 | |
| 	shorthands        map[byte]*Flag
 | |
| 	args              []string // arguments after flags
 | |
| 	argsLenAtDash     int      // len(args) when a '--' was located when parsing, or -1 if no --
 | |
| 	errorHandling     ErrorHandling
 | |
| 	output            io.Writer // nil means stderr; use out() accessor
 | |
| 	interspersed      bool      // allow interspersed option/non-option args
 | |
| 	normalizeNameFunc func(f *FlagSet, name string) NormalizedName
 | |
| 
 | |
| 	addedGoFlagSets []*goflag.FlagSet
 | |
| }
 | |
| 
 | |
| // A Flag represents the state of a flag.
 | |
| type Flag struct {
 | |
| 	Name                string              // name as it appears on command line
 | |
| 	Shorthand           string              // one-letter abbreviated flag
 | |
| 	Usage               string              // help message
 | |
| 	Value               Value               // value as set
 | |
| 	DefValue            string              // default value (as text); for usage message
 | |
| 	Changed             bool                // If the user set the value (or if left to default)
 | |
| 	NoOptDefVal         string              // default value (as text); if the flag is on the command line without any options
 | |
| 	Deprecated          string              // If this flag is deprecated, this string is the new or now thing to use
 | |
| 	Hidden              bool                // used by cobra.Command to allow flags to be hidden from help/usage text
 | |
| 	ShorthandDeprecated string              // If the shorthand of this flag is deprecated, this string is the new or now thing to use
 | |
| 	Annotations         map[string][]string // used by cobra.Command bash autocomple code
 | |
| }
 | |
| 
 | |
| // Value is the interface to the dynamic value stored in a flag.
 | |
| // (The default value is represented as a string.)
 | |
| type Value interface {
 | |
| 	String() string
 | |
| 	Set(string) error
 | |
| 	Type() string
 | |
| }
 | |
| 
 | |
| // SliceValue is a secondary interface to all flags which hold a list
 | |
| // of values.  This allows full control over the value of list flags,
 | |
| // and avoids complicated marshalling and unmarshalling to csv.
 | |
| type SliceValue interface {
 | |
| 	// Append adds the specified value to the end of the flag value list.
 | |
| 	Append(string) error
 | |
| 	// Replace will fully overwrite any data currently in the flag value list.
 | |
| 	Replace([]string) error
 | |
| 	// GetSlice returns the flag value list as an array of strings.
 | |
| 	GetSlice() []string
 | |
| }
 | |
| 
 | |
| // sortFlags returns the flags as a slice in lexicographical sorted order.
 | |
| func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
 | |
| 	list := make(sort.StringSlice, len(flags))
 | |
| 	i := 0
 | |
| 	for k := range flags {
 | |
| 		list[i] = string(k)
 | |
| 		i++
 | |
| 	}
 | |
| 	list.Sort()
 | |
| 	result := make([]*Flag, len(list))
 | |
| 	for i, name := range list {
 | |
| 		result[i] = flags[NormalizedName(name)]
 | |
| 	}
 | |
| 	return result
 | |
| }
 | |
| 
 | |
| // SetNormalizeFunc allows you to add a function which can translate flag names.
 | |
| // Flags added to the FlagSet will be translated and then when anything tries to
 | |
| // look up the flag that will also be translated. So it would be possible to create
 | |
| // a flag named "getURL" and have it translated to "geturl".  A user could then pass
 | |
| // "--getUrl" which may also be translated to "geturl" and everything will work.
 | |
| func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
 | |
| 	f.normalizeNameFunc = n
 | |
| 	f.sortedFormal = f.sortedFormal[:0]
 | |
| 	for fname, flag := range f.formal {
 | |
| 		nname := f.normalizeFlagName(flag.Name)
 | |
| 		if fname == nname {
 | |
| 			continue
 | |
| 		}
 | |
| 		flag.Name = string(nname)
 | |
| 		delete(f.formal, fname)
 | |
| 		f.formal[nname] = flag
 | |
| 		if _, set := f.actual[fname]; set {
 | |
| 			delete(f.actual, fname)
 | |
| 			f.actual[nname] = flag
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // GetNormalizeFunc returns the previously set NormalizeFunc of a function which
 | |
| // does no translation, if not set previously.
 | |
| func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName {
 | |
| 	if f.normalizeNameFunc != nil {
 | |
| 		return f.normalizeNameFunc
 | |
| 	}
 | |
| 	return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) }
 | |
| }
 | |
| 
 | |
| func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
 | |
| 	n := f.GetNormalizeFunc()
 | |
| 	return n(f, name)
 | |
| }
 | |
| 
 | |
| func (f *FlagSet) out() io.Writer {
 | |
| 	if f.output == nil {
 | |
| 		return os.Stderr
 | |
| 	}
 | |
| 	return f.output
 | |
| }
 | |
| 
 | |
| // SetOutput sets the destination for usage and error messages.
 | |
| // If output is nil, os.Stderr is used.
 | |
| func (f *FlagSet) SetOutput(output io.Writer) {
 | |
| 	f.output = output
 | |
| }
 | |
| 
 | |
| // VisitAll visits the flags in lexicographical order or
 | |
| // in primordial order if f.SortFlags is false, calling fn for each.
 | |
| // It visits all flags, even those not set.
 | |
| func (f *FlagSet) VisitAll(fn func(*Flag)) {
 | |
| 	if len(f.formal) == 0 {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	var flags []*Flag
 | |
| 	if f.SortFlags {
 | |
| 		if len(f.formal) != len(f.sortedFormal) {
 | |
| 			f.sortedFormal = sortFlags(f.formal)
 | |
| 		}
 | |
| 		flags = f.sortedFormal
 | |
| 	} else {
 | |
| 		flags = f.orderedFormal
 | |
| 	}
 | |
| 
 | |
| 	for _, flag := range flags {
 | |
| 		fn(flag)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // HasFlags returns a bool to indicate if the FlagSet has any flags defined.
 | |
| func (f *FlagSet) HasFlags() bool {
 | |
| 	return len(f.formal) > 0
 | |
| }
 | |
| 
 | |
| // HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
 | |
| // that are not hidden.
 | |
| func (f *FlagSet) HasAvailableFlags() bool {
 | |
| 	for _, flag := range f.formal {
 | |
| 		if !flag.Hidden {
 | |
| 			return true
 | |
| 		}
 | |
| 	}
 | |
| 	return false
 | |
| }
 | |
| 
 | |
| // VisitAll visits the command-line flags in lexicographical order or
 | |
| // in primordial order if f.SortFlags is false, calling fn for each.
 | |
| // It visits all flags, even those not set.
 | |
| func VisitAll(fn func(*Flag)) {
 | |
| 	CommandLine.VisitAll(fn)
 | |
| }
 | |
| 
 | |
| // Visit visits the flags in lexicographical order or
 | |
| // in primordial order if f.SortFlags is false, calling fn for each.
 | |
| // It visits only those flags that have been set.
 | |
| func (f *FlagSet) Visit(fn func(*Flag)) {
 | |
| 	if len(f.actual) == 0 {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	var flags []*Flag
 | |
| 	if f.SortFlags {
 | |
| 		if len(f.actual) != len(f.sortedActual) {
 | |
| 			f.sortedActual = sortFlags(f.actual)
 | |
| 		}
 | |
| 		flags = f.sortedActual
 | |
| 	} else {
 | |
| 		flags = f.orderedActual
 | |
| 	}
 | |
| 
 | |
| 	for _, flag := range flags {
 | |
| 		fn(flag)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Visit visits the command-line flags in lexicographical order or
 | |
| // in primordial order if f.SortFlags is false, calling fn for each.
 | |
| // It visits only those flags that have been set.
 | |
| func Visit(fn func(*Flag)) {
 | |
| 	CommandLine.Visit(fn)
 | |
| }
 | |
| 
 | |
| // Lookup returns the Flag structure of the named flag, returning nil if none exists.
 | |
| func (f *FlagSet) Lookup(name string) *Flag {
 | |
| 	return f.lookup(f.normalizeFlagName(name))
 | |
| }
 | |
| 
 | |
| // ShorthandLookup returns the Flag structure of the short handed flag,
 | |
| // returning nil if none exists.
 | |
| // It panics, if len(name) > 1.
 | |
| func (f *FlagSet) ShorthandLookup(name string) *Flag {
 | |
| 	if name == "" {
 | |
| 		return nil
 | |
| 	}
 | |
| 	if len(name) > 1 {
 | |
| 		msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
 | |
| 		fmt.Fprintf(f.out(), msg)
 | |
| 		panic(msg)
 | |
| 	}
 | |
| 	c := name[0]
 | |
| 	return f.shorthands[c]
 | |
| }
 | |
| 
 | |
| // lookup returns the Flag structure of the named flag, returning nil if none exists.
 | |
| func (f *FlagSet) lookup(name NormalizedName) *Flag {
 | |
| 	return f.formal[name]
 | |
| }
 | |
| 
 | |
| // func to return a given type for a given flag name
 | |
| func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) {
 | |
| 	flag := f.Lookup(name)
 | |
| 	if flag == nil {
 | |
| 		err := fmt.Errorf("flag accessed but not defined: %s", name)
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	if flag.Value.Type() != ftype {
 | |
| 		err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type())
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	sval := flag.Value.String()
 | |
| 	result, err := convFunc(sval)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	return result, nil
 | |
| }
 | |
| 
 | |
| // ArgsLenAtDash will return the length of f.Args at the moment when a -- was
 | |
| // found during arg parsing. This allows your program to know which args were
 | |
| // before the -- and which came after.
 | |
| func (f *FlagSet) ArgsLenAtDash() int {
 | |
| 	return f.argsLenAtDash
 | |
| }
 | |
| 
 | |
| // MarkDeprecated indicated that a flag is deprecated in your program. It will
 | |
| // continue to function but will not show up in help or usage messages. Using
 | |
| // this flag will also print the given usageMessage.
 | |
| func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
 | |
| 	flag := f.Lookup(name)
 | |
| 	if flag == nil {
 | |
| 		return fmt.Errorf("flag %q does not exist", name)
 | |
| 	}
 | |
| 	if usageMessage == "" {
 | |
| 		return fmt.Errorf("deprecated message for flag %q must be set", name)
 | |
| 	}
 | |
| 	flag.Deprecated = usageMessage
 | |
| 	flag.Hidden = true
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your
 | |
| // program. It will continue to function but will not show up in help or usage
 | |
| // messages. Using this flag will also print the given usageMessage.
 | |
| func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error {
 | |
| 	flag := f.Lookup(name)
 | |
| 	if flag == nil {
 | |
| 		return fmt.Errorf("flag %q does not exist", name)
 | |
| 	}
 | |
| 	if usageMessage == "" {
 | |
| 		return fmt.Errorf("deprecated message for flag %q must be set", name)
 | |
| 	}
 | |
| 	flag.ShorthandDeprecated = usageMessage
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // MarkHidden sets a flag to 'hidden' in your program. It will continue to
 | |
| // function but will not show up in help or usage messages.
 | |
| func (f *FlagSet) MarkHidden(name string) error {
 | |
| 	flag := f.Lookup(name)
 | |
| 	if flag == nil {
 | |
| 		return fmt.Errorf("flag %q does not exist", name)
 | |
| 	}
 | |
| 	flag.Hidden = true
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // Lookup returns the Flag structure of the named command-line flag,
 | |
| // returning nil if none exists.
 | |
| func Lookup(name string) *Flag {
 | |
| 	return CommandLine.Lookup(name)
 | |
| }
 | |
| 
 | |
| // ShorthandLookup returns the Flag structure of the short handed flag,
 | |
| // returning nil if none exists.
 | |
| func ShorthandLookup(name string) *Flag {
 | |
| 	return CommandLine.ShorthandLookup(name)
 | |
| }
 | |
| 
 | |
| // Set sets the value of the named flag.
 | |
| func (f *FlagSet) Set(name, value string) error {
 | |
| 	normalName := f.normalizeFlagName(name)
 | |
| 	flag, ok := f.formal[normalName]
 | |
| 	if !ok {
 | |
| 		return fmt.Errorf("no such flag -%v", name)
 | |
| 	}
 | |
| 
 | |
| 	err := flag.Value.Set(value)
 | |
| 	if err != nil {
 | |
| 		var flagName string
 | |
| 		if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
 | |
| 			flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name)
 | |
| 		} else {
 | |
| 			flagName = fmt.Sprintf("--%s", flag.Name)
 | |
| 		}
 | |
| 		return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err)
 | |
| 	}
 | |
| 
 | |
| 	if !flag.Changed {
 | |
| 		if f.actual == nil {
 | |
| 			f.actual = make(map[NormalizedName]*Flag)
 | |
| 		}
 | |
| 		f.actual[normalName] = flag
 | |
| 		f.orderedActual = append(f.orderedActual, flag)
 | |
| 
 | |
| 		flag.Changed = true
 | |
| 	}
 | |
| 
 | |
| 	if flag.Deprecated != "" {
 | |
| 		fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // SetAnnotation allows one to set arbitrary annotations on a flag in the FlagSet.
 | |
| // This is sometimes used by spf13/cobra programs which want to generate additional
 | |
| // bash completion information.
 | |
| func (f *FlagSet) SetAnnotation(name, key string, values []string) error {
 | |
| 	normalName := f.normalizeFlagName(name)
 | |
| 	flag, ok := f.formal[normalName]
 | |
| 	if !ok {
 | |
| 		return fmt.Errorf("no such flag -%v", name)
 | |
| 	}
 | |
| 	if flag.Annotations == nil {
 | |
| 		flag.Annotations = map[string][]string{}
 | |
| 	}
 | |
| 	flag.Annotations[key] = values
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // Changed returns true if the flag was explicitly set during Parse() and false
 | |
| // otherwise
 | |
| func (f *FlagSet) Changed(name string) bool {
 | |
| 	flag := f.Lookup(name)
 | |
| 	// If a flag doesn't exist, it wasn't changed....
 | |
| 	if flag == nil {
 | |
| 		return false
 | |
| 	}
 | |
| 	return flag.Changed
 | |
| }
 | |
| 
 | |
| // Set sets the value of the named command-line flag.
 | |
| func Set(name, value string) error {
 | |
| 	return CommandLine.Set(name, value)
 | |
| }
 | |
| 
 | |
| // PrintDefaults prints, to standard error unless configured
 | |
| // otherwise, the default values of all defined flags in the set.
 | |
| func (f *FlagSet) PrintDefaults() {
 | |
| 	usages := f.FlagUsages()
 | |
| 	fmt.Fprint(f.out(), usages)
 | |
| }
 | |
| 
 | |
| // defaultIsZeroValue returns true if the default value for this flag represents
 | |
| // a zero value.
 | |
| func (f *Flag) defaultIsZeroValue() bool {
 | |
| 	switch f.Value.(type) {
 | |
| 	case boolFlag:
 | |
| 		return f.DefValue == "false"
 | |
| 	case *durationValue:
 | |
| 		// Beginning in Go 1.7, duration zero values are "0s"
 | |
| 		return f.DefValue == "0" || f.DefValue == "0s"
 | |
| 	case *intValue, *int8Value, *int32Value, *int64Value, *uintValue, *uint8Value, *uint16Value, *uint32Value, *uint64Value, *countValue, *float32Value, *float64Value:
 | |
| 		return f.DefValue == "0"
 | |
| 	case *stringValue:
 | |
| 		return f.DefValue == ""
 | |
| 	case *ipValue, *ipMaskValue, *ipNetValue:
 | |
| 		return f.DefValue == "<nil>"
 | |
| 	case *intSliceValue, *stringSliceValue, *stringArrayValue:
 | |
| 		return f.DefValue == "[]"
 | |
| 	default:
 | |
| 		switch f.Value.String() {
 | |
| 		case "false":
 | |
| 			return true
 | |
| 		case "<nil>":
 | |
| 			return true
 | |
| 		case "":
 | |
| 			return true
 | |
| 		case "0":
 | |
| 			return true
 | |
| 		}
 | |
| 		return false
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // UnquoteUsage extracts a back-quoted name from the usage
 | |
| // string for a flag and returns it and the un-quoted usage.
 | |
| // Given "a `name` to show" it returns ("name", "a name to show").
 | |
| // If there are no back quotes, the name is an educated guess of the
 | |
| // type of the flag's value, or the empty string if the flag is boolean.
 | |
| func UnquoteUsage(flag *Flag) (name string, usage string) {
 | |
| 	// Look for a back-quoted name, but avoid the strings package.
 | |
| 	usage = flag.Usage
 | |
| 	for i := 0; i < len(usage); i++ {
 | |
| 		if usage[i] == '`' {
 | |
| 			for j := i + 1; j < len(usage); j++ {
 | |
| 				if usage[j] == '`' {
 | |
| 					name = usage[i+1 : j]
 | |
| 					usage = usage[:i] + name + usage[j+1:]
 | |
| 					return name, usage
 | |
| 				}
 | |
| 			}
 | |
| 			break // Only one back quote; use type name.
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	name = flag.Value.Type()
 | |
| 	switch name {
 | |
| 	case "bool":
 | |
| 		name = ""
 | |
| 	case "float64":
 | |
| 		name = "float"
 | |
| 	case "int64":
 | |
| 		name = "int"
 | |
| 	case "uint64":
 | |
| 		name = "uint"
 | |
| 	case "stringSlice":
 | |
| 		name = "strings"
 | |
| 	case "intSlice":
 | |
| 		name = "ints"
 | |
| 	case "uintSlice":
 | |
| 		name = "uints"
 | |
| 	case "boolSlice":
 | |
| 		name = "bools"
 | |
| 	}
 | |
| 
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // Splits the string `s` on whitespace into an initial substring up to
 | |
| // `i` runes in length and the remainder. Will go `slop` over `i` if
 | |
| // that encompasses the entire string (which allows the caller to
 | |
| // avoid short orphan words on the final line).
 | |
| func wrapN(i, slop int, s string) (string, string) {
 | |
| 	if i+slop > len(s) {
 | |
| 		return s, ""
 | |
| 	}
 | |
| 
 | |
| 	w := strings.LastIndexAny(s[:i], " \t\n")
 | |
| 	if w <= 0 {
 | |
| 		return s, ""
 | |
| 	}
 | |
| 	nlPos := strings.LastIndex(s[:i], "\n")
 | |
| 	if nlPos > 0 && nlPos < w {
 | |
| 		return s[:nlPos], s[nlPos+1:]
 | |
| 	}
 | |
| 	return s[:w], s[w+1:]
 | |
| }
 | |
| 
 | |
| // Wraps the string `s` to a maximum width `w` with leading indent
 | |
| // `i`. The first line is not indented (this is assumed to be done by
 | |
| // caller). Pass `w` == 0 to do no wrapping
 | |
| func wrap(i, w int, s string) string {
 | |
| 	if w == 0 {
 | |
| 		return strings.Replace(s, "\n", "\n"+strings.Repeat(" ", i), -1)
 | |
| 	}
 | |
| 
 | |
| 	// space between indent i and end of line width w into which
 | |
| 	// we should wrap the text.
 | |
| 	wrap := w - i
 | |
| 
 | |
| 	var r, l string
 | |
| 
 | |
| 	// Not enough space for sensible wrapping. Wrap as a block on
 | |
| 	// the next line instead.
 | |
| 	if wrap < 24 {
 | |
| 		i = 16
 | |
| 		wrap = w - i
 | |
| 		r += "\n" + strings.Repeat(" ", i)
 | |
| 	}
 | |
| 	// If still not enough space then don't even try to wrap.
 | |
| 	if wrap < 24 {
 | |
| 		return strings.Replace(s, "\n", r, -1)
 | |
| 	}
 | |
| 
 | |
| 	// Try to avoid short orphan words on the final line, by
 | |
| 	// allowing wrapN to go a bit over if that would fit in the
 | |
| 	// remainder of the line.
 | |
| 	slop := 5
 | |
| 	wrap = wrap - slop
 | |
| 
 | |
| 	// Handle first line, which is indented by the caller (or the
 | |
| 	// special case above)
 | |
| 	l, s = wrapN(wrap, slop, s)
 | |
| 	r = r + strings.Replace(l, "\n", "\n"+strings.Repeat(" ", i), -1)
 | |
| 
 | |
| 	// Now wrap the rest
 | |
| 	for s != "" {
 | |
| 		var t string
 | |
| 
 | |
| 		t, s = wrapN(wrap, slop, s)
 | |
| 		r = r + "\n" + strings.Repeat(" ", i) + strings.Replace(t, "\n", "\n"+strings.Repeat(" ", i), -1)
 | |
| 	}
 | |
| 
 | |
| 	return r
 | |
| 
 | |
| }
 | |
| 
 | |
| // FlagUsagesWrapped returns a string containing the usage information
 | |
| // for all flags in the FlagSet. Wrapped to `cols` columns (0 for no
 | |
| // wrapping)
 | |
| func (f *FlagSet) FlagUsagesWrapped(cols int) string {
 | |
| 	buf := new(bytes.Buffer)
 | |
| 
 | |
| 	lines := make([]string, 0, len(f.formal))
 | |
| 
 | |
| 	maxlen := 0
 | |
| 	f.VisitAll(func(flag *Flag) {
 | |
| 		if flag.Hidden {
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		line := ""
 | |
| 		if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
 | |
| 			line = fmt.Sprintf("  -%s, --%s", flag.Shorthand, flag.Name)
 | |
| 		} else {
 | |
| 			line = fmt.Sprintf("      --%s", flag.Name)
 | |
| 		}
 | |
| 
 | |
| 		varname, usage := UnquoteUsage(flag)
 | |
| 		if varname != "" {
 | |
| 			line += " " + varname
 | |
| 		}
 | |
| 		if flag.NoOptDefVal != "" {
 | |
| 			switch flag.Value.Type() {
 | |
| 			case "string":
 | |
| 				line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
 | |
| 			case "bool":
 | |
| 				if flag.NoOptDefVal != "true" {
 | |
| 					line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
 | |
| 				}
 | |
| 			case "count":
 | |
| 				if flag.NoOptDefVal != "+1" {
 | |
| 					line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
 | |
| 				}
 | |
| 			default:
 | |
| 				line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		// This special character will be replaced with spacing once the
 | |
| 		// correct alignment is calculated
 | |
| 		line += "\x00"
 | |
| 		if len(line) > maxlen {
 | |
| 			maxlen = len(line)
 | |
| 		}
 | |
| 
 | |
| 		line += usage
 | |
| 		if !flag.defaultIsZeroValue() {
 | |
| 			if flag.Value.Type() == "string" {
 | |
| 				line += fmt.Sprintf(" (default %q)", flag.DefValue)
 | |
| 			} else {
 | |
| 				line += fmt.Sprintf(" (default %s)", flag.DefValue)
 | |
| 			}
 | |
| 		}
 | |
| 		if len(flag.Deprecated) != 0 {
 | |
| 			line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated)
 | |
| 		}
 | |
| 
 | |
| 		lines = append(lines, line)
 | |
| 	})
 | |
| 
 | |
| 	for _, line := range lines {
 | |
| 		sidx := strings.Index(line, "\x00")
 | |
| 		spacing := strings.Repeat(" ", maxlen-sidx)
 | |
| 		// maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx
 | |
| 		fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
 | |
| 	}
 | |
| 
 | |
| 	return buf.String()
 | |
| }
 | |
| 
 | |
| // FlagUsages returns a string containing the usage information for all flags in
 | |
| // the FlagSet
 | |
| func (f *FlagSet) FlagUsages() string {
 | |
| 	return f.FlagUsagesWrapped(0)
 | |
| }
 | |
| 
 | |
| // PrintDefaults prints to standard error the default values of all defined command-line flags.
 | |
| func PrintDefaults() {
 | |
| 	CommandLine.PrintDefaults()
 | |
| }
 | |
| 
 | |
| // defaultUsage is the default function to print a usage message.
 | |
| func defaultUsage(f *FlagSet) {
 | |
| 	fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
 | |
| 	f.PrintDefaults()
 | |
| }
 | |
| 
 | |
| // NOTE: Usage is not just defaultUsage(CommandLine)
 | |
| // because it serves (via godoc flag Usage) as the example
 | |
| // for how to write your own usage function.
 | |
| 
 | |
| // Usage prints to standard error a usage message documenting all defined command-line flags.
 | |
| // The function is a variable that may be changed to point to a custom function.
 | |
| // By default it prints a simple header and calls PrintDefaults; for details about the
 | |
| // format of the output and how to control it, see the documentation for PrintDefaults.
 | |
| var Usage = func() {
 | |
| 	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
 | |
| 	PrintDefaults()
 | |
| }
 | |
| 
 | |
| // NFlag returns the number of flags that have been set.
 | |
| func (f *FlagSet) NFlag() int { return len(f.actual) }
 | |
| 
 | |
| // NFlag returns the number of command-line flags that have been set.
 | |
| func NFlag() int { return len(CommandLine.actual) }
 | |
| 
 | |
| // Arg returns the i'th argument.  Arg(0) is the first remaining argument
 | |
| // after flags have been processed.
 | |
| func (f *FlagSet) Arg(i int) string {
 | |
| 	if i < 0 || i >= len(f.args) {
 | |
| 		return ""
 | |
| 	}
 | |
| 	return f.args[i]
 | |
| }
 | |
| 
 | |
| // Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
 | |
| // after flags have been processed.
 | |
| func Arg(i int) string {
 | |
| 	return CommandLine.Arg(i)
 | |
| }
 | |
| 
 | |
| // NArg is the number of arguments remaining after flags have been processed.
 | |
| func (f *FlagSet) NArg() int { return len(f.args) }
 | |
| 
 | |
| // NArg is the number of arguments remaining after flags have been processed.
 | |
| func NArg() int { return len(CommandLine.args) }
 | |
| 
 | |
| // Args returns the non-flag arguments.
 | |
| func (f *FlagSet) Args() []string { return f.args }
 | |
| 
 | |
| // Args returns the non-flag command-line arguments.
 | |
| func Args() []string { return CommandLine.args }
 | |
| 
 | |
| // Var defines a flag with the specified name and usage string. The type and
 | |
| // value of the flag are represented by the first argument, of type Value, which
 | |
| // typically holds a user-defined implementation of Value. For instance, the
 | |
| // caller could create a flag that turns a comma-separated string into a slice
 | |
| // of strings by giving the slice the methods of Value; in particular, Set would
 | |
| // decompose the comma-separated string into the slice.
 | |
| func (f *FlagSet) Var(value Value, name string, usage string) {
 | |
| 	f.VarP(value, name, "", usage)
 | |
| }
 | |
| 
 | |
| // VarPF is like VarP, but returns the flag created
 | |
| func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {
 | |
| 	// Remember the default value as a string; it won't change.
 | |
| 	flag := &Flag{
 | |
| 		Name:      name,
 | |
| 		Shorthand: shorthand,
 | |
| 		Usage:     usage,
 | |
| 		Value:     value,
 | |
| 		DefValue:  value.String(),
 | |
| 	}
 | |
| 	f.AddFlag(flag)
 | |
| 	return flag
 | |
| }
 | |
| 
 | |
| // VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
 | |
| func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
 | |
| 	f.VarPF(value, name, shorthand, usage)
 | |
| }
 | |
| 
 | |
| // AddFlag will add the flag to the FlagSet
 | |
| func (f *FlagSet) AddFlag(flag *Flag) {
 | |
| 	normalizedFlagName := f.normalizeFlagName(flag.Name)
 | |
| 
 | |
| 	_, alreadyThere := f.formal[normalizedFlagName]
 | |
| 	if alreadyThere {
 | |
| 		msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
 | |
| 		fmt.Fprintln(f.out(), msg)
 | |
| 		panic(msg) // Happens only if flags are declared with identical names
 | |
| 	}
 | |
| 	if f.formal == nil {
 | |
| 		f.formal = make(map[NormalizedName]*Flag)
 | |
| 	}
 | |
| 
 | |
| 	flag.Name = string(normalizedFlagName)
 | |
| 	f.formal[normalizedFlagName] = flag
 | |
| 	f.orderedFormal = append(f.orderedFormal, flag)
 | |
| 
 | |
| 	if flag.Shorthand == "" {
 | |
| 		return
 | |
| 	}
 | |
| 	if len(flag.Shorthand) > 1 {
 | |
| 		msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
 | |
| 		fmt.Fprintf(f.out(), msg)
 | |
| 		panic(msg)
 | |
| 	}
 | |
| 	if f.shorthands == nil {
 | |
| 		f.shorthands = make(map[byte]*Flag)
 | |
| 	}
 | |
| 	c := flag.Shorthand[0]
 | |
| 	used, alreadyThere := f.shorthands[c]
 | |
| 	if alreadyThere {
 | |
| 		msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name)
 | |
| 		fmt.Fprintf(f.out(), msg)
 | |
| 		panic(msg)
 | |
| 	}
 | |
| 	f.shorthands[c] = flag
 | |
| }
 | |
| 
 | |
| // AddFlagSet adds one FlagSet to another. If a flag is already present in f
 | |
| // the flag from newSet will be ignored.
 | |
| func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
 | |
| 	if newSet == nil {
 | |
| 		return
 | |
| 	}
 | |
| 	newSet.VisitAll(func(flag *Flag) {
 | |
| 		if f.Lookup(flag.Name) == nil {
 | |
| 			f.AddFlag(flag)
 | |
| 		}
 | |
| 	})
 | |
| }
 | |
| 
 | |
| // Var defines a flag with the specified name and usage string. The type and
 | |
| // value of the flag are represented by the first argument, of type Value, which
 | |
| // typically holds a user-defined implementation of Value. For instance, the
 | |
| // caller could create a flag that turns a comma-separated string into a slice
 | |
| // of strings by giving the slice the methods of Value; in particular, Set would
 | |
| // decompose the comma-separated string into the slice.
 | |
| func Var(value Value, name string, usage string) {
 | |
| 	CommandLine.VarP(value, name, "", usage)
 | |
| }
 | |
| 
 | |
| // VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
 | |
| func VarP(value Value, name, shorthand, usage string) {
 | |
| 	CommandLine.VarP(value, name, shorthand, usage)
 | |
| }
 | |
| 
 | |
| // failf prints to standard error a formatted error and usage message and
 | |
| // returns the error.
 | |
| func (f *FlagSet) failf(format string, a ...interface{}) error {
 | |
| 	err := fmt.Errorf(format, a...)
 | |
| 	if f.errorHandling != ContinueOnError {
 | |
| 		fmt.Fprintln(f.out(), err)
 | |
| 		f.usage()
 | |
| 	}
 | |
| 	return err
 | |
| }
 | |
| 
 | |
| // usage calls the Usage method for the flag set, or the usage function if
 | |
| // the flag set is CommandLine.
 | |
| func (f *FlagSet) usage() {
 | |
| 	if f == CommandLine {
 | |
| 		Usage()
 | |
| 	} else if f.Usage == nil {
 | |
| 		defaultUsage(f)
 | |
| 	} else {
 | |
| 		f.Usage()
 | |
| 	}
 | |
| }
 | |
| 
 | |
| //--unknown (args will be empty)
 | |
| //--unknown --next-flag ... (args will be --next-flag ...)
 | |
| //--unknown arg ... (args will be arg ...)
 | |
| func stripUnknownFlagValue(args []string) []string {
 | |
| 	if len(args) == 0 {
 | |
| 		//--unknown
 | |
| 		return args
 | |
| 	}
 | |
| 
 | |
| 	first := args[0]
 | |
| 	if len(first) > 0 && first[0] == '-' {
 | |
| 		//--unknown --next-flag ...
 | |
| 		return args
 | |
| 	}
 | |
| 
 | |
| 	//--unknown arg ... (args will be arg ...)
 | |
| 	if len(args) > 1 {
 | |
| 		return args[1:]
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
 | |
| 	a = args
 | |
| 	name := s[2:]
 | |
| 	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
 | |
| 		err = f.failf("bad flag syntax: %s", s)
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	split := strings.SplitN(name, "=", 2)
 | |
| 	name = split[0]
 | |
| 	flag, exists := f.formal[f.normalizeFlagName(name)]
 | |
| 
 | |
| 	if !exists {
 | |
| 		switch {
 | |
| 		case name == "help":
 | |
| 			f.usage()
 | |
| 			return a, ErrHelp
 | |
| 		case f.ParseErrorsWhitelist.UnknownFlags:
 | |
| 			// --unknown=unknownval arg ...
 | |
| 			// we do not want to lose arg in this case
 | |
| 			if len(split) >= 2 {
 | |
| 				return a, nil
 | |
| 			}
 | |
| 
 | |
| 			return stripUnknownFlagValue(a), nil
 | |
| 		default:
 | |
| 			err = f.failf("unknown flag: --%s", name)
 | |
| 			return
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	var value string
 | |
| 	if len(split) == 2 {
 | |
| 		// '--flag=arg'
 | |
| 		value = split[1]
 | |
| 	} else if flag.NoOptDefVal != "" {
 | |
| 		// '--flag' (arg was optional)
 | |
| 		value = flag.NoOptDefVal
 | |
| 	} else if len(a) > 0 {
 | |
| 		// '--flag arg'
 | |
| 		value = a[0]
 | |
| 		a = a[1:]
 | |
| 	} else {
 | |
| 		// '--flag' (arg was required)
 | |
| 		err = f.failf("flag needs an argument: %s", s)
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	err = fn(flag, value)
 | |
| 	if err != nil {
 | |
| 		f.failf(err.Error())
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) {
 | |
| 	outArgs = args
 | |
| 
 | |
| 	if strings.HasPrefix(shorthands, "test.") {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	outShorts = shorthands[1:]
 | |
| 	c := shorthands[0]
 | |
| 
 | |
| 	flag, exists := f.shorthands[c]
 | |
| 	if !exists {
 | |
| 		switch {
 | |
| 		case c == 'h':
 | |
| 			f.usage()
 | |
| 			err = ErrHelp
 | |
| 			return
 | |
| 		case f.ParseErrorsWhitelist.UnknownFlags:
 | |
| 			// '-f=arg arg ...'
 | |
| 			// we do not want to lose arg in this case
 | |
| 			if len(shorthands) > 2 && shorthands[1] == '=' {
 | |
| 				outShorts = ""
 | |
| 				return
 | |
| 			}
 | |
| 
 | |
| 			outArgs = stripUnknownFlagValue(outArgs)
 | |
| 			return
 | |
| 		default:
 | |
| 			err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
 | |
| 			return
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	var value string
 | |
| 	if len(shorthands) > 2 && shorthands[1] == '=' {
 | |
| 		// '-f=arg'
 | |
| 		value = shorthands[2:]
 | |
| 		outShorts = ""
 | |
| 	} else if flag.NoOptDefVal != "" {
 | |
| 		// '-f' (arg was optional)
 | |
| 		value = flag.NoOptDefVal
 | |
| 	} else if len(shorthands) > 1 {
 | |
| 		// '-farg'
 | |
| 		value = shorthands[1:]
 | |
| 		outShorts = ""
 | |
| 	} else if len(args) > 0 {
 | |
| 		// '-f arg'
 | |
| 		value = args[0]
 | |
| 		outArgs = args[1:]
 | |
| 	} else {
 | |
| 		// '-f' (arg was required)
 | |
| 		err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	if flag.ShorthandDeprecated != "" {
 | |
| 		fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
 | |
| 	}
 | |
| 
 | |
| 	err = fn(flag, value)
 | |
| 	if err != nil {
 | |
| 		f.failf(err.Error())
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) {
 | |
| 	a = args
 | |
| 	shorthands := s[1:]
 | |
| 
 | |
| 	// "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv").
 | |
| 	for len(shorthands) > 0 {
 | |
| 		shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
 | |
| 		if err != nil {
 | |
| 			return
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return
 | |
| }
 | |
| 
 | |
| func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
 | |
| 	for len(args) > 0 {
 | |
| 		s := args[0]
 | |
| 		args = args[1:]
 | |
| 		if len(s) == 0 || s[0] != '-' || len(s) == 1 {
 | |
| 			if !f.interspersed {
 | |
| 				f.args = append(f.args, s)
 | |
| 				f.args = append(f.args, args...)
 | |
| 				return nil
 | |
| 			}
 | |
| 			f.args = append(f.args, s)
 | |
| 			continue
 | |
| 		}
 | |
| 
 | |
| 		if s[1] == '-' {
 | |
| 			if len(s) == 2 { // "--" terminates the flags
 | |
| 				f.argsLenAtDash = len(f.args)
 | |
| 				f.args = append(f.args, args...)
 | |
| 				break
 | |
| 			}
 | |
| 			args, err = f.parseLongArg(s, args, fn)
 | |
| 		} else {
 | |
| 			args, err = f.parseShortArg(s, args, fn)
 | |
| 		}
 | |
| 		if err != nil {
 | |
| 			return
 | |
| 		}
 | |
| 	}
 | |
| 	return
 | |
| }
 | |
| 
 | |
| // Parse parses flag definitions from the argument list, which should not
 | |
| // include the command name.  Must be called after all flags in the FlagSet
 | |
| // are defined and before flags are accessed by the program.
 | |
| // The return value will be ErrHelp if -help was set but not defined.
 | |
| func (f *FlagSet) Parse(arguments []string) error {
 | |
| 	if f.addedGoFlagSets != nil {
 | |
| 		for _, goFlagSet := range f.addedGoFlagSets {
 | |
| 			goFlagSet.Parse(nil)
 | |
| 		}
 | |
| 	}
 | |
| 	f.parsed = true
 | |
| 
 | |
| 	if len(arguments) < 0 {
 | |
| 		return nil
 | |
| 	}
 | |
| 
 | |
| 	f.args = make([]string, 0, len(arguments))
 | |
| 
 | |
| 	set := func(flag *Flag, value string) error {
 | |
| 		return f.Set(flag.Name, value)
 | |
| 	}
 | |
| 
 | |
| 	err := f.parseArgs(arguments, set)
 | |
| 	if err != nil {
 | |
| 		switch f.errorHandling {
 | |
| 		case ContinueOnError:
 | |
| 			return err
 | |
| 		case ExitOnError:
 | |
| 			fmt.Println(err)
 | |
| 			os.Exit(2)
 | |
| 		case PanicOnError:
 | |
| 			panic(err)
 | |
| 		}
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| type parseFunc func(flag *Flag, value string) error
 | |
| 
 | |
| // ParseAll parses flag definitions from the argument list, which should not
 | |
| // include the command name. The arguments for fn are flag and value. Must be
 | |
| // called after all flags in the FlagSet are defined and before flags are
 | |
| // accessed by the program. The return value will be ErrHelp if -help was set
 | |
| // but not defined.
 | |
| func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error {
 | |
| 	f.parsed = true
 | |
| 	f.args = make([]string, 0, len(arguments))
 | |
| 
 | |
| 	err := f.parseArgs(arguments, fn)
 | |
| 	if err != nil {
 | |
| 		switch f.errorHandling {
 | |
| 		case ContinueOnError:
 | |
| 			return err
 | |
| 		case ExitOnError:
 | |
| 			os.Exit(2)
 | |
| 		case PanicOnError:
 | |
| 			panic(err)
 | |
| 		}
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // Parsed reports whether f.Parse has been called.
 | |
| func (f *FlagSet) Parsed() bool {
 | |
| 	return f.parsed
 | |
| }
 | |
| 
 | |
| // Parse parses the command-line flags from os.Args[1:].  Must be called
 | |
| // after all flags are defined and before flags are accessed by the program.
 | |
| func Parse() {
 | |
| 	// Ignore errors; CommandLine is set for ExitOnError.
 | |
| 	CommandLine.Parse(os.Args[1:])
 | |
| }
 | |
| 
 | |
| // ParseAll parses the command-line flags from os.Args[1:] and called fn for each.
 | |
| // The arguments for fn are flag and value. Must be called after all flags are
 | |
| // defined and before flags are accessed by the program.
 | |
| func ParseAll(fn func(flag *Flag, value string) error) {
 | |
| 	// Ignore errors; CommandLine is set for ExitOnError.
 | |
| 	CommandLine.ParseAll(os.Args[1:], fn)
 | |
| }
 | |
| 
 | |
| // SetInterspersed sets whether to support interspersed option/non-option arguments.
 | |
| func SetInterspersed(interspersed bool) {
 | |
| 	CommandLine.SetInterspersed(interspersed)
 | |
| }
 | |
| 
 | |
| // Parsed returns true if the command-line flags have been parsed.
 | |
| func Parsed() bool {
 | |
| 	return CommandLine.Parsed()
 | |
| }
 | |
| 
 | |
| // CommandLine is the default set of command-line flags, parsed from os.Args.
 | |
| var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
 | |
| 
 | |
| // NewFlagSet returns a new, empty flag set with the specified name,
 | |
| // error handling property and SortFlags set to true.
 | |
| func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
 | |
| 	f := &FlagSet{
 | |
| 		name:          name,
 | |
| 		errorHandling: errorHandling,
 | |
| 		argsLenAtDash: -1,
 | |
| 		interspersed:  true,
 | |
| 		SortFlags:     true,
 | |
| 	}
 | |
| 	return f
 | |
| }
 | |
| 
 | |
| // SetInterspersed sets whether to support interspersed option/non-option arguments.
 | |
| func (f *FlagSet) SetInterspersed(interspersed bool) {
 | |
| 	f.interspersed = interspersed
 | |
| }
 | |
| 
 | |
| // Init sets the name and error handling property for a flag set.
 | |
| // By default, the zero FlagSet uses an empty name and the
 | |
| // ContinueOnError error handling policy.
 | |
| func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
 | |
| 	f.name = name
 | |
| 	f.errorHandling = errorHandling
 | |
| 	f.argsLenAtDash = -1
 | |
| }
 |