Black Lives Matter. Support the Equal Justice Initiative.

Source file src/flag/flag.go

Documentation: flag

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

View as plain text