github.com/ccccaoqing/test@v0.0.0-20220510085219-3985d23445c0/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 after the flag 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  	"sort"
    72  	"strconv"
    73  	"time"
    74  )
    75  
    76  // ErrHelp is the error returned if the -help or -h flag is invoked
    77  // but no such flag is defined.
    78  var ErrHelp = errors.New("flag: help requested")
    79  
    80  // -- bool Value
    81  type boolValue bool
    82  
    83  func newBoolValue(val bool, p *bool) *boolValue {
    84  	*p = val
    85  	return (*boolValue)(p)
    86  }
    87  
    88  func (b *boolValue) Set(s string) error {
    89  	v, err := strconv.ParseBool(s)
    90  	*b = boolValue(v)
    91  	return err
    92  }
    93  
    94  func (b *boolValue) Get() interface{} { return bool(*b) }
    95  
    96  func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) }
    97  
    98  func (b *boolValue) IsBoolFlag() bool { return true }
    99  
   100  // optional interface to indicate boolean flags that can be
   101  // supplied without "=value" text
   102  type boolFlag interface {
   103  	Value
   104  	IsBoolFlag() bool
   105  }
   106  
   107  // -- int Value
   108  type intValue int
   109  
   110  func newIntValue(val int, p *int) *intValue {
   111  	*p = val
   112  	return (*intValue)(p)
   113  }
   114  
   115  func (i *intValue) Set(s string) error {
   116  	v, err := strconv.ParseInt(s, 0, 64)
   117  	*i = intValue(v)
   118  	return err
   119  }
   120  
   121  func (i *intValue) Get() interface{} { return int(*i) }
   122  
   123  func (i *intValue) String() string { return fmt.Sprintf("%v", *i) }
   124  
   125  // -- int64 Value
   126  type int64Value int64
   127  
   128  func newInt64Value(val int64, p *int64) *int64Value {
   129  	*p = val
   130  	return (*int64Value)(p)
   131  }
   132  
   133  func (i *int64Value) Set(s string) error {
   134  	v, err := strconv.ParseInt(s, 0, 64)
   135  	*i = int64Value(v)
   136  	return err
   137  }
   138  
   139  func (i *int64Value) Get() interface{} { return int64(*i) }
   140  
   141  func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) }
   142  
   143  // -- uint Value
   144  type uintValue uint
   145  
   146  func newUintValue(val uint, p *uint) *uintValue {
   147  	*p = val
   148  	return (*uintValue)(p)
   149  }
   150  
   151  func (i *uintValue) Set(s string) error {
   152  	v, err := strconv.ParseUint(s, 0, 64)
   153  	*i = uintValue(v)
   154  	return err
   155  }
   156  
   157  func (i *uintValue) Get() interface{} { return uint(*i) }
   158  
   159  func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
   160  
   161  // -- uint64 Value
   162  type uint64Value uint64
   163  
   164  func newUint64Value(val uint64, p *uint64) *uint64Value {
   165  	*p = val
   166  	return (*uint64Value)(p)
   167  }
   168  
   169  func (i *uint64Value) Set(s string) error {
   170  	v, err := strconv.ParseUint(s, 0, 64)
   171  	*i = uint64Value(v)
   172  	return err
   173  }
   174  
   175  func (i *uint64Value) Get() interface{} { return uint64(*i) }
   176  
   177  func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
   178  
   179  // -- string Value
   180  type stringValue string
   181  
   182  func newStringValue(val string, p *string) *stringValue {
   183  	*p = val
   184  	return (*stringValue)(p)
   185  }
   186  
   187  func (s *stringValue) Set(val string) error {
   188  	*s = stringValue(val)
   189  	return nil
   190  }
   191  
   192  func (s *stringValue) Get() interface{} { return string(*s) }
   193  
   194  func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) }
   195  
   196  // -- float64 Value
   197  type float64Value float64
   198  
   199  func newFloat64Value(val float64, p *float64) *float64Value {
   200  	*p = val
   201  	return (*float64Value)(p)
   202  }
   203  
   204  func (f *float64Value) Set(s string) error {
   205  	v, err := strconv.ParseFloat(s, 64)
   206  	*f = float64Value(v)
   207  	return err
   208  }
   209  
   210  func (f *float64Value) Get() interface{} { return float64(*f) }
   211  
   212  func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
   213  
   214  // -- time.Duration Value
   215  type durationValue time.Duration
   216  
   217  func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
   218  	*p = val
   219  	return (*durationValue)(p)
   220  }
   221  
   222  func (d *durationValue) Set(s string) error {
   223  	v, err := time.ParseDuration(s)
   224  	*d = durationValue(v)
   225  	return err
   226  }
   227  
   228  func (d *durationValue) Get() interface{} { return time.Duration(*d) }
   229  
   230  func (d *durationValue) String() string { return (*time.Duration)(d).String() }
   231  
   232  // Value is the interface to the dynamic value stored in a flag.
   233  // (The default value is represented as a string.)
   234  //
   235  // If a Value has an IsBoolFlag() bool method returning true,
   236  // the command-line parser makes -name equivalent to -name=true
   237  // rather than using the next command-line argument.
   238  type Value interface {
   239  	String() string
   240  	Set(string) error
   241  }
   242  
   243  // Getter is an interface that allows the contents of a Value to be retrieved.
   244  // It wraps the Value interface, rather than being part of it, because it
   245  // appeared after Go 1 and its compatibility rules. All Value types provided
   246  // by this package satisfy the Getter interface.
   247  type Getter interface {
   248  	Value
   249  	Get() interface{}
   250  }
   251  
   252  // ErrorHandling defines how to handle flag parsing errors.
   253  type ErrorHandling int
   254  
   255  const (
   256  	ContinueOnError ErrorHandling = iota
   257  	ExitOnError
   258  	PanicOnError
   259  )
   260  
   261  // A FlagSet represents a set of defined flags.  The zero value of a FlagSet
   262  // has no name and has ContinueOnError error handling.
   263  type FlagSet struct {
   264  	// Usage is the function called when an error occurs while parsing flags.
   265  	// The field is a function (not a method) that may be changed to point to
   266  	// a custom error handler.
   267  	Usage func()
   268  
   269  	name          string
   270  	parsed        bool
   271  	actual        map[string]*Flag
   272  	formal        map[string]*Flag
   273  	args          []string // arguments after flags
   274  	errorHandling ErrorHandling
   275  	output        io.Writer // nil means stderr; use out() accessor
   276  }
   277  
   278  // A Flag represents the state of a flag.
   279  type Flag struct {
   280  	Name     string // name as it appears on command line
   281  	Usage    string // help message
   282  	Value    Value  // value as set
   283  	DefValue string // default value (as text); for usage message
   284  }
   285  
   286  // sortFlags returns the flags as a slice in lexicographical sorted order.
   287  func sortFlags(flags map[string]*Flag) []*Flag {
   288  	list := make(sort.StringSlice, len(flags))
   289  	i := 0
   290  	for _, f := range flags {
   291  		list[i] = f.Name
   292  		i++
   293  	}
   294  	list.Sort()
   295  	result := make([]*Flag, len(list))
   296  	for i, name := range list {
   297  		result[i] = flags[name]
   298  	}
   299  	return result
   300  }
   301  
   302  func (f *FlagSet) out() io.Writer {
   303  	if f.output == nil {
   304  		return os.Stderr
   305  	}
   306  	return f.output
   307  }
   308  
   309  // SetOutput sets the destination for usage and error messages.
   310  // If output is nil, os.Stderr is used.
   311  func (f *FlagSet) SetOutput(output io.Writer) {
   312  	f.output = output
   313  }
   314  
   315  // VisitAll visits the flags in lexicographical order, calling fn for each.
   316  // It visits all flags, even those not set.
   317  func (f *FlagSet) VisitAll(fn func(*Flag)) {
   318  	for _, flag := range sortFlags(f.formal) {
   319  		fn(flag)
   320  	}
   321  }
   322  
   323  // VisitAll visits the command-line flags in lexicographical order, calling
   324  // fn for each.  It visits all flags, even those not set.
   325  func VisitAll(fn func(*Flag)) {
   326  	CommandLine.VisitAll(fn)
   327  }
   328  
   329  // Visit visits the flags in lexicographical order, calling fn for each.
   330  // It visits only those flags that have been set.
   331  func (f *FlagSet) Visit(fn func(*Flag)) {
   332  	for _, flag := range sortFlags(f.actual) {
   333  		fn(flag)
   334  	}
   335  }
   336  
   337  // Visit visits the command-line flags in lexicographical order, calling fn
   338  // for each.  It visits only those flags that have been set.
   339  func Visit(fn func(*Flag)) {
   340  	CommandLine.Visit(fn)
   341  }
   342  
   343  // Lookup returns the Flag structure of the named flag, returning nil if none exists.
   344  func (f *FlagSet) Lookup(name string) *Flag {
   345  	return f.formal[name]
   346  }
   347  
   348  // Lookup returns the Flag structure of the named command-line flag,
   349  // returning nil if none exists.
   350  func Lookup(name string) *Flag {
   351  	return CommandLine.formal[name]
   352  }
   353  
   354  // Set sets the value of the named flag.
   355  func (f *FlagSet) Set(name, value string) error {
   356  	flag, ok := f.formal[name]
   357  	if !ok {
   358  		return fmt.Errorf("no such flag -%v", name)
   359  	}
   360  	err := flag.Value.Set(value)
   361  	if err != nil {
   362  		return err
   363  	}
   364  	if f.actual == nil {
   365  		f.actual = make(map[string]*Flag)
   366  	}
   367  	f.actual[name] = flag
   368  	return nil
   369  }
   370  
   371  // Set sets the value of the named command-line flag.
   372  func Set(name, value string) error {
   373  	return CommandLine.Set(name, value)
   374  }
   375  
   376  // PrintDefaults prints, to standard error unless configured
   377  // otherwise, the default values of all defined flags in the set.
   378  func (f *FlagSet) PrintDefaults() {
   379  	f.VisitAll(func(flag *Flag) {
   380  		format := "  -%s=%s: %s\n"
   381  		if _, ok := flag.Value.(*stringValue); ok {
   382  			// put quotes on the value
   383  			format = "  -%s=%q: %s\n"
   384  		}
   385  		fmt.Fprintf(f.out(), format, flag.Name, flag.DefValue, flag.Usage)
   386  	})
   387  }
   388  
   389  // PrintDefaults prints to standard error the default values of all defined command-line flags.
   390  func PrintDefaults() {
   391  	CommandLine.PrintDefaults()
   392  }
   393  
   394  // defaultUsage is the default function to print a usage message.
   395  func defaultUsage(f *FlagSet) {
   396  	if f.name == "" {
   397  		fmt.Fprintf(f.out(), "Usage:\n")
   398  	} else {
   399  		fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
   400  	}
   401  	f.PrintDefaults()
   402  }
   403  
   404  // NOTE: Usage is not just defaultUsage(CommandLine)
   405  // because it serves (via godoc flag Usage) as the example
   406  // for how to write your own usage function.
   407  
   408  // Usage prints to standard error a usage message documenting all defined command-line flags.
   409  // It is called when an error occurs while parsing flags.
   410  // The function is a variable that may be changed to point to a custom function.
   411  var Usage = func() {
   412  	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
   413  	PrintDefaults()
   414  }
   415  
   416  // NFlag returns the number of flags that have been set.
   417  func (f *FlagSet) NFlag() int { return len(f.actual) }
   418  
   419  // NFlag returns the number of command-line flags that have been set.
   420  func NFlag() int { return len(CommandLine.actual) }
   421  
   422  // Arg returns the i'th argument.  Arg(0) is the first remaining argument
   423  // after flags have been processed.
   424  func (f *FlagSet) Arg(i int) string {
   425  	if i < 0 || i >= len(f.args) {
   426  		return ""
   427  	}
   428  	return f.args[i]
   429  }
   430  
   431  // Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
   432  // after flags have been processed.
   433  func Arg(i int) string {
   434  	return CommandLine.Arg(i)
   435  }
   436  
   437  // NArg is the number of arguments remaining after flags have been processed.
   438  func (f *FlagSet) NArg() int { return len(f.args) }
   439  
   440  // NArg is the number of arguments remaining after flags have been processed.
   441  func NArg() int { return len(CommandLine.args) }
   442  
   443  // Args returns the non-flag arguments.
   444  func (f *FlagSet) Args() []string { return f.args }
   445  
   446  // Args returns the non-flag command-line arguments.
   447  func Args() []string { return CommandLine.args }
   448  
   449  // BoolVar defines a bool flag with specified name, default value, and usage string.
   450  // The argument p points to a bool variable in which to store the value of the flag.
   451  func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
   452  	f.Var(newBoolValue(value, p), name, usage)
   453  }
   454  
   455  // BoolVar defines a bool flag with specified name, default value, and usage string.
   456  // The argument p points to a bool variable in which to store the value of the flag.
   457  func BoolVar(p *bool, name string, value bool, usage string) {
   458  	CommandLine.Var(newBoolValue(value, p), name, usage)
   459  }
   460  
   461  // Bool defines a bool flag with specified name, default value, and usage string.
   462  // The return value is the address of a bool variable that stores the value of the flag.
   463  func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
   464  	p := new(bool)
   465  	f.BoolVar(p, name, value, usage)
   466  	return p
   467  }
   468  
   469  // Bool defines a bool flag with specified name, default value, and usage string.
   470  // The return value is the address of a bool variable that stores the value of the flag.
   471  func Bool(name string, value bool, usage string) *bool {
   472  	return CommandLine.Bool(name, value, usage)
   473  }
   474  
   475  // IntVar defines an int flag with specified name, default value, and usage string.
   476  // The argument p points to an int variable in which to store the value of the flag.
   477  func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
   478  	f.Var(newIntValue(value, p), name, usage)
   479  }
   480  
   481  // IntVar defines an int flag with specified name, default value, and usage string.
   482  // The argument p points to an int variable in which to store the value of the flag.
   483  func IntVar(p *int, name string, value int, usage string) {
   484  	CommandLine.Var(newIntValue(value, p), name, usage)
   485  }
   486  
   487  // Int defines an int flag with specified name, default value, and usage string.
   488  // The return value is the address of an int variable that stores the value of the flag.
   489  func (f *FlagSet) Int(name string, value int, usage string) *int {
   490  	p := new(int)
   491  	f.IntVar(p, name, value, usage)
   492  	return p
   493  }
   494  
   495  // Int defines an int flag with specified name, default value, and usage string.
   496  // The return value is the address of an int variable that stores the value of the flag.
   497  func Int(name string, value int, usage string) *int {
   498  	return CommandLine.Int(name, value, usage)
   499  }
   500  
   501  // Int64Var defines an int64 flag with specified name, default value, and usage string.
   502  // The argument p points to an int64 variable in which to store the value of the flag.
   503  func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {
   504  	f.Var(newInt64Value(value, p), name, usage)
   505  }
   506  
   507  // Int64Var defines an int64 flag with specified name, default value, and usage string.
   508  // The argument p points to an int64 variable in which to store the value of the flag.
   509  func Int64Var(p *int64, name string, value int64, usage string) {
   510  	CommandLine.Var(newInt64Value(value, p), name, usage)
   511  }
   512  
   513  // Int64 defines an int64 flag with specified name, default value, and usage string.
   514  // The return value is the address of an int64 variable that stores the value of the flag.
   515  func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
   516  	p := new(int64)
   517  	f.Int64Var(p, name, value, usage)
   518  	return p
   519  }
   520  
   521  // Int64 defines an int64 flag with specified name, default value, and usage string.
   522  // The return value is the address of an int64 variable that stores the value of the flag.
   523  func Int64(name string, value int64, usage string) *int64 {
   524  	return CommandLine.Int64(name, value, usage)
   525  }
   526  
   527  // UintVar defines a uint flag with specified name, default value, and usage string.
   528  // The argument p points to a uint variable in which to store the value of the flag.
   529  func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
   530  	f.Var(newUintValue(value, p), name, usage)
   531  }
   532  
   533  // UintVar defines a uint flag with specified name, default value, and usage string.
   534  // The argument p points to a uint  variable in which to store the value of the flag.
   535  func UintVar(p *uint, name string, value uint, usage string) {
   536  	CommandLine.Var(newUintValue(value, p), name, usage)
   537  }
   538  
   539  // Uint defines a uint flag with specified name, default value, and usage string.
   540  // The return value is the address of a uint  variable that stores the value of the flag.
   541  func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
   542  	p := new(uint)
   543  	f.UintVar(p, name, value, usage)
   544  	return p
   545  }
   546  
   547  // Uint defines a uint flag with specified name, default value, and usage string.
   548  // The return value is the address of a uint  variable that stores the value of the flag.
   549  func Uint(name string, value uint, usage string) *uint {
   550  	return CommandLine.Uint(name, value, usage)
   551  }
   552  
   553  // Uint64Var defines a uint64 flag with specified name, default value, and usage string.
   554  // The argument p points to a uint64 variable in which to store the value of the flag.
   555  func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
   556  	f.Var(newUint64Value(value, p), name, usage)
   557  }
   558  
   559  // Uint64Var defines a uint64 flag with specified name, default value, and usage string.
   560  // The argument p points to a uint64 variable in which to store the value of the flag.
   561  func Uint64Var(p *uint64, name string, value uint64, usage string) {
   562  	CommandLine.Var(newUint64Value(value, p), name, usage)
   563  }
   564  
   565  // Uint64 defines a uint64 flag with specified name, default value, and usage string.
   566  // The return value is the address of a uint64 variable that stores the value of the flag.
   567  func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
   568  	p := new(uint64)
   569  	f.Uint64Var(p, name, value, usage)
   570  	return p
   571  }
   572  
   573  // Uint64 defines a uint64 flag with specified name, default value, and usage string.
   574  // The return value is the address of a uint64 variable that stores the value of the flag.
   575  func Uint64(name string, value uint64, usage string) *uint64 {
   576  	return CommandLine.Uint64(name, value, usage)
   577  }
   578  
   579  // StringVar defines a string flag with specified name, default value, and usage string.
   580  // The argument p points to a string variable in which to store the value of the flag.
   581  func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
   582  	f.Var(newStringValue(value, p), name, usage)
   583  }
   584  
   585  // StringVar defines a string flag with specified name, default value, and usage string.
   586  // The argument p points to a string variable in which to store the value of the flag.
   587  func StringVar(p *string, name string, value string, usage string) {
   588  	CommandLine.Var(newStringValue(value, p), name, usage)
   589  }
   590  
   591  // String defines a string flag with specified name, default value, and usage string.
   592  // The return value is the address of a string variable that stores the value of the flag.
   593  func (f *FlagSet) String(name string, value string, usage string) *string {
   594  	p := new(string)
   595  	f.StringVar(p, name, value, usage)
   596  	return p
   597  }
   598  
   599  // String defines a string flag with specified name, default value, and usage string.
   600  // The return value is the address of a string variable that stores the value of the flag.
   601  func String(name string, value string, usage string) *string {
   602  	return CommandLine.String(name, value, usage)
   603  }
   604  
   605  // Float64Var defines a float64 flag with specified name, default value, and usage string.
   606  // The argument p points to a float64 variable in which to store the value of the flag.
   607  func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) {
   608  	f.Var(newFloat64Value(value, p), name, usage)
   609  }
   610  
   611  // Float64Var defines a float64 flag with specified name, default value, and usage string.
   612  // The argument p points to a float64 variable in which to store the value of the flag.
   613  func Float64Var(p *float64, name string, value float64, usage string) {
   614  	CommandLine.Var(newFloat64Value(value, p), name, usage)
   615  }
   616  
   617  // Float64 defines a float64 flag with specified name, default value, and usage string.
   618  // The return value is the address of a float64 variable that stores the value of the flag.
   619  func (f *FlagSet) Float64(name string, value float64, usage string) *float64 {
   620  	p := new(float64)
   621  	f.Float64Var(p, name, value, usage)
   622  	return p
   623  }
   624  
   625  // Float64 defines a float64 flag with specified name, default value, and usage string.
   626  // The return value is the address of a float64 variable that stores the value of the flag.
   627  func Float64(name string, value float64, usage string) *float64 {
   628  	return CommandLine.Float64(name, value, usage)
   629  }
   630  
   631  // DurationVar defines a time.Duration flag with specified name, default value, and usage string.
   632  // The argument p points to a time.Duration variable in which to store the value of the flag.
   633  // The flag accepts a value acceptable to time.ParseDuration.
   634  func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
   635  	f.Var(newDurationValue(value, p), name, usage)
   636  }
   637  
   638  // DurationVar defines a time.Duration flag with specified name, default value, and usage string.
   639  // The argument p points to a time.Duration variable in which to store the value of the flag.
   640  // The flag accepts a value acceptable to time.ParseDuration.
   641  func DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
   642  	CommandLine.Var(newDurationValue(value, p), name, usage)
   643  }
   644  
   645  // Duration defines a time.Duration flag with specified name, default value, and usage string.
   646  // The return value is the address of a time.Duration variable that stores the value of the flag.
   647  // The flag accepts a value acceptable to time.ParseDuration.
   648  func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration {
   649  	p := new(time.Duration)
   650  	f.DurationVar(p, name, value, usage)
   651  	return p
   652  }
   653  
   654  // Duration defines a time.Duration flag with specified name, default value, and usage string.
   655  // The return value is the address of a time.Duration variable that stores the value of the flag.
   656  // The flag accepts a value acceptable to time.ParseDuration.
   657  func Duration(name string, value time.Duration, usage string) *time.Duration {
   658  	return CommandLine.Duration(name, value, usage)
   659  }
   660  
   661  // Var defines a flag with the specified name and usage string. The type and
   662  // value of the flag are represented by the first argument, of type Value, which
   663  // typically holds a user-defined implementation of Value. For instance, the
   664  // caller could create a flag that turns a comma-separated string into a slice
   665  // of strings by giving the slice the methods of Value; in particular, Set would
   666  // decompose the comma-separated string into the slice.
   667  func (f *FlagSet) Var(value Value, name string, usage string) {
   668  	// Remember the default value as a string; it won't change.
   669  	flag := &Flag{name, usage, value, value.String()}
   670  	_, alreadythere := f.formal[name]
   671  	if alreadythere {
   672  		var msg string
   673  		if f.name == "" {
   674  			msg = fmt.Sprintf("flag redefined: %s", name)
   675  		} else {
   676  			msg = fmt.Sprintf("%s flag redefined: %s", f.name, name)
   677  		}
   678  		fmt.Fprintln(f.out(), msg)
   679  		panic(msg) // Happens only if flags are declared with identical names
   680  	}
   681  	if f.formal == nil {
   682  		f.formal = make(map[string]*Flag)
   683  	}
   684  	f.formal[name] = flag
   685  }
   686  
   687  // Var defines a flag with the specified name and usage string. The type and
   688  // value of the flag are represented by the first argument, of type Value, which
   689  // typically holds a user-defined implementation of Value. For instance, the
   690  // caller could create a flag that turns a comma-separated string into a slice
   691  // of strings by giving the slice the methods of Value; in particular, Set would
   692  // decompose the comma-separated string into the slice.
   693  func Var(value Value, name string, usage string) {
   694  	CommandLine.Var(value, name, usage)
   695  }
   696  
   697  // failf prints to standard error a formatted error and usage message and
   698  // returns the error.
   699  func (f *FlagSet) failf(format string, a ...interface{}) error {
   700  	err := fmt.Errorf(format, a...)
   701  	fmt.Fprintln(f.out(), err)
   702  	f.usage()
   703  	return err
   704  }
   705  
   706  // usage calls the Usage method for the flag set if one is specified,
   707  // or the appropriate default usage function otherwise.
   708  func (f *FlagSet) usage() {
   709  	if f.Usage == nil {
   710  		if f == CommandLine {
   711  			Usage()
   712  		} else {
   713  			defaultUsage(f)
   714  		}
   715  	} else {
   716  		f.Usage()
   717  	}
   718  }
   719  
   720  // parseOne parses one flag. It reports whether a flag was seen.
   721  func (f *FlagSet) parseOne() (bool, error) {
   722  	if len(f.args) == 0 {
   723  		return false, nil
   724  	}
   725  	s := f.args[0]
   726  	if len(s) == 0 || s[0] != '-' || len(s) == 1 {
   727  		return false, nil
   728  	}
   729  	num_minuses := 1
   730  	if s[1] == '-' {
   731  		num_minuses++
   732  		if len(s) == 2 { // "--" terminates the flags
   733  			f.args = f.args[1:]
   734  			return false, nil
   735  		}
   736  	}
   737  	name := s[num_minuses:]
   738  	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
   739  		return false, f.failf("bad flag syntax: %s", s)
   740  	}
   741  
   742  	// it's a flag. does it have an argument?
   743  	f.args = f.args[1:]
   744  	has_value := false
   745  	value := ""
   746  	for i := 1; i < len(name); i++ { // equals cannot be first
   747  		if name[i] == '=' {
   748  			value = name[i+1:]
   749  			has_value = true
   750  			name = name[0:i]
   751  			break
   752  		}
   753  	}
   754  	m := f.formal
   755  	flag, alreadythere := m[name] // BUG
   756  	if !alreadythere {
   757  		if name == "help" || name == "h" { // special case for nice help message.
   758  			f.usage()
   759  			return false, ErrHelp
   760  		}
   761  		return false, f.failf("flag provided but not defined: -%s", name)
   762  	}
   763  
   764  	if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
   765  		if has_value {
   766  			if err := fv.Set(value); err != nil {
   767  				return false, f.failf("invalid boolean value %q for -%s: %v", value, name, err)
   768  			}
   769  		} else {
   770  			fv.Set("true")
   771  		}
   772  	} else {
   773  		// It must have a value, which might be the next argument.
   774  		if !has_value && len(f.args) > 0 {
   775  			// value is the next arg
   776  			has_value = true
   777  			value, f.args = f.args[0], f.args[1:]
   778  		}
   779  		if !has_value {
   780  			return false, f.failf("flag needs an argument: -%s", name)
   781  		}
   782  		if err := flag.Value.Set(value); err != nil {
   783  			return false, f.failf("invalid value %q for flag -%s: %v", value, name, err)
   784  		}
   785  	}
   786  	if f.actual == nil {
   787  		f.actual = make(map[string]*Flag)
   788  	}
   789  	f.actual[name] = flag
   790  	return true, nil
   791  }
   792  
   793  // Parse parses flag definitions from the argument list, which should not
   794  // include the command name.  Must be called after all flags in the FlagSet
   795  // are defined and before flags are accessed by the program.
   796  // The return value will be ErrHelp if -help or -h were set but not defined.
   797  func (f *FlagSet) Parse(arguments []string) error {
   798  	f.parsed = true
   799  	f.args = arguments
   800  	for {
   801  		seen, err := f.parseOne()
   802  		if seen {
   803  			continue
   804  		}
   805  		if err == nil {
   806  			break
   807  		}
   808  		switch f.errorHandling {
   809  		case ContinueOnError:
   810  			return err
   811  		case ExitOnError:
   812  			os.Exit(2)
   813  		case PanicOnError:
   814  			panic(err)
   815  		}
   816  	}
   817  	return nil
   818  }
   819  
   820  // Parsed reports whether f.Parse has been called.
   821  func (f *FlagSet) Parsed() bool {
   822  	return f.parsed
   823  }
   824  
   825  // Parse parses the command-line flags from os.Args[1:].  Must be called
   826  // after all flags are defined and before flags are accessed by the program.
   827  func Parse() {
   828  	// Ignore errors; CommandLine is set for ExitOnError.
   829  	CommandLine.Parse(os.Args[1:])
   830  }
   831  
   832  // Parsed returns true if the command-line flags have been parsed.
   833  func Parsed() bool {
   834  	return CommandLine.Parsed()
   835  }
   836  
   837  // CommandLine is the default set of command-line flags, parsed from os.Args.
   838  // The top-level functions such as BoolVar, Arg, and so on are wrappers for the
   839  // methods of CommandLine.
   840  var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
   841  
   842  // NewFlagSet returns a new, empty flag set with the specified name and
   843  // error handling property.
   844  func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
   845  	f := &FlagSet{
   846  		name:          name,
   847  		errorHandling: errorHandling,
   848  	}
   849  	return f
   850  }
   851  
   852  // Init sets the name and error handling property for a flag set.
   853  // By default, the zero FlagSet uses an empty name and the
   854  // ContinueOnError error handling policy.
   855  func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
   856  	f.name = name
   857  	f.errorHandling = errorHandling
   858  }