github.com/stchris/docker@v1.4.2-0.20150106053530-1510a324dbd5/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  }
   295  
   296  // A Flag represents the state of a flag.
   297  type Flag struct {
   298  	Names    []string // name as it appears on command line
   299  	Usage    string   // help message
   300  	Value    Value    // value as set
   301  	DefValue string   // default value (as text); for usage message
   302  }
   303  
   304  type flagSlice []string
   305  
   306  func (p flagSlice) Len() int { return len(p) }
   307  func (p flagSlice) Less(i, j int) bool {
   308  	pi, pj := strings.TrimPrefix(p[i], "-"), strings.TrimPrefix(p[j], "-")
   309  	lpi, lpj := strings.ToLower(pi), strings.ToLower(pj)
   310  	if lpi != lpj {
   311  		return lpi < lpj
   312  	}
   313  	return pi < pj
   314  }
   315  func (p flagSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
   316  
   317  // sortFlags returns the flags as a slice in lexicographical sorted order.
   318  func sortFlags(flags map[string]*Flag) []*Flag {
   319  	var list flagSlice
   320  
   321  	// The sorted list is based on the first name, when flag map might use the other names.
   322  	nameMap := make(map[string]string)
   323  
   324  	for n, f := range flags {
   325  		fName := strings.TrimPrefix(f.Names[0], "#")
   326  		nameMap[fName] = n
   327  		if len(f.Names) == 1 {
   328  			list = append(list, fName)
   329  			continue
   330  		}
   331  
   332  		found := false
   333  		for _, name := range list {
   334  			if name == fName {
   335  				found = true
   336  				break
   337  			}
   338  		}
   339  		if !found {
   340  			list = append(list, fName)
   341  		}
   342  	}
   343  	sort.Sort(list)
   344  	result := make([]*Flag, len(list))
   345  	for i, name := range list {
   346  		result[i] = flags[nameMap[name]]
   347  	}
   348  	return result
   349  }
   350  
   351  func (f *FlagSet) out() io.Writer {
   352  	if f.output == nil {
   353  		return os.Stderr
   354  	}
   355  	return f.output
   356  }
   357  
   358  // SetOutput sets the destination for usage and error messages.
   359  // If output is nil, os.Stderr is used.
   360  func (f *FlagSet) SetOutput(output io.Writer) {
   361  	f.output = output
   362  }
   363  
   364  // VisitAll visits the flags in lexicographical order, calling fn for each.
   365  // It visits all flags, even those not set.
   366  func (f *FlagSet) VisitAll(fn func(*Flag)) {
   367  	for _, flag := range sortFlags(f.formal) {
   368  		fn(flag)
   369  	}
   370  }
   371  
   372  // VisitAll visits the command-line flags in lexicographical order, calling
   373  // fn for each.  It visits all flags, even those not set.
   374  func VisitAll(fn func(*Flag)) {
   375  	CommandLine.VisitAll(fn)
   376  }
   377  
   378  // Visit visits the flags in lexicographical order, calling fn for each.
   379  // It visits only those flags that have been set.
   380  func (f *FlagSet) Visit(fn func(*Flag)) {
   381  	for _, flag := range sortFlags(f.actual) {
   382  		fn(flag)
   383  	}
   384  }
   385  
   386  // Visit visits the command-line flags in lexicographical order, calling fn
   387  // for each.  It visits only those flags that have been set.
   388  func Visit(fn func(*Flag)) {
   389  	CommandLine.Visit(fn)
   390  }
   391  
   392  // Lookup returns the Flag structure of the named flag, returning nil if none exists.
   393  func (f *FlagSet) Lookup(name string) *Flag {
   394  	return f.formal[name]
   395  }
   396  
   397  // Indicates whether the specified flag was specified at all on the cmd line
   398  func (f *FlagSet) IsSet(name string) bool {
   399  	return f.actual[name] != nil
   400  }
   401  
   402  // Lookup returns the Flag structure of the named command-line flag,
   403  // returning nil if none exists.
   404  func Lookup(name string) *Flag {
   405  	return CommandLine.formal[name]
   406  }
   407  
   408  // Indicates whether the specified flag was specified at all on the cmd line
   409  func IsSet(name string) bool {
   410  	return CommandLine.IsSet(name)
   411  }
   412  
   413  // Set sets the value of the named flag.
   414  func (f *FlagSet) Set(name, value string) error {
   415  	flag, ok := f.formal[name]
   416  	if !ok {
   417  		return fmt.Errorf("no such flag -%v", name)
   418  	}
   419  	err := flag.Value.Set(value)
   420  	if err != nil {
   421  		return err
   422  	}
   423  	if f.actual == nil {
   424  		f.actual = make(map[string]*Flag)
   425  	}
   426  	f.actual[name] = flag
   427  	return nil
   428  }
   429  
   430  // Set sets the value of the named command-line flag.
   431  func Set(name, value string) error {
   432  	return CommandLine.Set(name, value)
   433  }
   434  
   435  // PrintDefaults prints, to standard error unless configured
   436  // otherwise, the default values of all defined flags in the set.
   437  func (f *FlagSet) PrintDefaults() {
   438  	writer := tabwriter.NewWriter(f.out(), 20, 1, 3, ' ', 0)
   439  	f.VisitAll(func(flag *Flag) {
   440  		format := "  -%s=%s"
   441  		if _, ok := flag.Value.(*stringValue); ok {
   442  			// put quotes on the value
   443  			format = "  -%s=%q"
   444  		}
   445  		names := []string{}
   446  		for _, name := range flag.Names {
   447  			if name[0] != '#' {
   448  				names = append(names, name)
   449  			}
   450  		}
   451  		if len(names) > 0 {
   452  			fmt.Fprintf(writer, format, strings.Join(names, ", -"), flag.DefValue)
   453  			for i, line := range strings.Split(flag.Usage, "\n") {
   454  				if i != 0 {
   455  					line = "  " + line
   456  				}
   457  				fmt.Fprintln(writer, "\t", line)
   458  			}
   459  		}
   460  	})
   461  	writer.Flush()
   462  }
   463  
   464  // PrintDefaults prints to standard error the default values of all defined command-line flags.
   465  func PrintDefaults() {
   466  	CommandLine.PrintDefaults()
   467  }
   468  
   469  // defaultUsage is the default function to print a usage message.
   470  func defaultUsage(f *FlagSet) {
   471  	if f.name == "" {
   472  		fmt.Fprintf(f.out(), "Usage:\n")
   473  	} else {
   474  		fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
   475  	}
   476  	f.PrintDefaults()
   477  }
   478  
   479  // NOTE: Usage is not just defaultUsage(CommandLine)
   480  // because it serves (via godoc flag Usage) as the example
   481  // for how to write your own usage function.
   482  
   483  // Usage prints to standard error a usage message documenting all defined command-line flags.
   484  // The function is a variable that may be changed to point to a custom function.
   485  var Usage = func() {
   486  	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
   487  	PrintDefaults()
   488  }
   489  
   490  // FlagCount returns the number of flags that have been defined.
   491  func (f *FlagSet) FlagCount() int { return len(sortFlags(f.formal)) }
   492  
   493  // FlagCountUndeprecated returns the number of undeprecated flags that have been defined.
   494  func (f *FlagSet) FlagCountUndeprecated() int {
   495  	count := 0
   496  	for _, flag := range sortFlags(f.formal) {
   497  		for _, name := range flag.Names {
   498  			if name[0] != '#' {
   499  				count++
   500  				break
   501  			}
   502  		}
   503  	}
   504  	return count
   505  }
   506  
   507  // NFlag returns the number of flags that have been set.
   508  func (f *FlagSet) NFlag() int { return len(f.actual) }
   509  
   510  // NFlag returns the number of command-line flags that have been set.
   511  func NFlag() int { return len(CommandLine.actual) }
   512  
   513  // Arg returns the i'th argument.  Arg(0) is the first remaining argument
   514  // after flags have been processed.
   515  func (f *FlagSet) Arg(i int) string {
   516  	if i < 0 || i >= len(f.args) {
   517  		return ""
   518  	}
   519  	return f.args[i]
   520  }
   521  
   522  // Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
   523  // after flags have been processed.
   524  func Arg(i int) string {
   525  	return CommandLine.Arg(i)
   526  }
   527  
   528  // NArg is the number of arguments remaining after flags have been processed.
   529  func (f *FlagSet) NArg() int { return len(f.args) }
   530  
   531  // NArg is the number of arguments remaining after flags have been processed.
   532  func NArg() int { return len(CommandLine.args) }
   533  
   534  // Args returns the non-flag arguments.
   535  func (f *FlagSet) Args() []string { return f.args }
   536  
   537  // Args returns the non-flag command-line arguments.
   538  func Args() []string { return CommandLine.args }
   539  
   540  // BoolVar defines a bool flag with specified name, default value, and usage string.
   541  // The argument p points to a bool variable in which to store the value of the flag.
   542  func (f *FlagSet) BoolVar(p *bool, names []string, value bool, usage string) {
   543  	f.Var(newBoolValue(value, p), names, usage)
   544  }
   545  
   546  // BoolVar defines a bool flag with specified name, default value, and usage string.
   547  // The argument p points to a bool variable in which to store the value of the flag.
   548  func BoolVar(p *bool, names []string, value bool, usage string) {
   549  	CommandLine.Var(newBoolValue(value, p), names, usage)
   550  }
   551  
   552  // Bool defines a bool flag with specified name, default value, and usage string.
   553  // The return value is the address of a bool variable that stores the value of the flag.
   554  func (f *FlagSet) Bool(names []string, value bool, usage string) *bool {
   555  	p := new(bool)
   556  	f.BoolVar(p, names, value, usage)
   557  	return p
   558  }
   559  
   560  // Bool defines a bool flag with specified name, default value, and usage string.
   561  // The return value is the address of a bool variable that stores the value of the flag.
   562  func Bool(names []string, value bool, usage string) *bool {
   563  	return CommandLine.Bool(names, value, usage)
   564  }
   565  
   566  // IntVar defines an int flag with specified name, default value, and usage string.
   567  // The argument p points to an int variable in which to store the value of the flag.
   568  func (f *FlagSet) IntVar(p *int, names []string, value int, usage string) {
   569  	f.Var(newIntValue(value, p), names, usage)
   570  }
   571  
   572  // IntVar defines an int flag with specified name, default value, and usage string.
   573  // The argument p points to an int variable in which to store the value of the flag.
   574  func IntVar(p *int, names []string, value int, usage string) {
   575  	CommandLine.Var(newIntValue(value, p), names, usage)
   576  }
   577  
   578  // Int defines an int flag with specified name, default value, and usage string.
   579  // The return value is the address of an int variable that stores the value of the flag.
   580  func (f *FlagSet) Int(names []string, value int, usage string) *int {
   581  	p := new(int)
   582  	f.IntVar(p, names, value, usage)
   583  	return p
   584  }
   585  
   586  // Int defines an int flag with specified name, default value, and usage string.
   587  // The return value is the address of an int variable that stores the value of the flag.
   588  func Int(names []string, value int, usage string) *int {
   589  	return CommandLine.Int(names, value, usage)
   590  }
   591  
   592  // Int64Var defines an int64 flag with specified name, default value, and usage string.
   593  // The argument p points to an int64 variable in which to store the value of the flag.
   594  func (f *FlagSet) Int64Var(p *int64, names []string, value int64, usage string) {
   595  	f.Var(newInt64Value(value, p), names, usage)
   596  }
   597  
   598  // Int64Var defines an int64 flag with specified name, default value, and usage string.
   599  // The argument p points to an int64 variable in which to store the value of the flag.
   600  func Int64Var(p *int64, names []string, value int64, usage string) {
   601  	CommandLine.Var(newInt64Value(value, p), names, usage)
   602  }
   603  
   604  // Int64 defines an int64 flag with specified name, default value, and usage string.
   605  // The return value is the address of an int64 variable that stores the value of the flag.
   606  func (f *FlagSet) Int64(names []string, value int64, usage string) *int64 {
   607  	p := new(int64)
   608  	f.Int64Var(p, names, value, usage)
   609  	return p
   610  }
   611  
   612  // Int64 defines an int64 flag with specified name, default value, and usage string.
   613  // The return value is the address of an int64 variable that stores the value of the flag.
   614  func Int64(names []string, value int64, usage string) *int64 {
   615  	return CommandLine.Int64(names, value, usage)
   616  }
   617  
   618  // UintVar defines a uint flag with specified name, default value, and usage string.
   619  // The argument p points to a uint variable in which to store the value of the flag.
   620  func (f *FlagSet) UintVar(p *uint, names []string, value uint, usage string) {
   621  	f.Var(newUintValue(value, p), names, usage)
   622  }
   623  
   624  // UintVar defines a uint flag with specified name, default value, and usage string.
   625  // The argument p points to a uint  variable in which to store the value of the flag.
   626  func UintVar(p *uint, names []string, value uint, usage string) {
   627  	CommandLine.Var(newUintValue(value, p), names, usage)
   628  }
   629  
   630  // Uint defines a uint flag with specified name, default value, and usage string.
   631  // The return value is the address of a uint  variable that stores the value of the flag.
   632  func (f *FlagSet) Uint(names []string, value uint, usage string) *uint {
   633  	p := new(uint)
   634  	f.UintVar(p, names, value, usage)
   635  	return p
   636  }
   637  
   638  // Uint defines a uint flag with specified name, default value, and usage string.
   639  // The return value is the address of a uint  variable that stores the value of the flag.
   640  func Uint(names []string, value uint, usage string) *uint {
   641  	return CommandLine.Uint(names, value, usage)
   642  }
   643  
   644  // Uint64Var defines a uint64 flag with specified name, default value, and usage string.
   645  // The argument p points to a uint64 variable in which to store the value of the flag.
   646  func (f *FlagSet) Uint64Var(p *uint64, names []string, value uint64, usage string) {
   647  	f.Var(newUint64Value(value, p), names, usage)
   648  }
   649  
   650  // Uint64Var defines a uint64 flag with specified name, default value, and usage string.
   651  // The argument p points to a uint64 variable in which to store the value of the flag.
   652  func Uint64Var(p *uint64, names []string, value uint64, usage string) {
   653  	CommandLine.Var(newUint64Value(value, p), names, usage)
   654  }
   655  
   656  // Uint64 defines a uint64 flag with specified name, default value, and usage string.
   657  // The return value is the address of a uint64 variable that stores the value of the flag.
   658  func (f *FlagSet) Uint64(names []string, value uint64, usage string) *uint64 {
   659  	p := new(uint64)
   660  	f.Uint64Var(p, names, value, usage)
   661  	return p
   662  }
   663  
   664  // Uint64 defines a uint64 flag with specified name, default value, and usage string.
   665  // The return value is the address of a uint64 variable that stores the value of the flag.
   666  func Uint64(names []string, value uint64, usage string) *uint64 {
   667  	return CommandLine.Uint64(names, value, usage)
   668  }
   669  
   670  // StringVar defines a string flag with specified name, default value, and usage string.
   671  // The argument p points to a string variable in which to store the value of the flag.
   672  func (f *FlagSet) StringVar(p *string, names []string, value string, usage string) {
   673  	f.Var(newStringValue(value, p), names, usage)
   674  }
   675  
   676  // StringVar defines a string flag with specified name, default value, and usage string.
   677  // The argument p points to a string variable in which to store the value of the flag.
   678  func StringVar(p *string, names []string, value string, usage string) {
   679  	CommandLine.Var(newStringValue(value, p), names, usage)
   680  }
   681  
   682  // String defines a string flag with specified name, default value, and usage string.
   683  // The return value is the address of a string variable that stores the value of the flag.
   684  func (f *FlagSet) String(names []string, value string, usage string) *string {
   685  	p := new(string)
   686  	f.StringVar(p, names, value, usage)
   687  	return p
   688  }
   689  
   690  // String defines a string flag with specified name, default value, and usage string.
   691  // The return value is the address of a string variable that stores the value of the flag.
   692  func String(names []string, value string, usage string) *string {
   693  	return CommandLine.String(names, value, usage)
   694  }
   695  
   696  // Float64Var defines a float64 flag with specified name, default value, and usage string.
   697  // The argument p points to a float64 variable in which to store the value of the flag.
   698  func (f *FlagSet) Float64Var(p *float64, names []string, value float64, usage string) {
   699  	f.Var(newFloat64Value(value, p), names, usage)
   700  }
   701  
   702  // Float64Var defines a float64 flag with specified name, default value, and usage string.
   703  // The argument p points to a float64 variable in which to store the value of the flag.
   704  func Float64Var(p *float64, names []string, value float64, usage string) {
   705  	CommandLine.Var(newFloat64Value(value, p), names, usage)
   706  }
   707  
   708  // Float64 defines a float64 flag with specified name, default value, and usage string.
   709  // The return value is the address of a float64 variable that stores the value of the flag.
   710  func (f *FlagSet) Float64(names []string, value float64, usage string) *float64 {
   711  	p := new(float64)
   712  	f.Float64Var(p, names, value, usage)
   713  	return p
   714  }
   715  
   716  // Float64 defines a float64 flag with specified name, default value, and usage string.
   717  // The return value is the address of a float64 variable that stores the value of the flag.
   718  func Float64(names []string, value float64, usage string) *float64 {
   719  	return CommandLine.Float64(names, value, usage)
   720  }
   721  
   722  // DurationVar defines a time.Duration flag with specified name, default value, and usage string.
   723  // The argument p points to a time.Duration variable in which to store the value of the flag.
   724  func (f *FlagSet) DurationVar(p *time.Duration, names []string, value time.Duration, usage string) {
   725  	f.Var(newDurationValue(value, p), names, usage)
   726  }
   727  
   728  // DurationVar defines a time.Duration flag with specified name, default value, and usage string.
   729  // The argument p points to a time.Duration variable in which to store the value of the flag.
   730  func DurationVar(p *time.Duration, names []string, value time.Duration, usage string) {
   731  	CommandLine.Var(newDurationValue(value, p), names, usage)
   732  }
   733  
   734  // Duration defines a time.Duration flag with specified name, default value, and usage string.
   735  // The return value is the address of a time.Duration variable that stores the value of the flag.
   736  func (f *FlagSet) Duration(names []string, value time.Duration, usage string) *time.Duration {
   737  	p := new(time.Duration)
   738  	f.DurationVar(p, names, value, usage)
   739  	return p
   740  }
   741  
   742  // Duration defines a time.Duration flag with specified name, default value, and usage string.
   743  // The return value is the address of a time.Duration variable that stores the value of the flag.
   744  func Duration(names []string, value time.Duration, usage string) *time.Duration {
   745  	return CommandLine.Duration(names, value, usage)
   746  }
   747  
   748  // Var defines a flag with the specified name and usage string. The type and
   749  // value of the flag are represented by the first argument, of type Value, which
   750  // typically holds a user-defined implementation of Value. For instance, the
   751  // caller could create a flag that turns a comma-separated string into a slice
   752  // of strings by giving the slice the methods of Value; in particular, Set would
   753  // decompose the comma-separated string into the slice.
   754  func (f *FlagSet) Var(value Value, names []string, usage string) {
   755  	// Remember the default value as a string; it won't change.
   756  	flag := &Flag{names, usage, value, value.String()}
   757  	for _, name := range names {
   758  		name = strings.TrimPrefix(name, "#")
   759  		_, alreadythere := f.formal[name]
   760  		if alreadythere {
   761  			var msg string
   762  			if f.name == "" {
   763  				msg = fmt.Sprintf("flag redefined: %s", name)
   764  			} else {
   765  				msg = fmt.Sprintf("%s flag redefined: %s", f.name, name)
   766  			}
   767  			fmt.Fprintln(f.out(), msg)
   768  			panic(msg) // Happens only if flags are declared with identical names
   769  		}
   770  		if f.formal == nil {
   771  			f.formal = make(map[string]*Flag)
   772  		}
   773  		f.formal[name] = flag
   774  	}
   775  }
   776  
   777  // Var defines a flag with the specified name and usage string. The type and
   778  // value of the flag are represented by the first argument, of type Value, which
   779  // typically holds a user-defined implementation of Value. For instance, the
   780  // caller could create a flag that turns a comma-separated string into a slice
   781  // of strings by giving the slice the methods of Value; in particular, Set would
   782  // decompose the comma-separated string into the slice.
   783  func Var(value Value, names []string, usage string) {
   784  	CommandLine.Var(value, names, usage)
   785  }
   786  
   787  // failf prints to standard error a formatted error and usage message and
   788  // returns the error.
   789  func (f *FlagSet) failf(format string, a ...interface{}) error {
   790  	err := fmt.Errorf(format, a...)
   791  	fmt.Fprintln(f.out(), err)
   792  	f.usage()
   793  	return err
   794  }
   795  
   796  // usage calls the Usage method for the flag set, or the usage function if
   797  // the flag set is CommandLine.
   798  func (f *FlagSet) usage() {
   799  	if f == CommandLine {
   800  		Usage()
   801  	} else if f.Usage == nil {
   802  		defaultUsage(f)
   803  	} else {
   804  		f.Usage()
   805  	}
   806  }
   807  
   808  func trimQuotes(str string) string {
   809  	if len(str) == 0 {
   810  		return str
   811  	}
   812  	type quote struct {
   813  		start, end byte
   814  	}
   815  
   816  	// All valid quote types.
   817  	quotes := []quote{
   818  		// Double quotes
   819  		{
   820  			start: '"',
   821  			end:   '"',
   822  		},
   823  
   824  		// Single quotes
   825  		{
   826  			start: '\'',
   827  			end:   '\'',
   828  		},
   829  	}
   830  
   831  	for _, quote := range quotes {
   832  		// Only strip if outermost match.
   833  		if str[0] == quote.start && str[len(str)-1] == quote.end {
   834  			str = str[1 : len(str)-1]
   835  			break
   836  		}
   837  	}
   838  
   839  	return str
   840  }
   841  
   842  // parseOne parses one flag. It reports whether a flag was seen.
   843  func (f *FlagSet) parseOne() (bool, string, error) {
   844  	if len(f.args) == 0 {
   845  		return false, "", nil
   846  	}
   847  	s := f.args[0]
   848  	if len(s) == 0 || s[0] != '-' || len(s) == 1 {
   849  		return false, "", nil
   850  	}
   851  	if s[1] == '-' && len(s) == 2 { // "--" terminates the flags
   852  		f.args = f.args[1:]
   853  		return false, "", nil
   854  	}
   855  	name := s[1:]
   856  	if len(name) == 0 || name[0] == '=' {
   857  		return false, "", f.failf("bad flag syntax: %s", s)
   858  	}
   859  
   860  	// it's a flag. does it have an argument?
   861  	f.args = f.args[1:]
   862  	has_value := false
   863  	value := ""
   864  	if i := strings.Index(name, "="); i != -1 {
   865  		value = trimQuotes(name[i+1:])
   866  		has_value = true
   867  		name = name[:i]
   868  	}
   869  
   870  	m := f.formal
   871  	flag, alreadythere := m[name] // BUG
   872  	if !alreadythere {
   873  		if name == "-help" || name == "help" || name == "h" { // special case for nice help message.
   874  			f.usage()
   875  			return false, "", ErrHelp
   876  		}
   877  		if len(name) > 0 && name[0] == '-' {
   878  			return false, "", f.failf("flag provided but not defined: -%s", name)
   879  		}
   880  		return false, name, ErrRetry
   881  	}
   882  	if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
   883  		if has_value {
   884  			if err := fv.Set(value); err != nil {
   885  				return false, "", f.failf("invalid boolean value %q for  -%s: %v", value, name, err)
   886  			}
   887  		} else {
   888  			fv.Set("true")
   889  		}
   890  	} else {
   891  		// It must have a value, which might be the next argument.
   892  		if !has_value && len(f.args) > 0 {
   893  			// value is the next arg
   894  			has_value = true
   895  			value, f.args = f.args[0], f.args[1:]
   896  		}
   897  		if !has_value {
   898  			return false, "", f.failf("flag needs an argument: -%s", name)
   899  		}
   900  		if err := flag.Value.Set(value); err != nil {
   901  			return false, "", f.failf("invalid value %q for flag -%s: %v", value, name, err)
   902  		}
   903  	}
   904  	if f.actual == nil {
   905  		f.actual = make(map[string]*Flag)
   906  	}
   907  	f.actual[name] = flag
   908  	for i, n := range flag.Names {
   909  		if n == fmt.Sprintf("#%s", name) {
   910  			replacement := ""
   911  			for j := i; j < len(flag.Names); j++ {
   912  				if flag.Names[j][0] != '#' {
   913  					replacement = flag.Names[j]
   914  					break
   915  				}
   916  			}
   917  			if replacement != "" {
   918  				fmt.Fprintf(f.out(), "Warning: '-%s' is deprecated, it will be replaced by '-%s' soon. See usage.\n", name, replacement)
   919  			} else {
   920  				fmt.Fprintf(f.out(), "Warning: '-%s' is deprecated, it will be removed soon. See usage.\n", name)
   921  			}
   922  		}
   923  	}
   924  	return true, "", nil
   925  }
   926  
   927  // Parse parses flag definitions from the argument list, which should not
   928  // include the command name.  Must be called after all flags in the FlagSet
   929  // are defined and before flags are accessed by the program.
   930  // The return value will be ErrHelp if -help was set but not defined.
   931  func (f *FlagSet) Parse(arguments []string) error {
   932  	f.parsed = true
   933  	f.args = arguments
   934  	for {
   935  		seen, name, err := f.parseOne()
   936  		if seen {
   937  			continue
   938  		}
   939  		if err == nil {
   940  			break
   941  		}
   942  		if err == ErrRetry {
   943  			if len(name) > 1 {
   944  				err = nil
   945  				for _, letter := range strings.Split(name, "") {
   946  					f.args = append([]string{"-" + letter}, f.args...)
   947  					seen2, _, err2 := f.parseOne()
   948  					if seen2 {
   949  						continue
   950  					}
   951  					if err2 != nil {
   952  						err = f.failf("flag provided but not defined: -%s", name)
   953  						break
   954  					}
   955  				}
   956  				if err == nil {
   957  					continue
   958  				}
   959  			} else {
   960  				err = f.failf("flag provided but not defined: -%s", name)
   961  			}
   962  		}
   963  		switch f.errorHandling {
   964  		case ContinueOnError:
   965  			return err
   966  		case ExitOnError:
   967  			os.Exit(2)
   968  		case PanicOnError:
   969  			panic(err)
   970  		}
   971  	}
   972  	return nil
   973  }
   974  
   975  // Parsed reports whether f.Parse has been called.
   976  func (f *FlagSet) Parsed() bool {
   977  	return f.parsed
   978  }
   979  
   980  // Parse parses the command-line flags from os.Args[1:].  Must be called
   981  // after all flags are defined and before flags are accessed by the program.
   982  func Parse() {
   983  	// Ignore errors; CommandLine is set for ExitOnError.
   984  	CommandLine.Parse(os.Args[1:])
   985  }
   986  
   987  // Parsed returns true if the command-line flags have been parsed.
   988  func Parsed() bool {
   989  	return CommandLine.Parsed()
   990  }
   991  
   992  // CommandLine is the default set of command-line flags, parsed from os.Args.
   993  // The top-level functions such as BoolVar, Arg, and on are wrappers for the
   994  // methods of CommandLine.
   995  var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
   996  
   997  // NewFlagSet returns a new, empty flag set with the specified name and
   998  // error handling property.
   999  func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
  1000  	f := &FlagSet{
  1001  		name:          name,
  1002  		errorHandling: errorHandling,
  1003  	}
  1004  	return f
  1005  }
  1006  
  1007  // Init sets the name and error handling property for a flag set.
  1008  // By default, the zero FlagSet uses an empty name and the
  1009  // ContinueOnError error handling policy.
  1010  func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
  1011  	f.name = name
  1012  	f.errorHandling = errorHandling
  1013  }