github.com/fcwu/docker@v1.4.2-0.20150115145920-2a69ca89f0df/pkg/mflag/flag.go (about)

     1  // Copyright 2014 The Docker & 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, -f or --flagname, stored in the pointer ip, with type *int.
    13  		import "flag /github.com/docker/docker/pkg/mflag"
    14  		var ip = flag.Int([]string{"f", "-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  			// -flaghidden will work, but will be hidden from the usage
    19  			flag.IntVar(&flagvar, []string{"f", "#flaghidden", "-flagname"}, 1234, "help message for flagname")
    20  		}
    21  	Or you can create custom flags that satisfy the Value interface (with
    22  	pointer receivers) and couple them to flag parsing by
    23  		flag.Var(&flagVal, []string{"name"}, "help message for flagname")
    24  	For such flags, the default value is just the initial value of the variable.
    25  
    26  	You can also add "deprecated" flags, they are still usable, but are not shown
    27  	in the usage and will display a warning when you try to use them:
    28  		var ip = flag.Int([]string{"#f", "#flagname", "-flagname2"}, 1234, "help message for flagname")
    29  	this will display: `Warning: '--flagname' is deprecated, it will be replaced by '--flagname2' soon. See usage.` and
    30  		var ip = flag.Int([]string{"f", "#flagname"}, 1234, "help message for flagname")
    31  	will display: `Warning: '-f' is deprecated, it will be removed soon. See usage.`
    32  
    33  	You can also group one letter flags, bif you declare
    34  		var v = flag.Bool([]string{"v", "-verbose"}, false, "help message for verbose")
    35  		var s = flag.Bool([]string{"s", "-slow"}, false, "help message for slow")
    36  	you will be able to use the -vs or -sv
    37  
    38  	After all flags are defined, call
    39  		flag.Parse()
    40  	to parse the command line into the defined flags.
    41  
    42  	Flags may then be used directly. If you're using the flags themselves,
    43  	they are all pointers; if you bind to variables, they're values.
    44  		fmt.Println("ip has value ", *ip)
    45  		fmt.Println("flagvar has value ", flagvar)
    46  
    47  	After parsing, the arguments after the flag are available as the
    48  	slice flag.Args() or individually as flag.Arg(i).
    49  	The arguments are indexed from 0 through flag.NArg()-1.
    50  
    51  	Command line flag syntax:
    52  		-flag
    53  		-flag=x
    54  		-flag="x"
    55  		-flag='x'
    56  		-flag x  // non-boolean flags only
    57  	One or two minus signs may be used; they are equivalent.
    58  	The last form is not permitted for boolean flags because the
    59  	meaning of the command
    60  		cmd -x *
    61  	will change if there is a file called 0, false, etc.  You must
    62  	use the -flag=false form to turn off a boolean flag.
    63  
    64  	Flag parsing stops just before the first non-flag argument
    65  	("-" is a non-flag argument) or after the terminator "--".
    66  
    67  	Integer flags accept 1234, 0664, 0x1234 and may be negative.
    68  	Boolean flags may be 1, 0, t, f, true, false, TRUE, FALSE, True, False.
    69  	Duration flags accept any input valid for time.ParseDuration.
    70  
    71  	The default set of command-line flags is controlled by
    72  	top-level functions.  The FlagSet type allows one to define
    73  	independent sets of flags, such as to implement subcommands
    74  	in a command-line interface. The methods of FlagSet are
    75  	analogous to the top-level functions for the command-line
    76  	flag set.
    77  */
    78  package mflag
    79  
    80  import (
    81  	"errors"
    82  	"fmt"
    83  	"io"
    84  	"os"
    85  	"sort"
    86  	"strconv"
    87  	"strings"
    88  	"text/tabwriter"
    89  	"time"
    90  )
    91  
    92  // ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
    93  var ErrHelp = errors.New("flag: help requested")
    94  
    95  // ErrRetry is the error returned if you need to try letter by letter
    96  var ErrRetry = errors.New("flag: retry")
    97  
    98  // -- bool Value
    99  type boolValue bool
   100  
   101  func newBoolValue(val bool, p *bool) *boolValue {
   102  	*p = val
   103  	return (*boolValue)(p)
   104  }
   105  
   106  func (b *boolValue) Set(s string) error {
   107  	v, err := strconv.ParseBool(s)
   108  	*b = boolValue(v)
   109  	return err
   110  }
   111  
   112  func (b *boolValue) Get() interface{} { return bool(*b) }
   113  
   114  func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) }
   115  
   116  func (b *boolValue) IsBoolFlag() bool { return true }
   117  
   118  // optional interface to indicate boolean flags that can be
   119  // supplied without "=value" text
   120  type boolFlag interface {
   121  	Value
   122  	IsBoolFlag() bool
   123  }
   124  
   125  // -- int Value
   126  type intValue int
   127  
   128  func newIntValue(val int, p *int) *intValue {
   129  	*p = val
   130  	return (*intValue)(p)
   131  }
   132  
   133  func (i *intValue) Set(s string) error {
   134  	v, err := strconv.ParseInt(s, 0, 64)
   135  	*i = intValue(v)
   136  	return err
   137  }
   138  
   139  func (i *intValue) Get() interface{} { return int(*i) }
   140  
   141  func (i *intValue) String() string { return fmt.Sprintf("%v", *i) }
   142  
   143  // -- int64 Value
   144  type int64Value int64
   145  
   146  func newInt64Value(val int64, p *int64) *int64Value {
   147  	*p = val
   148  	return (*int64Value)(p)
   149  }
   150  
   151  func (i *int64Value) Set(s string) error {
   152  	v, err := strconv.ParseInt(s, 0, 64)
   153  	*i = int64Value(v)
   154  	return err
   155  }
   156  
   157  func (i *int64Value) Get() interface{} { return int64(*i) }
   158  
   159  func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) }
   160  
   161  // -- uint Value
   162  type uintValue uint
   163  
   164  func newUintValue(val uint, p *uint) *uintValue {
   165  	*p = val
   166  	return (*uintValue)(p)
   167  }
   168  
   169  func (i *uintValue) Set(s string) error {
   170  	v, err := strconv.ParseUint(s, 0, 64)
   171  	*i = uintValue(v)
   172  	return err
   173  }
   174  
   175  func (i *uintValue) Get() interface{} { return uint(*i) }
   176  
   177  func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
   178  
   179  // -- uint64 Value
   180  type uint64Value uint64
   181  
   182  func newUint64Value(val uint64, p *uint64) *uint64Value {
   183  	*p = val
   184  	return (*uint64Value)(p)
   185  }
   186  
   187  func (i *uint64Value) Set(s string) error {
   188  	v, err := strconv.ParseUint(s, 0, 64)
   189  	*i = uint64Value(v)
   190  	return err
   191  }
   192  
   193  func (i *uint64Value) Get() interface{} { return uint64(*i) }
   194  
   195  func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
   196  
   197  // -- string Value
   198  type stringValue string
   199  
   200  func newStringValue(val string, p *string) *stringValue {
   201  	*p = val
   202  	return (*stringValue)(p)
   203  }
   204  
   205  func (s *stringValue) Set(val string) error {
   206  	*s = stringValue(val)
   207  	return nil
   208  }
   209  
   210  func (s *stringValue) Get() interface{} { return string(*s) }
   211  
   212  func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) }
   213  
   214  // -- float64 Value
   215  type float64Value float64
   216  
   217  func newFloat64Value(val float64, p *float64) *float64Value {
   218  	*p = val
   219  	return (*float64Value)(p)
   220  }
   221  
   222  func (f *float64Value) Set(s string) error {
   223  	v, err := strconv.ParseFloat(s, 64)
   224  	*f = float64Value(v)
   225  	return err
   226  }
   227  
   228  func (f *float64Value) Get() interface{} { return float64(*f) }
   229  
   230  func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
   231  
   232  // -- time.Duration Value
   233  type durationValue time.Duration
   234  
   235  func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
   236  	*p = val
   237  	return (*durationValue)(p)
   238  }
   239  
   240  func (d *durationValue) Set(s string) error {
   241  	v, err := time.ParseDuration(s)
   242  	*d = durationValue(v)
   243  	return err
   244  }
   245  
   246  func (d *durationValue) Get() interface{} { return time.Duration(*d) }
   247  
   248  func (d *durationValue) String() string { return (*time.Duration)(d).String() }
   249  
   250  // Value is the interface to the dynamic value stored in a flag.
   251  // (The default value is represented as a string.)
   252  //
   253  // If a Value has an IsBoolFlag() bool method returning true,
   254  // the command-line parser makes -name equivalent to -name=true
   255  // rather than using the next command-line argument.
   256  type Value interface {
   257  	String() string
   258  	Set(string) error
   259  }
   260  
   261  // Getter is an interface that allows the contents of a Value to be retrieved.
   262  // It wraps the Value interface, rather than being part of it, because it
   263  // appeared after Go 1 and its compatibility rules. All Value types provided
   264  // by this package satisfy the Getter interface.
   265  type Getter interface {
   266  	Value
   267  	Get() interface{}
   268  }
   269  
   270  // ErrorHandling defines how to handle flag parsing errors.
   271  type ErrorHandling int
   272  
   273  const (
   274  	ContinueOnError ErrorHandling = iota
   275  	ExitOnError
   276  	PanicOnError
   277  )
   278  
   279  // A FlagSet represents a set of defined flags.  The zero value of a FlagSet
   280  // has no name and has ContinueOnError error handling.
   281  type FlagSet struct {
   282  	// Usage is the function called when an error occurs while parsing flags.
   283  	// The field is a function (not a method) that may be changed to point to
   284  	// a custom error handler.
   285  	Usage func()
   286  
   287  	name             string
   288  	parsed           bool
   289  	actual           map[string]*Flag
   290  	formal           map[string]*Flag
   291  	args             []string // arguments after flags
   292  	errorHandling    ErrorHandling
   293  	output           io.Writer // nil means stderr; use Out() accessor
   294  	nArgRequirements []nArgRequirement
   295  }
   296  
   297  // A Flag represents the state of a flag.
   298  type Flag struct {
   299  	Names    []string // name as it appears on command line
   300  	Usage    string   // help message
   301  	Value    Value    // value as set
   302  	DefValue string   // default value (as text); for usage message
   303  }
   304  
   305  type flagSlice []string
   306  
   307  func (p flagSlice) Len() int { return len(p) }
   308  func (p flagSlice) Less(i, j int) bool {
   309  	pi, pj := strings.TrimPrefix(p[i], "-"), strings.TrimPrefix(p[j], "-")
   310  	lpi, lpj := strings.ToLower(pi), strings.ToLower(pj)
   311  	if lpi != lpj {
   312  		return lpi < lpj
   313  	}
   314  	return pi < pj
   315  }
   316  func (p flagSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
   317  
   318  // sortFlags returns the flags as a slice in lexicographical sorted order.
   319  func sortFlags(flags map[string]*Flag) []*Flag {
   320  	var list flagSlice
   321  
   322  	// The sorted list is based on the first name, when flag map might use the other names.
   323  	nameMap := make(map[string]string)
   324  
   325  	for n, f := range flags {
   326  		fName := strings.TrimPrefix(f.Names[0], "#")
   327  		nameMap[fName] = n
   328  		if len(f.Names) == 1 {
   329  			list = append(list, fName)
   330  			continue
   331  		}
   332  
   333  		found := false
   334  		for _, name := range list {
   335  			if name == fName {
   336  				found = true
   337  				break
   338  			}
   339  		}
   340  		if !found {
   341  			list = append(list, fName)
   342  		}
   343  	}
   344  	sort.Sort(list)
   345  	result := make([]*Flag, len(list))
   346  	for i, name := range list {
   347  		result[i] = flags[nameMap[name]]
   348  	}
   349  	return result
   350  }
   351  
   352  // Name returns the name of the FlagSet.
   353  func (f *FlagSet) Name() string {
   354  	return f.name
   355  }
   356  
   357  // Out returns the destination for usage and error messages.
   358  func (f *FlagSet) Out() io.Writer {
   359  	if f.output == nil {
   360  		return os.Stderr
   361  	}
   362  	return f.output
   363  }
   364  
   365  // SetOutput sets the destination for usage and error messages.
   366  // If output is nil, os.Stderr is used.
   367  func (f *FlagSet) SetOutput(output io.Writer) {
   368  	f.output = output
   369  }
   370  
   371  // VisitAll visits the flags in lexicographical order, calling fn for each.
   372  // It visits all flags, even those not set.
   373  func (f *FlagSet) VisitAll(fn func(*Flag)) {
   374  	for _, flag := range sortFlags(f.formal) {
   375  		fn(flag)
   376  	}
   377  }
   378  
   379  // VisitAll visits the command-line flags in lexicographical order, calling
   380  // fn for each.  It visits all flags, even those not set.
   381  func VisitAll(fn func(*Flag)) {
   382  	CommandLine.VisitAll(fn)
   383  }
   384  
   385  // Visit visits the flags in lexicographical order, calling fn for each.
   386  // It visits only those flags that have been set.
   387  func (f *FlagSet) Visit(fn func(*Flag)) {
   388  	for _, flag := range sortFlags(f.actual) {
   389  		fn(flag)
   390  	}
   391  }
   392  
   393  // Visit visits the command-line flags in lexicographical order, calling fn
   394  // for each.  It visits only those flags that have been set.
   395  func Visit(fn func(*Flag)) {
   396  	CommandLine.Visit(fn)
   397  }
   398  
   399  // Lookup returns the Flag structure of the named flag, returning nil if none exists.
   400  func (f *FlagSet) Lookup(name string) *Flag {
   401  	return f.formal[name]
   402  }
   403  
   404  // Indicates whether the specified flag was specified at all on the cmd line
   405  func (f *FlagSet) IsSet(name string) bool {
   406  	return f.actual[name] != nil
   407  }
   408  
   409  // Lookup returns the Flag structure of the named command-line flag,
   410  // returning nil if none exists.
   411  func Lookup(name string) *Flag {
   412  	return CommandLine.formal[name]
   413  }
   414  
   415  // Indicates whether the specified flag was specified at all on the cmd line
   416  func IsSet(name string) bool {
   417  	return CommandLine.IsSet(name)
   418  }
   419  
   420  type nArgRequirementType int
   421  
   422  // Indicator used to pass to BadArgs function
   423  const (
   424  	Exact nArgRequirementType = iota
   425  	Max
   426  	Min
   427  )
   428  
   429  type nArgRequirement struct {
   430  	Type nArgRequirementType
   431  	N    int
   432  }
   433  
   434  // Require adds a requirement about the number of arguments for the FlagSet.
   435  // The first parameter can be Exact, Max, or Min to respectively specify the exact,
   436  // the maximum, or the minimal number of arguments required.
   437  // The actual check is done in FlagSet.CheckArgs().
   438  func (f *FlagSet) Require(nArgRequirementType nArgRequirementType, nArg int) {
   439  	f.nArgRequirements = append(f.nArgRequirements, nArgRequirement{nArgRequirementType, nArg})
   440  }
   441  
   442  // CheckArgs uses the requirements set by FlagSet.Require() to validate
   443  // the number of arguments. If the requirements are not met,
   444  // an error message string is returned.
   445  func (f *FlagSet) CheckArgs() (message string) {
   446  	for _, req := range f.nArgRequirements {
   447  		var arguments string
   448  		if req.N == 1 {
   449  			arguments = "1 argument"
   450  		} else {
   451  			arguments = fmt.Sprintf("%d arguments", req.N)
   452  		}
   453  
   454  		str := func(kind string) string {
   455  			return fmt.Sprintf("%q requires %s%s", f.name, kind, arguments)
   456  		}
   457  
   458  		switch req.Type {
   459  		case Exact:
   460  			if f.NArg() != req.N {
   461  				return str("")
   462  			}
   463  		case Max:
   464  			if f.NArg() > req.N {
   465  				return str("a maximum of ")
   466  			}
   467  		case Min:
   468  			if f.NArg() < req.N {
   469  				return str("a minimum of ")
   470  			}
   471  		}
   472  	}
   473  	return ""
   474  }
   475  
   476  // Set sets the value of the named flag.
   477  func (f *FlagSet) Set(name, value string) error {
   478  	flag, ok := f.formal[name]
   479  	if !ok {
   480  		return fmt.Errorf("no such flag -%v", name)
   481  	}
   482  	err := flag.Value.Set(value)
   483  	if err != nil {
   484  		return err
   485  	}
   486  	if f.actual == nil {
   487  		f.actual = make(map[string]*Flag)
   488  	}
   489  	f.actual[name] = flag
   490  	return nil
   491  }
   492  
   493  // Set sets the value of the named command-line flag.
   494  func Set(name, value string) error {
   495  	return CommandLine.Set(name, value)
   496  }
   497  
   498  // PrintDefaults prints, to standard error unless configured
   499  // otherwise, the default values of all defined flags in the set.
   500  func (f *FlagSet) PrintDefaults() {
   501  	writer := tabwriter.NewWriter(f.Out(), 20, 1, 3, ' ', 0)
   502  	f.VisitAll(func(flag *Flag) {
   503  		format := "  -%s=%s"
   504  		if _, ok := flag.Value.(*stringValue); ok {
   505  			// put quotes on the value
   506  			format = "  -%s=%q"
   507  		}
   508  		names := []string{}
   509  		for _, name := range flag.Names {
   510  			if name[0] != '#' {
   511  				names = append(names, name)
   512  			}
   513  		}
   514  		if len(names) > 0 {
   515  			fmt.Fprintf(writer, format, strings.Join(names, ", -"), flag.DefValue)
   516  			for i, line := range strings.Split(flag.Usage, "\n") {
   517  				if i != 0 {
   518  					line = "  " + line
   519  				}
   520  				fmt.Fprintln(writer, "\t", line)
   521  			}
   522  		}
   523  	})
   524  	writer.Flush()
   525  }
   526  
   527  // PrintDefaults prints to standard error the default values of all defined command-line flags.
   528  func PrintDefaults() {
   529  	CommandLine.PrintDefaults()
   530  }
   531  
   532  // defaultUsage is the default function to print a usage message.
   533  func defaultUsage(f *FlagSet) {
   534  	if f.name == "" {
   535  		fmt.Fprintf(f.Out(), "Usage:\n")
   536  	} else {
   537  		fmt.Fprintf(f.Out(), "Usage of %s:\n", f.name)
   538  	}
   539  	f.PrintDefaults()
   540  }
   541  
   542  // NOTE: Usage is not just defaultUsage(CommandLine)
   543  // because it serves (via godoc flag Usage) as the example
   544  // for how to write your own usage function.
   545  
   546  // Usage prints to standard error a usage message documenting all defined command-line flags.
   547  // The function is a variable that may be changed to point to a custom function.
   548  var Usage = func() {
   549  	fmt.Fprintf(CommandLine.output, "Usage of %s:\n", os.Args[0])
   550  	PrintDefaults()
   551  }
   552  
   553  // FlagCount returns the number of flags that have been defined.
   554  func (f *FlagSet) FlagCount() int { return len(sortFlags(f.formal)) }
   555  
   556  // FlagCountUndeprecated returns the number of undeprecated flags that have been defined.
   557  func (f *FlagSet) FlagCountUndeprecated() int {
   558  	count := 0
   559  	for _, flag := range sortFlags(f.formal) {
   560  		for _, name := range flag.Names {
   561  			if name[0] != '#' {
   562  				count++
   563  				break
   564  			}
   565  		}
   566  	}
   567  	return count
   568  }
   569  
   570  // NFlag returns the number of flags that have been set.
   571  func (f *FlagSet) NFlag() int { return len(f.actual) }
   572  
   573  // NFlag returns the number of command-line flags that have been set.
   574  func NFlag() int { return len(CommandLine.actual) }
   575  
   576  // Arg returns the i'th argument.  Arg(0) is the first remaining argument
   577  // after flags have been processed.
   578  func (f *FlagSet) Arg(i int) string {
   579  	if i < 0 || i >= len(f.args) {
   580  		return ""
   581  	}
   582  	return f.args[i]
   583  }
   584  
   585  // Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
   586  // after flags have been processed.
   587  func Arg(i int) string {
   588  	return CommandLine.Arg(i)
   589  }
   590  
   591  // NArg is the number of arguments remaining after flags have been processed.
   592  func (f *FlagSet) NArg() int { return len(f.args) }
   593  
   594  // NArg is the number of arguments remaining after flags have been processed.
   595  func NArg() int { return len(CommandLine.args) }
   596  
   597  // Args returns the non-flag arguments.
   598  func (f *FlagSet) Args() []string { return f.args }
   599  
   600  // Args returns the non-flag command-line arguments.
   601  func Args() []string { return CommandLine.args }
   602  
   603  // BoolVar defines a bool flag with specified name, default value, and usage string.
   604  // The argument p points to a bool variable in which to store the value of the flag.
   605  func (f *FlagSet) BoolVar(p *bool, names []string, value bool, usage string) {
   606  	f.Var(newBoolValue(value, p), names, usage)
   607  }
   608  
   609  // BoolVar defines a bool flag with specified name, default value, and usage string.
   610  // The argument p points to a bool variable in which to store the value of the flag.
   611  func BoolVar(p *bool, names []string, value bool, usage string) {
   612  	CommandLine.Var(newBoolValue(value, p), names, usage)
   613  }
   614  
   615  // Bool defines a bool flag with specified name, default value, and usage string.
   616  // The return value is the address of a bool variable that stores the value of the flag.
   617  func (f *FlagSet) Bool(names []string, value bool, usage string) *bool {
   618  	p := new(bool)
   619  	f.BoolVar(p, names, value, usage)
   620  	return p
   621  }
   622  
   623  // Bool defines a bool flag with specified name, default value, and usage string.
   624  // The return value is the address of a bool variable that stores the value of the flag.
   625  func Bool(names []string, value bool, usage string) *bool {
   626  	return CommandLine.Bool(names, value, usage)
   627  }
   628  
   629  // IntVar defines an int flag with specified name, default value, and usage string.
   630  // The argument p points to an int variable in which to store the value of the flag.
   631  func (f *FlagSet) IntVar(p *int, names []string, value int, usage string) {
   632  	f.Var(newIntValue(value, p), names, usage)
   633  }
   634  
   635  // IntVar defines an int flag with specified name, default value, and usage string.
   636  // The argument p points to an int variable in which to store the value of the flag.
   637  func IntVar(p *int, names []string, value int, usage string) {
   638  	CommandLine.Var(newIntValue(value, p), names, usage)
   639  }
   640  
   641  // Int defines an int flag with specified name, default value, and usage string.
   642  // The return value is the address of an int variable that stores the value of the flag.
   643  func (f *FlagSet) Int(names []string, value int, usage string) *int {
   644  	p := new(int)
   645  	f.IntVar(p, names, value, usage)
   646  	return p
   647  }
   648  
   649  // Int defines an int flag with specified name, default value, and usage string.
   650  // The return value is the address of an int variable that stores the value of the flag.
   651  func Int(names []string, value int, usage string) *int {
   652  	return CommandLine.Int(names, value, usage)
   653  }
   654  
   655  // Int64Var defines an int64 flag with specified name, default value, and usage string.
   656  // The argument p points to an int64 variable in which to store the value of the flag.
   657  func (f *FlagSet) Int64Var(p *int64, names []string, value int64, usage string) {
   658  	f.Var(newInt64Value(value, p), names, usage)
   659  }
   660  
   661  // Int64Var defines an int64 flag with specified name, default value, and usage string.
   662  // The argument p points to an int64 variable in which to store the value of the flag.
   663  func Int64Var(p *int64, names []string, value int64, usage string) {
   664  	CommandLine.Var(newInt64Value(value, p), names, usage)
   665  }
   666  
   667  // Int64 defines an int64 flag with specified name, default value, and usage string.
   668  // The return value is the address of an int64 variable that stores the value of the flag.
   669  func (f *FlagSet) Int64(names []string, value int64, usage string) *int64 {
   670  	p := new(int64)
   671  	f.Int64Var(p, names, value, usage)
   672  	return p
   673  }
   674  
   675  // Int64 defines an int64 flag with specified name, default value, and usage string.
   676  // The return value is the address of an int64 variable that stores the value of the flag.
   677  func Int64(names []string, value int64, usage string) *int64 {
   678  	return CommandLine.Int64(names, value, usage)
   679  }
   680  
   681  // UintVar defines a uint flag with specified name, default value, and usage string.
   682  // The argument p points to a uint variable in which to store the value of the flag.
   683  func (f *FlagSet) UintVar(p *uint, names []string, value uint, usage string) {
   684  	f.Var(newUintValue(value, p), names, usage)
   685  }
   686  
   687  // UintVar defines a uint flag with specified name, default value, and usage string.
   688  // The argument p points to a uint  variable in which to store the value of the flag.
   689  func UintVar(p *uint, names []string, value uint, usage string) {
   690  	CommandLine.Var(newUintValue(value, p), names, usage)
   691  }
   692  
   693  // Uint defines a uint flag with specified name, default value, and usage string.
   694  // The return value is the address of a uint  variable that stores the value of the flag.
   695  func (f *FlagSet) Uint(names []string, value uint, usage string) *uint {
   696  	p := new(uint)
   697  	f.UintVar(p, names, value, usage)
   698  	return p
   699  }
   700  
   701  // Uint defines a uint flag with specified name, default value, and usage string.
   702  // The return value is the address of a uint  variable that stores the value of the flag.
   703  func Uint(names []string, value uint, usage string) *uint {
   704  	return CommandLine.Uint(names, value, usage)
   705  }
   706  
   707  // Uint64Var defines a uint64 flag with specified name, default value, and usage string.
   708  // The argument p points to a uint64 variable in which to store the value of the flag.
   709  func (f *FlagSet) Uint64Var(p *uint64, names []string, value uint64, usage string) {
   710  	f.Var(newUint64Value(value, p), names, usage)
   711  }
   712  
   713  // Uint64Var defines a uint64 flag with specified name, default value, and usage string.
   714  // The argument p points to a uint64 variable in which to store the value of the flag.
   715  func Uint64Var(p *uint64, names []string, value uint64, usage string) {
   716  	CommandLine.Var(newUint64Value(value, p), names, usage)
   717  }
   718  
   719  // Uint64 defines a uint64 flag with specified name, default value, and usage string.
   720  // The return value is the address of a uint64 variable that stores the value of the flag.
   721  func (f *FlagSet) Uint64(names []string, value uint64, usage string) *uint64 {
   722  	p := new(uint64)
   723  	f.Uint64Var(p, names, value, usage)
   724  	return p
   725  }
   726  
   727  // Uint64 defines a uint64 flag with specified name, default value, and usage string.
   728  // The return value is the address of a uint64 variable that stores the value of the flag.
   729  func Uint64(names []string, value uint64, usage string) *uint64 {
   730  	return CommandLine.Uint64(names, value, usage)
   731  }
   732  
   733  // StringVar defines a string flag with specified name, default value, and usage string.
   734  // The argument p points to a string variable in which to store the value of the flag.
   735  func (f *FlagSet) StringVar(p *string, names []string, value string, usage string) {
   736  	f.Var(newStringValue(value, p), names, usage)
   737  }
   738  
   739  // StringVar defines a string flag with specified name, default value, and usage string.
   740  // The argument p points to a string variable in which to store the value of the flag.
   741  func StringVar(p *string, names []string, value string, usage string) {
   742  	CommandLine.Var(newStringValue(value, p), names, usage)
   743  }
   744  
   745  // String defines a string flag with specified name, default value, and usage string.
   746  // The return value is the address of a string variable that stores the value of the flag.
   747  func (f *FlagSet) String(names []string, value string, usage string) *string {
   748  	p := new(string)
   749  	f.StringVar(p, names, value, usage)
   750  	return p
   751  }
   752  
   753  // String defines a string flag with specified name, default value, and usage string.
   754  // The return value is the address of a string variable that stores the value of the flag.
   755  func String(names []string, value string, usage string) *string {
   756  	return CommandLine.String(names, value, usage)
   757  }
   758  
   759  // Float64Var defines a float64 flag with specified name, default value, and usage string.
   760  // The argument p points to a float64 variable in which to store the value of the flag.
   761  func (f *FlagSet) Float64Var(p *float64, names []string, value float64, usage string) {
   762  	f.Var(newFloat64Value(value, p), names, usage)
   763  }
   764  
   765  // Float64Var defines a float64 flag with specified name, default value, and usage string.
   766  // The argument p points to a float64 variable in which to store the value of the flag.
   767  func Float64Var(p *float64, names []string, value float64, usage string) {
   768  	CommandLine.Var(newFloat64Value(value, p), names, usage)
   769  }
   770  
   771  // Float64 defines a float64 flag with specified name, default value, and usage string.
   772  // The return value is the address of a float64 variable that stores the value of the flag.
   773  func (f *FlagSet) Float64(names []string, value float64, usage string) *float64 {
   774  	p := new(float64)
   775  	f.Float64Var(p, names, value, usage)
   776  	return p
   777  }
   778  
   779  // Float64 defines a float64 flag with specified name, default value, and usage string.
   780  // The return value is the address of a float64 variable that stores the value of the flag.
   781  func Float64(names []string, value float64, usage string) *float64 {
   782  	return CommandLine.Float64(names, value, usage)
   783  }
   784  
   785  // DurationVar defines a time.Duration flag with specified name, default value, and usage string.
   786  // The argument p points to a time.Duration variable in which to store the value of the flag.
   787  func (f *FlagSet) DurationVar(p *time.Duration, names []string, value time.Duration, usage string) {
   788  	f.Var(newDurationValue(value, p), names, usage)
   789  }
   790  
   791  // DurationVar defines a time.Duration flag with specified name, default value, and usage string.
   792  // The argument p points to a time.Duration variable in which to store the value of the flag.
   793  func DurationVar(p *time.Duration, names []string, value time.Duration, usage string) {
   794  	CommandLine.Var(newDurationValue(value, p), names, usage)
   795  }
   796  
   797  // Duration defines a time.Duration flag with specified name, default value, and usage string.
   798  // The return value is the address of a time.Duration variable that stores the value of the flag.
   799  func (f *FlagSet) Duration(names []string, value time.Duration, usage string) *time.Duration {
   800  	p := new(time.Duration)
   801  	f.DurationVar(p, names, value, usage)
   802  	return p
   803  }
   804  
   805  // Duration defines a time.Duration flag with specified name, default value, and usage string.
   806  // The return value is the address of a time.Duration variable that stores the value of the flag.
   807  func Duration(names []string, value time.Duration, usage string) *time.Duration {
   808  	return CommandLine.Duration(names, value, usage)
   809  }
   810  
   811  // Var defines a flag with the specified name and usage string. The type and
   812  // value of the flag are represented by the first argument, of type Value, which
   813  // typically holds a user-defined implementation of Value. For instance, the
   814  // caller could create a flag that turns a comma-separated string into a slice
   815  // of strings by giving the slice the methods of Value; in particular, Set would
   816  // decompose the comma-separated string into the slice.
   817  func (f *FlagSet) Var(value Value, names []string, usage string) {
   818  	// Remember the default value as a string; it won't change.
   819  	flag := &Flag{names, usage, value, value.String()}
   820  	for _, name := range names {
   821  		name = strings.TrimPrefix(name, "#")
   822  		_, alreadythere := f.formal[name]
   823  		if alreadythere {
   824  			var msg string
   825  			if f.name == "" {
   826  				msg = fmt.Sprintf("flag redefined: %s", name)
   827  			} else {
   828  				msg = fmt.Sprintf("%s flag redefined: %s", f.name, name)
   829  			}
   830  			fmt.Fprintln(f.Out(), msg)
   831  			panic(msg) // Happens only if flags are declared with identical names
   832  		}
   833  		if f.formal == nil {
   834  			f.formal = make(map[string]*Flag)
   835  		}
   836  		f.formal[name] = flag
   837  	}
   838  }
   839  
   840  // Var defines a flag with the specified name and usage string. The type and
   841  // value of the flag are represented by the first argument, of type Value, which
   842  // typically holds a user-defined implementation of Value. For instance, the
   843  // caller could create a flag that turns a comma-separated string into a slice
   844  // of strings by giving the slice the methods of Value; in particular, Set would
   845  // decompose the comma-separated string into the slice.
   846  func Var(value Value, names []string, usage string) {
   847  	CommandLine.Var(value, names, usage)
   848  }
   849  
   850  // failf prints to standard error a formatted error and usage message and
   851  // returns the error.
   852  func (f *FlagSet) failf(format string, a ...interface{}) error {
   853  	err := fmt.Errorf(format, a...)
   854  	fmt.Fprintln(f.Out(), err)
   855  	if os.Args[0] == f.name {
   856  		fmt.Fprintf(f.Out(), "See '%s --help'.\n", os.Args[0])
   857  	} else {
   858  		fmt.Fprintf(f.Out(), "See '%s %s --help'.\n", os.Args[0], f.name)
   859  	}
   860  	return err
   861  }
   862  
   863  // usage calls the Usage method for the flag set, or the usage function if
   864  // the flag set is CommandLine.
   865  func (f *FlagSet) usage() {
   866  	if f == CommandLine {
   867  		Usage()
   868  	} else if f.Usage == nil {
   869  		defaultUsage(f)
   870  	} else {
   871  		f.Usage()
   872  	}
   873  }
   874  
   875  func trimQuotes(str string) string {
   876  	if len(str) == 0 {
   877  		return str
   878  	}
   879  	type quote struct {
   880  		start, end byte
   881  	}
   882  
   883  	// All valid quote types.
   884  	quotes := []quote{
   885  		// Double quotes
   886  		{
   887  			start: '"',
   888  			end:   '"',
   889  		},
   890  
   891  		// Single quotes
   892  		{
   893  			start: '\'',
   894  			end:   '\'',
   895  		},
   896  	}
   897  
   898  	for _, quote := range quotes {
   899  		// Only strip if outermost match.
   900  		if str[0] == quote.start && str[len(str)-1] == quote.end {
   901  			str = str[1 : len(str)-1]
   902  			break
   903  		}
   904  	}
   905  
   906  	return str
   907  }
   908  
   909  // parseOne parses one flag. It reports whether a flag was seen.
   910  func (f *FlagSet) parseOne() (bool, string, error) {
   911  	if len(f.args) == 0 {
   912  		return false, "", nil
   913  	}
   914  	s := f.args[0]
   915  	if len(s) == 0 || s[0] != '-' || len(s) == 1 {
   916  		return false, "", nil
   917  	}
   918  	if s[1] == '-' && len(s) == 2 { // "--" terminates the flags
   919  		f.args = f.args[1:]
   920  		return false, "", nil
   921  	}
   922  	name := s[1:]
   923  	if len(name) == 0 || name[0] == '=' {
   924  		return false, "", f.failf("bad flag syntax: %s", s)
   925  	}
   926  
   927  	// it's a flag. does it have an argument?
   928  	f.args = f.args[1:]
   929  	has_value := false
   930  	value := ""
   931  	if i := strings.Index(name, "="); i != -1 {
   932  		value = trimQuotes(name[i+1:])
   933  		has_value = true
   934  		name = name[:i]
   935  	}
   936  
   937  	m := f.formal
   938  	flag, alreadythere := m[name] // BUG
   939  	if !alreadythere {
   940  		if name == "-help" || name == "help" || name == "h" { // special case for nice help message.
   941  			f.usage()
   942  			return false, "", ErrHelp
   943  		}
   944  		if len(name) > 0 && name[0] == '-' {
   945  			return false, "", f.failf("flag provided but not defined: -%s", name)
   946  		}
   947  		return false, name, ErrRetry
   948  	}
   949  	if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
   950  		if has_value {
   951  			if err := fv.Set(value); err != nil {
   952  				return false, "", f.failf("invalid boolean value %q for  -%s: %v", value, name, err)
   953  			}
   954  		} else {
   955  			fv.Set("true")
   956  		}
   957  	} else {
   958  		// It must have a value, which might be the next argument.
   959  		if !has_value && len(f.args) > 0 {
   960  			// value is the next arg
   961  			has_value = true
   962  			value, f.args = f.args[0], f.args[1:]
   963  		}
   964  		if !has_value {
   965  			return false, "", f.failf("flag needs an argument: -%s", name)
   966  		}
   967  		if err := flag.Value.Set(value); err != nil {
   968  			return false, "", f.failf("invalid value %q for flag -%s: %v", value, name, err)
   969  		}
   970  	}
   971  	if f.actual == nil {
   972  		f.actual = make(map[string]*Flag)
   973  	}
   974  	f.actual[name] = flag
   975  	for i, n := range flag.Names {
   976  		if n == fmt.Sprintf("#%s", name) {
   977  			replacement := ""
   978  			for j := i; j < len(flag.Names); j++ {
   979  				if flag.Names[j][0] != '#' {
   980  					replacement = flag.Names[j]
   981  					break
   982  				}
   983  			}
   984  			if replacement != "" {
   985  				fmt.Fprintf(f.Out(), "Warning: '-%s' is deprecated, it will be replaced by '-%s' soon. See usage.\n", name, replacement)
   986  			} else {
   987  				fmt.Fprintf(f.Out(), "Warning: '-%s' is deprecated, it will be removed soon. See usage.\n", name)
   988  			}
   989  		}
   990  	}
   991  	return true, "", nil
   992  }
   993  
   994  // Parse parses flag definitions from the argument list, which should not
   995  // include the command name.  Must be called after all flags in the FlagSet
   996  // are defined and before flags are accessed by the program.
   997  // The return value will be ErrHelp if -help was set but not defined.
   998  func (f *FlagSet) Parse(arguments []string) error {
   999  	f.parsed = true
  1000  	f.args = arguments
  1001  	for {
  1002  		seen, name, err := f.parseOne()
  1003  		if seen {
  1004  			continue
  1005  		}
  1006  		if err == nil {
  1007  			break
  1008  		}
  1009  		if err == ErrRetry {
  1010  			if len(name) > 1 {
  1011  				err = nil
  1012  				for _, letter := range strings.Split(name, "") {
  1013  					f.args = append([]string{"-" + letter}, f.args...)
  1014  					seen2, _, err2 := f.parseOne()
  1015  					if seen2 {
  1016  						continue
  1017  					}
  1018  					if err2 != nil {
  1019  						err = f.failf("flag provided but not defined: -%s", name)
  1020  						break
  1021  					}
  1022  				}
  1023  				if err == nil {
  1024  					continue
  1025  				}
  1026  			} else {
  1027  				err = f.failf("flag provided but not defined: -%s", name)
  1028  			}
  1029  		}
  1030  		switch f.errorHandling {
  1031  		case ContinueOnError:
  1032  			return err
  1033  		case ExitOnError:
  1034  			os.Exit(2)
  1035  		case PanicOnError:
  1036  			panic(err)
  1037  		}
  1038  	}
  1039  	return nil
  1040  }
  1041  
  1042  // Parsed reports whether f.Parse has been called.
  1043  func (f *FlagSet) Parsed() bool {
  1044  	return f.parsed
  1045  }
  1046  
  1047  // Parse parses the command-line flags from os.Args[1:].  Must be called
  1048  // after all flags are defined and before flags are accessed by the program.
  1049  func Parse() {
  1050  	// Ignore errors; CommandLine is set for ExitOnError.
  1051  	CommandLine.Parse(os.Args[1:])
  1052  }
  1053  
  1054  // Parsed returns true if the command-line flags have been parsed.
  1055  func Parsed() bool {
  1056  	return CommandLine.Parsed()
  1057  }
  1058  
  1059  // CommandLine is the default set of command-line flags, parsed from os.Args.
  1060  // The top-level functions such as BoolVar, Arg, and on are wrappers for the
  1061  // methods of CommandLine.
  1062  var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
  1063  
  1064  // NewFlagSet returns a new, empty flag set with the specified name and
  1065  // error handling property.
  1066  func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
  1067  	f := &FlagSet{
  1068  		name:          name,
  1069  		errorHandling: errorHandling,
  1070  	}
  1071  	return f
  1072  }
  1073  
  1074  // Init sets the name and error handling property for a flag set.
  1075  // By default, the zero FlagSet uses an empty name and the
  1076  // ContinueOnError error handling policy.
  1077  func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
  1078  	f.name = name
  1079  	f.errorHandling = errorHandling
  1080  }