github.com/filosottile/go@v0.0.0-20170906193555-dbed9972d994/src/flag/flag.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  /*
     6  	Package flag implements command-line flag parsing.
     7  
     8  	Usage:
     9  
    10  	Define flags using flag.String(), Bool(), Int(), etc.
    11  
    12  	This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
    13  		import "flag"
    14  		var ip = flag.Int("flagname", 1234, "help message for flagname")
    15  	If you like, you can bind the flag to a variable using the Var() functions.
    16  		var flagvar int
    17  		func init() {
    18  			flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
    19  		}
    20  	Or you can create custom flags that satisfy the Value interface (with
    21  	pointer receivers) and couple them to flag parsing by
    22  		flag.Var(&flagVal, "name", "help message for flagname")
    23  	For such flags, the default value is just the initial value of the variable.
    24  
    25  	After all flags are defined, call
    26  		flag.Parse()
    27  	to parse the command line into the defined flags.
    28  
    29  	Flags may then be used directly. If you're using the flags themselves,
    30  	they are all pointers; if you bind to variables, they're values.
    31  		fmt.Println("ip has value ", *ip)
    32  		fmt.Println("flagvar has value ", flagvar)
    33  
    34  	After parsing, the arguments following the flags are available as the
    35  	slice flag.Args() or individually as flag.Arg(i).
    36  	The arguments are indexed from 0 through flag.NArg()-1.
    37  
    38  	Command line flag syntax:
    39  		-flag
    40  		-flag=x
    41  		-flag x  // non-boolean flags only
    42  	One or two minus signs may be used; they are equivalent.
    43  	The last form is not permitted for boolean flags because the
    44  	meaning of the command
    45  		cmd -x *
    46  	will change if there is a file called 0, false, etc.  You must
    47  	use the -flag=false form to turn off a boolean flag.
    48  
    49  	Flag parsing stops just before the first non-flag argument
    50  	("-" is a non-flag argument) or after the terminator "--".
    51  
    52  	Integer flags accept 1234, 0664, 0x1234 and may be negative.
    53  	Boolean flags may be:
    54  		1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False
    55  	Duration flags accept any input valid for time.ParseDuration.
    56  
    57  	The default set of command-line flags is controlled by
    58  	top-level functions.  The FlagSet type allows one to define
    59  	independent sets of flags, such as to implement subcommands
    60  	in a command-line interface. The methods of FlagSet are
    61  	analogous to the top-level functions for the command-line
    62  	flag set.
    63  */
    64  package flag
    65  
    66  import (
    67  	"errors"
    68  	"fmt"
    69  	"io"
    70  	"os"
    71  	"reflect"
    72  	"sort"
    73  	"strconv"
    74  	"time"
    75  )
    76  
    77  // ErrHelp is the error returned if the -help or -h flag is invoked
    78  // but no such flag is defined.
    79  var ErrHelp = errors.New("flag: help requested")
    80  
    81  // -- bool Value
    82  type boolValue bool
    83  
    84  func newBoolValue(val bool, p *bool) *boolValue {
    85  	*p = val
    86  	return (*boolValue)(p)
    87  }
    88  
    89  func (b *boolValue) Set(s string) error {
    90  	v, err := strconv.ParseBool(s)
    91  	*b = boolValue(v)
    92  	return err
    93  }
    94  
    95  func (b *boolValue) Get() interface{} { return bool(*b) }
    96  
    97  func (b *boolValue) String() string { return strconv.FormatBool(bool(*b)) }
    98  
    99  func (b *boolValue) IsBoolFlag() bool { return true }
   100  
   101  // optional interface to indicate boolean flags that can be
   102  // supplied without "=value" text
   103  type boolFlag interface {
   104  	Value
   105  	IsBoolFlag() bool
   106  }
   107  
   108  // -- int Value
   109  type intValue int
   110  
   111  func newIntValue(val int, p *int) *intValue {
   112  	*p = val
   113  	return (*intValue)(p)
   114  }
   115  
   116  func (i *intValue) Set(s string) error {
   117  	v, err := strconv.ParseInt(s, 0, strconv.IntSize)
   118  	*i = intValue(v)
   119  	return err
   120  }
   121  
   122  func (i *intValue) Get() interface{} { return int(*i) }
   123  
   124  func (i *intValue) String() string { return strconv.Itoa(int(*i)) }
   125  
   126  // -- int64 Value
   127  type int64Value int64
   128  
   129  func newInt64Value(val int64, p *int64) *int64Value {
   130  	*p = val
   131  	return (*int64Value)(p)
   132  }
   133  
   134  func (i *int64Value) Set(s string) error {
   135  	v, err := strconv.ParseInt(s, 0, 64)
   136  	*i = int64Value(v)
   137  	return err
   138  }
   139  
   140  func (i *int64Value) Get() interface{} { return int64(*i) }
   141  
   142  func (i *int64Value) String() string { return strconv.FormatInt(int64(*i), 10) }
   143  
   144  // -- uint Value
   145  type uintValue uint
   146  
   147  func newUintValue(val uint, p *uint) *uintValue {
   148  	*p = val
   149  	return (*uintValue)(p)
   150  }
   151  
   152  func (i *uintValue) Set(s string) error {
   153  	v, err := strconv.ParseUint(s, 0, strconv.IntSize)
   154  	*i = uintValue(v)
   155  	return err
   156  }
   157  
   158  func (i *uintValue) Get() interface{} { return uint(*i) }
   159  
   160  func (i *uintValue) String() string { return strconv.FormatUint(uint64(*i), 10) }
   161  
   162  // -- uint64 Value
   163  type uint64Value uint64
   164  
   165  func newUint64Value(val uint64, p *uint64) *uint64Value {
   166  	*p = val
   167  	return (*uint64Value)(p)
   168  }
   169  
   170  func (i *uint64Value) Set(s string) error {
   171  	v, err := strconv.ParseUint(s, 0, 64)
   172  	*i = uint64Value(v)
   173  	return err
   174  }
   175  
   176  func (i *uint64Value) Get() interface{} { return uint64(*i) }
   177  
   178  func (i *uint64Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
   179  
   180  // -- string Value
   181  type stringValue string
   182  
   183  func newStringValue(val string, p *string) *stringValue {
   184  	*p = val
   185  	return (*stringValue)(p)
   186  }
   187  
   188  func (s *stringValue) Set(val string) error {
   189  	*s = stringValue(val)
   190  	return nil
   191  }
   192  
   193  func (s *stringValue) Get() interface{} { return string(*s) }
   194  
   195  func (s *stringValue) String() string { return string(*s) }
   196  
   197  // -- float64 Value
   198  type float64Value float64
   199  
   200  func newFloat64Value(val float64, p *float64) *float64Value {
   201  	*p = val
   202  	return (*float64Value)(p)
   203  }
   204  
   205  func (f *float64Value) Set(s string) error {
   206  	v, err := strconv.ParseFloat(s, 64)
   207  	*f = float64Value(v)
   208  	return err
   209  }
   210  
   211  func (f *float64Value) Get() interface{} { return float64(*f) }
   212  
   213  func (f *float64Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 64) }
   214  
   215  // -- time.Duration Value
   216  type durationValue time.Duration
   217  
   218  func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
   219  	*p = val
   220  	return (*durationValue)(p)
   221  }
   222  
   223  func (d *durationValue) Set(s string) error {
   224  	v, err := time.ParseDuration(s)
   225  	*d = durationValue(v)
   226  	return err
   227  }
   228  
   229  func (d *durationValue) Get() interface{} { return time.Duration(*d) }
   230  
   231  func (d *durationValue) String() string { return (*time.Duration)(d).String() }
   232  
   233  // Value is the interface to the dynamic value stored in a flag.
   234  // (The default value is represented as a string.)
   235  //
   236  // If a Value has an IsBoolFlag() bool method returning true,
   237  // the command-line parser makes -name equivalent to -name=true
   238  // rather than using the next command-line argument.
   239  //
   240  // Set is called once, in command line order, for each flag present.
   241  // The flag package may call the String method with a zero-valued receiver,
   242  // such as a nil pointer.
   243  type Value interface {
   244  	String() string
   245  	Set(string) error
   246  }
   247  
   248  // Getter is an interface that allows the contents of a Value to be retrieved.
   249  // It wraps the Value interface, rather than being part of it, because it
   250  // appeared after Go 1 and its compatibility rules. All Value types provided
   251  // by this package satisfy the Getter interface.
   252  type Getter interface {
   253  	Value
   254  	Get() interface{}
   255  }
   256  
   257  // ErrorHandling defines how FlagSet.Parse behaves if the parse fails.
   258  type ErrorHandling int
   259  
   260  // These constants cause FlagSet.Parse to behave as described if the parse fails.
   261  const (
   262  	ContinueOnError ErrorHandling = iota // Return a descriptive error.
   263  	ExitOnError                          // Call os.Exit(2).
   264  	PanicOnError                         // Call panic with a descriptive error.
   265  )
   266  
   267  // A FlagSet represents a set of defined flags. The zero value of a FlagSet
   268  // has no name and has ContinueOnError error handling.
   269  type FlagSet struct {
   270  	// Usage is the function called when an error occurs while parsing flags.
   271  	// The field is a function (not a method) that may be changed to point to
   272  	// a custom error handler. What happens after Usage is called depends
   273  	// on the ErrorHandling setting; for the command line, this defaults
   274  	// to ExitOnError, which exits the program after calling Usage.
   275  	Usage func()
   276  
   277  	name          string
   278  	parsed        bool
   279  	actual        map[string]*Flag
   280  	formal        map[string]*Flag
   281  	args          []string // arguments after flags
   282  	errorHandling ErrorHandling
   283  	output        io.Writer // nil means stderr; use out() accessor
   284  }
   285  
   286  // A Flag represents the state of a flag.
   287  type Flag struct {
   288  	Name     string // name as it appears on command line
   289  	Usage    string // help message
   290  	Value    Value  // value as set
   291  	DefValue string // default value (as text); for usage message
   292  }
   293  
   294  // sortFlags returns the flags as a slice in lexicographical sorted order.
   295  func sortFlags(flags map[string]*Flag) []*Flag {
   296  	list := make(sort.StringSlice, len(flags))
   297  	i := 0
   298  	for _, f := range flags {
   299  		list[i] = f.Name
   300  		i++
   301  	}
   302  	list.Sort()
   303  	result := make([]*Flag, len(list))
   304  	for i, name := range list {
   305  		result[i] = flags[name]
   306  	}
   307  	return result
   308  }
   309  
   310  func (f *FlagSet) out() io.Writer {
   311  	if f.output == nil {
   312  		return os.Stderr
   313  	}
   314  	return f.output
   315  }
   316  
   317  // SetOutput sets the destination for usage and error messages.
   318  // If output is nil, os.Stderr is used.
   319  func (f *FlagSet) SetOutput(output io.Writer) {
   320  	f.output = output
   321  }
   322  
   323  // VisitAll visits the flags in lexicographical order, calling fn for each.
   324  // It visits all flags, even those not set.
   325  func (f *FlagSet) VisitAll(fn func(*Flag)) {
   326  	for _, flag := range sortFlags(f.formal) {
   327  		fn(flag)
   328  	}
   329  }
   330  
   331  // VisitAll visits the command-line flags in lexicographical order, calling
   332  // fn for each. It visits all flags, even those not set.
   333  func VisitAll(fn func(*Flag)) {
   334  	CommandLine.VisitAll(fn)
   335  }
   336  
   337  // Visit visits the flags in lexicographical order, calling fn for each.
   338  // It visits only those flags that have been set.
   339  func (f *FlagSet) Visit(fn func(*Flag)) {
   340  	for _, flag := range sortFlags(f.actual) {
   341  		fn(flag)
   342  	}
   343  }
   344  
   345  // Visit visits the command-line flags in lexicographical order, calling fn
   346  // for each. It visits only those flags that have been set.
   347  func Visit(fn func(*Flag)) {
   348  	CommandLine.Visit(fn)
   349  }
   350  
   351  // Lookup returns the Flag structure of the named flag, returning nil if none exists.
   352  func (f *FlagSet) Lookup(name string) *Flag {
   353  	return f.formal[name]
   354  }
   355  
   356  // Lookup returns the Flag structure of the named command-line flag,
   357  // returning nil if none exists.
   358  func Lookup(name string) *Flag {
   359  	return CommandLine.formal[name]
   360  }
   361  
   362  // Set sets the value of the named flag.
   363  func (f *FlagSet) Set(name, value string) error {
   364  	flag, ok := f.formal[name]
   365  	if !ok {
   366  		return fmt.Errorf("no such flag -%v", name)
   367  	}
   368  	err := flag.Value.Set(value)
   369  	if err != nil {
   370  		return err
   371  	}
   372  	if f.actual == nil {
   373  		f.actual = make(map[string]*Flag)
   374  	}
   375  	f.actual[name] = flag
   376  	return nil
   377  }
   378  
   379  // Set sets the value of the named command-line flag.
   380  func Set(name, value string) error {
   381  	return CommandLine.Set(name, value)
   382  }
   383  
   384  // isZeroValue guesses whether the string represents the zero
   385  // value for a flag. It is not accurate but in practice works OK.
   386  func isZeroValue(flag *Flag, value string) bool {
   387  	// Build a zero value of the flag's Value type, and see if the
   388  	// result of calling its String method equals the value passed in.
   389  	// This works unless the Value type is itself an interface type.
   390  	typ := reflect.TypeOf(flag.Value)
   391  	var z reflect.Value
   392  	if typ.Kind() == reflect.Ptr {
   393  		z = reflect.New(typ.Elem())
   394  	} else {
   395  		z = reflect.Zero(typ)
   396  	}
   397  	if value == z.Interface().(Value).String() {
   398  		return true
   399  	}
   400  
   401  	switch value {
   402  	case "false":
   403  		return true
   404  	case "":
   405  		return true
   406  	case "0":
   407  		return true
   408  	}
   409  	return false
   410  }
   411  
   412  // UnquoteUsage extracts a back-quoted name from the usage
   413  // string for a flag and returns it and the un-quoted usage.
   414  // Given "a `name` to show" it returns ("name", "a name to show").
   415  // If there are no back quotes, the name is an educated guess of the
   416  // type of the flag's value, or the empty string if the flag is boolean.
   417  func UnquoteUsage(flag *Flag) (name string, usage string) {
   418  	// Look for a back-quoted name, but avoid the strings package.
   419  	usage = flag.Usage
   420  	for i := 0; i < len(usage); i++ {
   421  		if usage[i] == '`' {
   422  			for j := i + 1; j < len(usage); j++ {
   423  				if usage[j] == '`' {
   424  					name = usage[i+1 : j]
   425  					usage = usage[:i] + name + usage[j+1:]
   426  					return name, usage
   427  				}
   428  			}
   429  			break // Only one back quote; use type name.
   430  		}
   431  	}
   432  	// No explicit name, so use type if we can find one.
   433  	name = "value"
   434  	switch flag.Value.(type) {
   435  	case boolFlag:
   436  		name = ""
   437  	case *durationValue:
   438  		name = "duration"
   439  	case *float64Value:
   440  		name = "float"
   441  	case *intValue, *int64Value:
   442  		name = "int"
   443  	case *stringValue:
   444  		name = "string"
   445  	case *uintValue, *uint64Value:
   446  		name = "uint"
   447  	}
   448  	return
   449  }
   450  
   451  // PrintDefaults prints to standard error the default values of all
   452  // defined command-line flags in the set. See the documentation for
   453  // the global function PrintDefaults for more information.
   454  func (f *FlagSet) PrintDefaults() {
   455  	f.VisitAll(func(flag *Flag) {
   456  		s := fmt.Sprintf("  -%s", flag.Name) // Two spaces before -; see next two comments.
   457  		name, usage := UnquoteUsage(flag)
   458  		if len(name) > 0 {
   459  			s += " " + name
   460  		}
   461  		// Boolean flags of one ASCII letter are so common we
   462  		// treat them specially, putting their usage on the same line.
   463  		if len(s) <= 4 { // space, space, '-', 'x'.
   464  			s += "\t"
   465  		} else {
   466  			// Four spaces before the tab triggers good alignment
   467  			// for both 4- and 8-space tab stops.
   468  			s += "\n    \t"
   469  		}
   470  		s += usage
   471  		if !isZeroValue(flag, flag.DefValue) {
   472  			if _, ok := flag.Value.(*stringValue); ok {
   473  				// put quotes on the value
   474  				s += fmt.Sprintf(" (default %q)", flag.DefValue)
   475  			} else {
   476  				s += fmt.Sprintf(" (default %v)", flag.DefValue)
   477  			}
   478  		}
   479  		fmt.Fprint(f.out(), s, "\n")
   480  	})
   481  }
   482  
   483  // PrintDefaults prints, to standard error unless configured otherwise,
   484  // a usage message showing the default settings of all defined
   485  // command-line flags.
   486  // For an integer valued flag x, the default output has the form
   487  //	-x int
   488  //		usage-message-for-x (default 7)
   489  // The usage message will appear on a separate line for anything but
   490  // a bool flag with a one-byte name. For bool flags, the type is
   491  // omitted and if the flag name is one byte the usage message appears
   492  // on the same line. The parenthetical default is omitted if the
   493  // default is the zero value for the type. The listed type, here int,
   494  // can be changed by placing a back-quoted name in the flag's usage
   495  // string; the first such item in the message is taken to be a parameter
   496  // name to show in the message and the back quotes are stripped from
   497  // the message when displayed. For instance, given
   498  //	flag.String("I", "", "search `directory` for include files")
   499  // the output will be
   500  //	-I directory
   501  //		search directory for include files.
   502  func PrintDefaults() {
   503  	CommandLine.PrintDefaults()
   504  }
   505  
   506  // defaultUsage is the default function to print a usage message.
   507  func (f *FlagSet) defaultUsage() {
   508  	if f.name == "" {
   509  		fmt.Fprintf(f.out(), "Usage:\n")
   510  	} else {
   511  		fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
   512  	}
   513  	f.PrintDefaults()
   514  }
   515  
   516  // NOTE: Usage is not just defaultUsage(CommandLine)
   517  // because it serves (via godoc flag Usage) as the example
   518  // for how to write your own usage function.
   519  
   520  // Usage prints a usage message documenting all defined command-line flags
   521  // to CommandLine's output, which by default is os.Stderr.
   522  // It is called when an error occurs while parsing flags.
   523  // The function is a variable that may be changed to point to a custom function.
   524  // By default it prints a simple header and calls PrintDefaults; for details about the
   525  // format of the output and how to control it, see the documentation for PrintDefaults.
   526  // Custom usage functions may choose to exit the program; by default exiting
   527  // happens anyway as the command line's error handling strategy is set to
   528  // ExitOnError.
   529  var Usage = func() {
   530  	fmt.Fprintf(CommandLine.out(), "Usage of %s:\n", os.Args[0])
   531  	PrintDefaults()
   532  }
   533  
   534  // NFlag returns the number of flags that have been set.
   535  func (f *FlagSet) NFlag() int { return len(f.actual) }
   536  
   537  // NFlag returns the number of command-line flags that have been set.
   538  func NFlag() int { return len(CommandLine.actual) }
   539  
   540  // Arg returns the i'th argument. Arg(0) is the first remaining argument
   541  // after flags have been processed. Arg returns an empty string if the
   542  // requested element does not exist.
   543  func (f *FlagSet) Arg(i int) string {
   544  	if i < 0 || i >= len(f.args) {
   545  		return ""
   546  	}
   547  	return f.args[i]
   548  }
   549  
   550  // Arg returns the i'th command-line argument. Arg(0) is the first remaining argument
   551  // after flags have been processed. Arg returns an empty string if the
   552  // requested element does not exist.
   553  func Arg(i int) string {
   554  	return CommandLine.Arg(i)
   555  }
   556  
   557  // NArg is the number of arguments remaining after flags have been processed.
   558  func (f *FlagSet) NArg() int { return len(f.args) }
   559  
   560  // NArg is the number of arguments remaining after flags have been processed.
   561  func NArg() int { return len(CommandLine.args) }
   562  
   563  // Args returns the non-flag arguments.
   564  func (f *FlagSet) Args() []string { return f.args }
   565  
   566  // Args returns the non-flag command-line arguments.
   567  func Args() []string { return CommandLine.args }
   568  
   569  // BoolVar defines a bool flag with specified name, default value, and usage string.
   570  // The argument p points to a bool variable in which to store the value of the flag.
   571  func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
   572  	f.Var(newBoolValue(value, p), name, usage)
   573  }
   574  
   575  // BoolVar defines a bool flag with specified name, default value, and usage string.
   576  // The argument p points to a bool variable in which to store the value of the flag.
   577  func BoolVar(p *bool, name string, value bool, usage string) {
   578  	CommandLine.Var(newBoolValue(value, p), name, usage)
   579  }
   580  
   581  // Bool defines a bool flag with specified name, default value, and usage string.
   582  // The return value is the address of a bool variable that stores the value of the flag.
   583  func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
   584  	p := new(bool)
   585  	f.BoolVar(p, name, value, usage)
   586  	return p
   587  }
   588  
   589  // Bool defines a bool flag with specified name, default value, and usage string.
   590  // The return value is the address of a bool variable that stores the value of the flag.
   591  func Bool(name string, value bool, usage string) *bool {
   592  	return CommandLine.Bool(name, value, usage)
   593  }
   594  
   595  // IntVar defines an int flag with specified name, default value, and usage string.
   596  // The argument p points to an int variable in which to store the value of the flag.
   597  func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
   598  	f.Var(newIntValue(value, p), name, usage)
   599  }
   600  
   601  // IntVar defines an int flag with specified name, default value, and usage string.
   602  // The argument p points to an int variable in which to store the value of the flag.
   603  func IntVar(p *int, name string, value int, usage string) {
   604  	CommandLine.Var(newIntValue(value, p), name, usage)
   605  }
   606  
   607  // Int defines an int flag with specified name, default value, and usage string.
   608  // The return value is the address of an int variable that stores the value of the flag.
   609  func (f *FlagSet) Int(name string, value int, usage string) *int {
   610  	p := new(int)
   611  	f.IntVar(p, name, value, usage)
   612  	return p
   613  }
   614  
   615  // Int defines an int flag with specified name, default value, and usage string.
   616  // The return value is the address of an int variable that stores the value of the flag.
   617  func Int(name string, value int, usage string) *int {
   618  	return CommandLine.Int(name, value, usage)
   619  }
   620  
   621  // Int64Var defines an int64 flag with specified name, default value, and usage string.
   622  // The argument p points to an int64 variable in which to store the value of the flag.
   623  func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {
   624  	f.Var(newInt64Value(value, p), name, usage)
   625  }
   626  
   627  // Int64Var defines an int64 flag with specified name, default value, and usage string.
   628  // The argument p points to an int64 variable in which to store the value of the flag.
   629  func Int64Var(p *int64, name string, value int64, usage string) {
   630  	CommandLine.Var(newInt64Value(value, p), name, usage)
   631  }
   632  
   633  // Int64 defines an int64 flag with specified name, default value, and usage string.
   634  // The return value is the address of an int64 variable that stores the value of the flag.
   635  func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
   636  	p := new(int64)
   637  	f.Int64Var(p, name, value, usage)
   638  	return p
   639  }
   640  
   641  // Int64 defines an int64 flag with specified name, default value, and usage string.
   642  // The return value is the address of an int64 variable that stores the value of the flag.
   643  func Int64(name string, value int64, usage string) *int64 {
   644  	return CommandLine.Int64(name, value, usage)
   645  }
   646  
   647  // UintVar defines a uint flag with specified name, default value, and usage string.
   648  // The argument p points to a uint variable in which to store the value of the flag.
   649  func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
   650  	f.Var(newUintValue(value, p), name, usage)
   651  }
   652  
   653  // UintVar defines a uint flag with specified name, default value, and usage string.
   654  // The argument p points to a uint variable in which to store the value of the flag.
   655  func UintVar(p *uint, name string, value uint, usage string) {
   656  	CommandLine.Var(newUintValue(value, p), name, usage)
   657  }
   658  
   659  // Uint defines a uint flag with specified name, default value, and usage string.
   660  // The return value is the address of a uint variable that stores the value of the flag.
   661  func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
   662  	p := new(uint)
   663  	f.UintVar(p, name, value, usage)
   664  	return p
   665  }
   666  
   667  // Uint defines a uint flag with specified name, default value, and usage string.
   668  // The return value is the address of a uint variable that stores the value of the flag.
   669  func Uint(name string, value uint, usage string) *uint {
   670  	return CommandLine.Uint(name, value, usage)
   671  }
   672  
   673  // Uint64Var defines a uint64 flag with specified name, default value, and usage string.
   674  // The argument p points to a uint64 variable in which to store the value of the flag.
   675  func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
   676  	f.Var(newUint64Value(value, p), name, usage)
   677  }
   678  
   679  // Uint64Var defines a uint64 flag with specified name, default value, and usage string.
   680  // The argument p points to a uint64 variable in which to store the value of the flag.
   681  func Uint64Var(p *uint64, name string, value uint64, usage string) {
   682  	CommandLine.Var(newUint64Value(value, p), name, usage)
   683  }
   684  
   685  // Uint64 defines a uint64 flag with specified name, default value, and usage string.
   686  // The return value is the address of a uint64 variable that stores the value of the flag.
   687  func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
   688  	p := new(uint64)
   689  	f.Uint64Var(p, name, value, usage)
   690  	return p
   691  }
   692  
   693  // Uint64 defines a uint64 flag with specified name, default value, and usage string.
   694  // The return value is the address of a uint64 variable that stores the value of the flag.
   695  func Uint64(name string, value uint64, usage string) *uint64 {
   696  	return CommandLine.Uint64(name, value, usage)
   697  }
   698  
   699  // StringVar defines a string flag with specified name, default value, and usage string.
   700  // The argument p points to a string variable in which to store the value of the flag.
   701  func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
   702  	f.Var(newStringValue(value, p), name, usage)
   703  }
   704  
   705  // StringVar defines a string flag with specified name, default value, and usage string.
   706  // The argument p points to a string variable in which to store the value of the flag.
   707  func StringVar(p *string, name string, value string, usage string) {
   708  	CommandLine.Var(newStringValue(value, p), name, usage)
   709  }
   710  
   711  // String defines a string flag with specified name, default value, and usage string.
   712  // The return value is the address of a string variable that stores the value of the flag.
   713  func (f *FlagSet) String(name string, value string, usage string) *string {
   714  	p := new(string)
   715  	f.StringVar(p, name, value, usage)
   716  	return p
   717  }
   718  
   719  // String defines a string flag with specified name, default value, and usage string.
   720  // The return value is the address of a string variable that stores the value of the flag.
   721  func String(name string, value string, usage string) *string {
   722  	return CommandLine.String(name, value, usage)
   723  }
   724  
   725  // Float64Var defines a float64 flag with specified name, default value, and usage string.
   726  // The argument p points to a float64 variable in which to store the value of the flag.
   727  func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) {
   728  	f.Var(newFloat64Value(value, p), name, usage)
   729  }
   730  
   731  // Float64Var defines a float64 flag with specified name, default value, and usage string.
   732  // The argument p points to a float64 variable in which to store the value of the flag.
   733  func Float64Var(p *float64, name string, value float64, usage string) {
   734  	CommandLine.Var(newFloat64Value(value, p), name, usage)
   735  }
   736  
   737  // Float64 defines a float64 flag with specified name, default value, and usage string.
   738  // The return value is the address of a float64 variable that stores the value of the flag.
   739  func (f *FlagSet) Float64(name string, value float64, usage string) *float64 {
   740  	p := new(float64)
   741  	f.Float64Var(p, name, value, usage)
   742  	return p
   743  }
   744  
   745  // Float64 defines a float64 flag with specified name, default value, and usage string.
   746  // The return value is the address of a float64 variable that stores the value of the flag.
   747  func Float64(name string, value float64, usage string) *float64 {
   748  	return CommandLine.Float64(name, value, usage)
   749  }
   750  
   751  // DurationVar defines a time.Duration flag with specified name, default value, and usage string.
   752  // The argument p points to a time.Duration variable in which to store the value of the flag.
   753  // The flag accepts a value acceptable to time.ParseDuration.
   754  func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
   755  	f.Var(newDurationValue(value, p), name, usage)
   756  }
   757  
   758  // DurationVar defines a time.Duration flag with specified name, default value, and usage string.
   759  // The argument p points to a time.Duration variable in which to store the value of the flag.
   760  // The flag accepts a value acceptable to time.ParseDuration.
   761  func DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
   762  	CommandLine.Var(newDurationValue(value, p), name, usage)
   763  }
   764  
   765  // Duration defines a time.Duration flag with specified name, default value, and usage string.
   766  // The return value is the address of a time.Duration variable that stores the value of the flag.
   767  // The flag accepts a value acceptable to time.ParseDuration.
   768  func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration {
   769  	p := new(time.Duration)
   770  	f.DurationVar(p, name, value, usage)
   771  	return p
   772  }
   773  
   774  // Duration defines a time.Duration flag with specified name, default value, and usage string.
   775  // The return value is the address of a time.Duration variable that stores the value of the flag.
   776  // The flag accepts a value acceptable to time.ParseDuration.
   777  func Duration(name string, value time.Duration, usage string) *time.Duration {
   778  	return CommandLine.Duration(name, value, usage)
   779  }
   780  
   781  // Var defines a flag with the specified name and usage string. The type and
   782  // value of the flag are represented by the first argument, of type Value, which
   783  // typically holds a user-defined implementation of Value. For instance, the
   784  // caller could create a flag that turns a comma-separated string into a slice
   785  // of strings by giving the slice the methods of Value; in particular, Set would
   786  // decompose the comma-separated string into the slice.
   787  func (f *FlagSet) Var(value Value, name string, usage string) {
   788  	// Remember the default value as a string; it won't change.
   789  	flag := &Flag{name, usage, value, value.String()}
   790  	_, alreadythere := f.formal[name]
   791  	if alreadythere {
   792  		var msg string
   793  		if f.name == "" {
   794  			msg = fmt.Sprintf("flag redefined: %s", name)
   795  		} else {
   796  			msg = fmt.Sprintf("%s flag redefined: %s", f.name, name)
   797  		}
   798  		fmt.Fprintln(f.out(), msg)
   799  		panic(msg) // Happens only if flags are declared with identical names
   800  	}
   801  	if f.formal == nil {
   802  		f.formal = make(map[string]*Flag)
   803  	}
   804  	f.formal[name] = flag
   805  }
   806  
   807  // Var defines a flag with the specified name and usage string. The type and
   808  // value of the flag are represented by the first argument, of type Value, which
   809  // typically holds a user-defined implementation of Value. For instance, the
   810  // caller could create a flag that turns a comma-separated string into a slice
   811  // of strings by giving the slice the methods of Value; in particular, Set would
   812  // decompose the comma-separated string into the slice.
   813  func Var(value Value, name string, usage string) {
   814  	CommandLine.Var(value, name, usage)
   815  }
   816  
   817  // failf prints to standard error a formatted error and usage message and
   818  // returns the error.
   819  func (f *FlagSet) failf(format string, a ...interface{}) error {
   820  	err := fmt.Errorf(format, a...)
   821  	fmt.Fprintln(f.out(), err)
   822  	f.usage()
   823  	return err
   824  }
   825  
   826  // usage calls the Usage method for the flag set if one is specified,
   827  // or the appropriate default usage function otherwise.
   828  func (f *FlagSet) usage() {
   829  	if f.Usage == nil {
   830  		f.defaultUsage()
   831  	} else {
   832  		f.Usage()
   833  	}
   834  }
   835  
   836  // parseOne parses one flag. It reports whether a flag was seen.
   837  func (f *FlagSet) parseOne() (bool, error) {
   838  	if len(f.args) == 0 {
   839  		return false, nil
   840  	}
   841  	s := f.args[0]
   842  	if len(s) == 0 || s[0] != '-' || len(s) == 1 {
   843  		return false, nil
   844  	}
   845  	numMinuses := 1
   846  	if s[1] == '-' {
   847  		numMinuses++
   848  		if len(s) == 2 { // "--" terminates the flags
   849  			f.args = f.args[1:]
   850  			return false, nil
   851  		}
   852  	}
   853  	name := s[numMinuses:]
   854  	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
   855  		return false, f.failf("bad flag syntax: %s", s)
   856  	}
   857  
   858  	// it's a flag. does it have an argument?
   859  	f.args = f.args[1:]
   860  	hasValue := false
   861  	value := ""
   862  	for i := 1; i < len(name); i++ { // equals cannot be first
   863  		if name[i] == '=' {
   864  			value = name[i+1:]
   865  			hasValue = true
   866  			name = name[0:i]
   867  			break
   868  		}
   869  	}
   870  	m := f.formal
   871  	flag, alreadythere := m[name] // BUG
   872  	if !alreadythere {
   873  		if name == "help" || name == "h" { // special case for nice help message.
   874  			f.usage()
   875  			return false, ErrHelp
   876  		}
   877  		return false, f.failf("flag provided but not defined: -%s", name)
   878  	}
   879  
   880  	if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
   881  		if hasValue {
   882  			if err := fv.Set(value); err != nil {
   883  				return false, f.failf("invalid boolean value %q for -%s: %v", value, name, err)
   884  			}
   885  		} else {
   886  			if err := fv.Set("true"); err != nil {
   887  				return false, f.failf("invalid boolean flag %s: %v", name, err)
   888  			}
   889  		}
   890  	} else {
   891  		// It must have a value, which might be the next argument.
   892  		if !hasValue && len(f.args) > 0 {
   893  			// value is the next arg
   894  			hasValue = true
   895  			value, f.args = f.args[0], f.args[1:]
   896  		}
   897  		if !hasValue {
   898  			return false, f.failf("flag needs an argument: -%s", name)
   899  		}
   900  		if err := flag.Value.Set(value); err != nil {
   901  			return false, f.failf("invalid value %q for flag -%s: %v", value, name, err)
   902  		}
   903  	}
   904  	if f.actual == nil {
   905  		f.actual = make(map[string]*Flag)
   906  	}
   907  	f.actual[name] = flag
   908  	return true, nil
   909  }
   910  
   911  // Parse parses flag definitions from the argument list, which should not
   912  // include the command name. Must be called after all flags in the FlagSet
   913  // are defined and before flags are accessed by the program.
   914  // The return value will be ErrHelp if -help or -h were set but not defined.
   915  func (f *FlagSet) Parse(arguments []string) error {
   916  	f.parsed = true
   917  	f.args = arguments
   918  	for {
   919  		seen, err := f.parseOne()
   920  		if seen {
   921  			continue
   922  		}
   923  		if err == nil {
   924  			break
   925  		}
   926  		switch f.errorHandling {
   927  		case ContinueOnError:
   928  			return err
   929  		case ExitOnError:
   930  			os.Exit(2)
   931  		case PanicOnError:
   932  			panic(err)
   933  		}
   934  	}
   935  	return nil
   936  }
   937  
   938  // Parsed reports whether f.Parse has been called.
   939  func (f *FlagSet) Parsed() bool {
   940  	return f.parsed
   941  }
   942  
   943  // Parse parses the command-line flags from os.Args[1:]. Must be called
   944  // after all flags are defined and before flags are accessed by the program.
   945  func Parse() {
   946  	// Ignore errors; CommandLine is set for ExitOnError.
   947  	CommandLine.Parse(os.Args[1:])
   948  }
   949  
   950  // Parsed reports whether the command-line flags have been parsed.
   951  func Parsed() bool {
   952  	return CommandLine.Parsed()
   953  }
   954  
   955  // CommandLine is the default set of command-line flags, parsed from os.Args.
   956  // The top-level functions such as BoolVar, Arg, and so on are wrappers for the
   957  // methods of CommandLine.
   958  var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
   959  
   960  func init() {
   961  	// Override generic FlagSet default Usage with call to global Usage.
   962  	// Note: This is not CommandLine.Usage = Usage,
   963  	// because we want any eventual call to use any updated value of Usage,
   964  	// not the value it has when this line is run.
   965  	CommandLine.Usage = commandLineUsage
   966  }
   967  
   968  func commandLineUsage() {
   969  	Usage()
   970  }
   971  
   972  // NewFlagSet returns a new, empty flag set with the specified name and
   973  // error handling property.
   974  func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
   975  	f := &FlagSet{
   976  		name:          name,
   977  		errorHandling: errorHandling,
   978  	}
   979  	f.Usage = f.defaultUsage
   980  	return f
   981  }
   982  
   983  // Init sets the name and error handling property for a flag set.
   984  // By default, the zero FlagSet uses an empty name and the
   985  // ContinueOnError error handling policy.
   986  func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
   987  	f.name = name
   988  	f.errorHandling = errorHandling
   989  }