github.com/pmorton/docker@v1.5.0/pkg/mflag/flag.go (about)

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