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