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