...
Run Format

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  type FlagSet struct {
   318  	// Usage is the function called when an error occurs while parsing flags.
   319  	// The field is a function (not a method) that may be changed to point to
   320  	// a custom error handler. What happens after Usage is called depends
   321  	// on the ErrorHandling setting; for the command line, this defaults
   322  	// to ExitOnError, which exits the program after calling Usage.
   323  	Usage func()
   324  
   325  	name          string
   326  	parsed        bool
   327  	actual        map[string]*Flag
   328  	formal        map[string]*Flag
   329  	args          []string // arguments after flags
   330  	errorHandling ErrorHandling
   331  	output        io.Writer // nil means stderr; use out() accessor
   332  }
   333  
   334  // A Flag represents the state of a flag.
   335  type Flag struct {
   336  	Name     string // name as it appears on command line
   337  	Usage    string // help message
   338  	Value    Value  // value as set
   339  	DefValue string // default value (as text); for usage message
   340  }
   341  
   342  // sortFlags returns the flags as a slice in lexicographical sorted order.
   343  func sortFlags(flags map[string]*Flag) []*Flag {
   344  	list := make(sort.StringSlice, len(flags))
   345  	i := 0
   346  	for _, f := range flags {
   347  		list[i] = f.Name
   348  		i++
   349  	}
   350  	list.Sort()
   351  	result := make([]*Flag, len(list))
   352  	for i, name := range list {
   353  		result[i] = flags[name]
   354  	}
   355  	return result
   356  }
   357  
   358  // Output returns the destination for usage and error messages. os.Stderr is returned if
   359  // output was not set or was set to nil.
   360  func (f *FlagSet) Output() io.Writer {
   361  	if f.output == nil {
   362  		return os.Stderr
   363  	}
   364  	return f.output
   365  }
   366  
   367  // Name returns the name of the flag set.
   368  func (f *FlagSet) Name() string {
   369  	return f.name
   370  }
   371  
   372  // ErrorHandling returns the error handling behavior of the flag set.
   373  func (f *FlagSet) ErrorHandling() ErrorHandling {
   374  	return f.errorHandling
   375  }
   376  
   377  // SetOutput sets the destination for usage and error messages.
   378  // If output is nil, os.Stderr is used.
   379  func (f *FlagSet) SetOutput(output io.Writer) {
   380  	f.output = output
   381  }
   382  
   383  // VisitAll visits the flags in lexicographical order, calling fn for each.
   384  // It visits all flags, even those not set.
   385  func (f *FlagSet) VisitAll(fn func(*Flag)) {
   386  	for _, flag := range sortFlags(f.formal) {
   387  		fn(flag)
   388  	}
   389  }
   390  
   391  // VisitAll visits the command-line flags in lexicographical order, calling
   392  // fn for each. It visits all flags, even those not set.
   393  func VisitAll(fn func(*Flag)) {
   394  	CommandLine.VisitAll(fn)
   395  }
   396  
   397  // Visit visits the flags in lexicographical order, calling fn for each.
   398  // It visits only those flags that have been set.
   399  func (f *FlagSet) Visit(fn func(*Flag)) {
   400  	for _, flag := range sortFlags(f.actual) {
   401  		fn(flag)
   402  	}
   403  }
   404  
   405  // Visit visits the command-line flags in lexicographical order, calling fn
   406  // for each. It visits only those flags that have been set.
   407  func Visit(fn func(*Flag)) {
   408  	CommandLine.Visit(fn)
   409  }
   410  
   411  // Lookup returns the Flag structure of the named flag, returning nil if none exists.
   412  func (f *FlagSet) Lookup(name string) *Flag {
   413  	return f.formal[name]
   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  // Set sets the value of the named flag.
   423  func (f *FlagSet) Set(name, value string) error {
   424  	flag, ok := f.formal[name]
   425  	if !ok {
   426  		return fmt.Errorf("no such flag -%v", name)
   427  	}
   428  	err := flag.Value.Set(value)
   429  	if err != nil {
   430  		return err
   431  	}
   432  	if f.actual == nil {
   433  		f.actual = make(map[string]*Flag)
   434  	}
   435  	f.actual[name] = flag
   436  	return nil
   437  }
   438  
   439  // Set sets the value of the named command-line flag.
   440  func Set(name, value string) error {
   441  	return CommandLine.Set(name, value)
   442  }
   443  
   444  // isZeroValue determines whether the string represents the zero
   445  // value for a flag.
   446  func isZeroValue(flag *Flag, value string) bool {
   447  	// Build a zero value of the flag's Value type, and see if the
   448  	// result of calling its String method equals the value passed in.
   449  	// This works unless the Value type is itself an interface type.
   450  	typ := reflect.TypeOf(flag.Value)
   451  	var z reflect.Value
   452  	if typ.Kind() == reflect.Ptr {
   453  		z = reflect.New(typ.Elem())
   454  	} else {
   455  		z = reflect.Zero(typ)
   456  	}
   457  	return value == z.Interface().(Value).String()
   458  }
   459  
   460  // UnquoteUsage extracts a back-quoted name from the usage
   461  // string for a flag and returns it and the un-quoted usage.
   462  // Given "a `name` to show" it returns ("name", "a name to show").
   463  // If there are no back quotes, the name is an educated guess of the
   464  // type of the flag's value, or the empty string if the flag is boolean.
   465  func UnquoteUsage(flag *Flag) (name string, usage string) {
   466  	// Look for a back-quoted name, but avoid the strings package.
   467  	usage = flag.Usage
   468  	for i := 0; i < len(usage); i++ {
   469  		if usage[i] == '`' {
   470  			for j := i + 1; j < len(usage); j++ {
   471  				if usage[j] == '`' {
   472  					name = usage[i+1 : j]
   473  					usage = usage[:i] + name + usage[j+1:]
   474  					return name, usage
   475  				}
   476  			}
   477  			break // Only one back quote; use type name.
   478  		}
   479  	}
   480  	// No explicit name, so use type if we can find one.
   481  	name = "value"
   482  	switch flag.Value.(type) {
   483  	case boolFlag:
   484  		name = ""
   485  	case *durationValue:
   486  		name = "duration"
   487  	case *float64Value:
   488  		name = "float"
   489  	case *intValue, *int64Value:
   490  		name = "int"
   491  	case *stringValue:
   492  		name = "string"
   493  	case *uintValue, *uint64Value:
   494  		name = "uint"
   495  	}
   496  	return
   497  }
   498  
   499  // PrintDefaults prints, to standard error unless configured otherwise, the
   500  // default values of all defined command-line flags in the set. See the
   501  // documentation for the global function PrintDefaults for more information.
   502  func (f *FlagSet) PrintDefaults() {
   503  	f.VisitAll(func(flag *Flag) {
   504  		s := fmt.Sprintf("  -%s", flag.Name) // Two spaces before -; see next two comments.
   505  		name, usage := UnquoteUsage(flag)
   506  		if len(name) > 0 {
   507  			s += " " + name
   508  		}
   509  		// Boolean flags of one ASCII letter are so common we
   510  		// treat them specially, putting their usage on the same line.
   511  		if len(s) <= 4 { // space, space, '-', 'x'.
   512  			s += "\t"
   513  		} else {
   514  			// Four spaces before the tab triggers good alignment
   515  			// for both 4- and 8-space tab stops.
   516  			s += "\n    \t"
   517  		}
   518  		s += strings.ReplaceAll(usage, "\n", "\n    \t")
   519  
   520  		if !isZeroValue(flag, flag.DefValue) {
   521  			if _, ok := flag.Value.(*stringValue); ok {
   522  				// put quotes on the value
   523  				s += fmt.Sprintf(" (default %q)", flag.DefValue)
   524  			} else {
   525  				s += fmt.Sprintf(" (default %v)", flag.DefValue)
   526  			}
   527  		}
   528  		fmt.Fprint(f.Output(), s, "\n")
   529  	})
   530  }
   531  
   532  // PrintDefaults prints, to standard error unless configured otherwise,
   533  // a usage message showing the default settings of all defined
   534  // command-line flags.
   535  // For an integer valued flag x, the default output has the form
   536  //	-x int
   537  //		usage-message-for-x (default 7)
   538  // The usage message will appear on a separate line for anything but
   539  // a bool flag with a one-byte name. For bool flags, the type is
   540  // omitted and if the flag name is one byte the usage message appears
   541  // on the same line. The parenthetical default is omitted if the
   542  // default is the zero value for the type. The listed type, here int,
   543  // can be changed by placing a back-quoted name in the flag's usage
   544  // string; the first such item in the message is taken to be a parameter
   545  // name to show in the message and the back quotes are stripped from
   546  // the message when displayed. For instance, given
   547  //	flag.String("I", "", "search `directory` for include files")
   548  // the output will be
   549  //	-I directory
   550  //		search directory for include files.
   551  //
   552  // To change the destination for flag messages, call CommandLine.SetOutput.
   553  func PrintDefaults() {
   554  	CommandLine.PrintDefaults()
   555  }
   556  
   557  // defaultUsage is the default function to print a usage message.
   558  func (f *FlagSet) defaultUsage() {
   559  	if f.name == "" {
   560  		fmt.Fprintf(f.Output(), "Usage:\n")
   561  	} else {
   562  		fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name)
   563  	}
   564  	f.PrintDefaults()
   565  }
   566  
   567  // NOTE: Usage is not just defaultUsage(CommandLine)
   568  // because it serves (via godoc flag Usage) as the example
   569  // for how to write your own usage function.
   570  
   571  // Usage prints a usage message documenting all defined command-line flags
   572  // to CommandLine's output, which by default is os.Stderr.
   573  // It is called when an error occurs while parsing flags.
   574  // The function is a variable that may be changed to point to a custom function.
   575  // By default it prints a simple header and calls PrintDefaults; for details about the
   576  // format of the output and how to control it, see the documentation for PrintDefaults.
   577  // Custom usage functions may choose to exit the program; by default exiting
   578  // happens anyway as the command line's error handling strategy is set to
   579  // ExitOnError.
   580  var Usage = func() {
   581  	fmt.Fprintf(CommandLine.Output(), "Usage of %s:\n", os.Args[0])
   582  	PrintDefaults()
   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. Arg returns an empty string if the
   593  // requested element does not exist.
   594  func (f *FlagSet) Arg(i int) string {
   595  	if i < 0 || i >= len(f.args) {
   596  		return ""
   597  	}
   598  	return f.args[i]
   599  }
   600  
   601  // Arg returns the i'th command-line argument. Arg(0) is the first remaining argument
   602  // after flags have been processed. Arg returns an empty string if the
   603  // requested element does not exist.
   604  func Arg(i int) string {
   605  	return CommandLine.Arg(i)
   606  }
   607  
   608  // NArg is the number of arguments remaining after flags have been processed.
   609  func (f *FlagSet) NArg() int { return len(f.args) }
   610  
   611  // NArg is the number of arguments remaining after flags have been processed.
   612  func NArg() int { return len(CommandLine.args) }
   613  
   614  // Args returns the non-flag arguments.
   615  func (f *FlagSet) Args() []string { return f.args }
   616  
   617  // Args returns the non-flag command-line arguments.
   618  func Args() []string { return CommandLine.args }
   619  
   620  // BoolVar defines a bool flag with specified name, default value, and usage string.
   621  // The argument p points to a bool variable in which to store the value of the flag.
   622  func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
   623  	f.Var(newBoolValue(value, p), name, usage)
   624  }
   625  
   626  // BoolVar defines a bool flag with specified name, default value, and usage string.
   627  // The argument p points to a bool variable in which to store the value of the flag.
   628  func BoolVar(p *bool, name string, value bool, usage string) {
   629  	CommandLine.Var(newBoolValue(value, p), name, usage)
   630  }
   631  
   632  // Bool defines a bool flag with specified name, default value, and usage string.
   633  // The return value is the address of a bool variable that stores the value of the flag.
   634  func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
   635  	p := new(bool)
   636  	f.BoolVar(p, name, value, usage)
   637  	return p
   638  }
   639  
   640  // Bool defines a bool flag with specified name, default value, and usage string.
   641  // The return value is the address of a bool variable that stores the value of the flag.
   642  func Bool(name string, value bool, usage string) *bool {
   643  	return CommandLine.Bool(name, value, usage)
   644  }
   645  
   646  // IntVar defines an int flag with specified name, default value, and usage string.
   647  // The argument p points to an int variable in which to store the value of the flag.
   648  func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
   649  	f.Var(newIntValue(value, p), name, usage)
   650  }
   651  
   652  // IntVar defines an int flag with specified name, default value, and usage string.
   653  // The argument p points to an int variable in which to store the value of the flag.
   654  func IntVar(p *int, name string, value int, usage string) {
   655  	CommandLine.Var(newIntValue(value, p), name, usage)
   656  }
   657  
   658  // Int defines an int flag with specified name, default value, and usage string.
   659  // The return value is the address of an int variable that stores the value of the flag.
   660  func (f *FlagSet) Int(name string, value int, usage string) *int {
   661  	p := new(int)
   662  	f.IntVar(p, name, value, usage)
   663  	return p
   664  }
   665  
   666  // Int defines an int flag with specified name, default value, and usage string.
   667  // The return value is the address of an int variable that stores the value of the flag.
   668  func Int(name string, value int, usage string) *int {
   669  	return CommandLine.Int(name, value, usage)
   670  }
   671  
   672  // Int64Var defines an int64 flag with specified name, default value, and usage string.
   673  // The argument p points to an int64 variable in which to store the value of the flag.
   674  func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {
   675  	f.Var(newInt64Value(value, p), name, usage)
   676  }
   677  
   678  // Int64Var defines an int64 flag with specified name, default value, and usage string.
   679  // The argument p points to an int64 variable in which to store the value of the flag.
   680  func Int64Var(p *int64, name string, value int64, usage string) {
   681  	CommandLine.Var(newInt64Value(value, p), name, usage)
   682  }
   683  
   684  // Int64 defines an int64 flag with specified name, default value, and usage string.
   685  // The return value is the address of an int64 variable that stores the value of the flag.
   686  func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
   687  	p := new(int64)
   688  	f.Int64Var(p, name, value, usage)
   689  	return p
   690  }
   691  
   692  // Int64 defines an int64 flag with specified name, default value, and usage string.
   693  // The return value is the address of an int64 variable that stores the value of the flag.
   694  func Int64(name string, value int64, usage string) *int64 {
   695  	return CommandLine.Int64(name, value, usage)
   696  }
   697  
   698  // UintVar defines a uint flag with specified name, default value, and usage string.
   699  // The argument p points to a uint variable in which to store the value of the flag.
   700  func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
   701  	f.Var(newUintValue(value, p), name, usage)
   702  }
   703  
   704  // UintVar defines a uint flag with specified name, default value, and usage string.
   705  // The argument p points to a uint variable in which to store the value of the flag.
   706  func UintVar(p *uint, name string, value uint, usage string) {
   707  	CommandLine.Var(newUintValue(value, p), name, usage)
   708  }
   709  
   710  // Uint defines a uint flag with specified name, default value, and usage string.
   711  // The return value is the address of a uint variable that stores the value of the flag.
   712  func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
   713  	p := new(uint)
   714  	f.UintVar(p, name, value, usage)
   715  	return p
   716  }
   717  
   718  // Uint defines a uint flag with specified name, default value, and usage string.
   719  // The return value is the address of a uint variable that stores the value of the flag.
   720  func Uint(name string, value uint, usage string) *uint {
   721  	return CommandLine.Uint(name, value, usage)
   722  }
   723  
   724  // Uint64Var defines a uint64 flag with specified name, default value, and usage string.
   725  // The argument p points to a uint64 variable in which to store the value of the flag.
   726  func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
   727  	f.Var(newUint64Value(value, p), name, usage)
   728  }
   729  
   730  // Uint64Var defines a uint64 flag with specified name, default value, and usage string.
   731  // The argument p points to a uint64 variable in which to store the value of the flag.
   732  func Uint64Var(p *uint64, name string, value uint64, usage string) {
   733  	CommandLine.Var(newUint64Value(value, p), name, usage)
   734  }
   735  
   736  // Uint64 defines a uint64 flag with specified name, default value, and usage string.
   737  // The return value is the address of a uint64 variable that stores the value of the flag.
   738  func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
   739  	p := new(uint64)
   740  	f.Uint64Var(p, name, value, usage)
   741  	return p
   742  }
   743  
   744  // Uint64 defines a uint64 flag with specified name, default value, and usage string.
   745  // The return value is the address of a uint64 variable that stores the value of the flag.
   746  func Uint64(name string, value uint64, usage string) *uint64 {
   747  	return CommandLine.Uint64(name, value, usage)
   748  }
   749  
   750  // StringVar defines a string flag with specified name, default value, and usage string.
   751  // The argument p points to a string variable in which to store the value of the flag.
   752  func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
   753  	f.Var(newStringValue(value, p), name, usage)
   754  }
   755  
   756  // StringVar defines a string flag with specified name, default value, and usage string.
   757  // The argument p points to a string variable in which to store the value of the flag.
   758  func StringVar(p *string, name string, value string, usage string) {
   759  	CommandLine.Var(newStringValue(value, p), name, usage)
   760  }
   761  
   762  // String defines a string flag with specified name, default value, and usage string.
   763  // The return value is the address of a string variable that stores the value of the flag.
   764  func (f *FlagSet) String(name string, value string, usage string) *string {
   765  	p := new(string)
   766  	f.StringVar(p, name, value, usage)
   767  	return p
   768  }
   769  
   770  // String defines a string flag with specified name, default value, and usage string.
   771  // The return value is the address of a string variable that stores the value of the flag.
   772  func String(name string, value string, usage string) *string {
   773  	return CommandLine.String(name, value, usage)
   774  }
   775  
   776  // Float64Var defines a float64 flag with specified name, default value, and usage string.
   777  // The argument p points to a float64 variable in which to store the value of the flag.
   778  func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) {
   779  	f.Var(newFloat64Value(value, p), name, usage)
   780  }
   781  
   782  // Float64Var defines a float64 flag with specified name, default value, and usage string.
   783  // The argument p points to a float64 variable in which to store the value of the flag.
   784  func Float64Var(p *float64, name string, value float64, usage string) {
   785  	CommandLine.Var(newFloat64Value(value, p), name, usage)
   786  }
   787  
   788  // Float64 defines a float64 flag with specified name, default value, and usage string.
   789  // The return value is the address of a float64 variable that stores the value of the flag.
   790  func (f *FlagSet) Float64(name string, value float64, usage string) *float64 {
   791  	p := new(float64)
   792  	f.Float64Var(p, name, value, usage)
   793  	return p
   794  }
   795  
   796  // Float64 defines a float64 flag with specified name, default value, and usage string.
   797  // The return value is the address of a float64 variable that stores the value of the flag.
   798  func Float64(name string, value float64, usage string) *float64 {
   799  	return CommandLine.Float64(name, value, usage)
   800  }
   801  
   802  // DurationVar defines a time.Duration flag with specified name, default value, and usage string.
   803  // The argument p points to a time.Duration variable in which to store the value of the flag.
   804  // The flag accepts a value acceptable to time.ParseDuration.
   805  func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
   806  	f.Var(newDurationValue(value, p), name, usage)
   807  }
   808  
   809  // DurationVar defines a time.Duration flag with specified name, default value, and usage string.
   810  // The argument p points to a time.Duration variable in which to store the value of the flag.
   811  // The flag accepts a value acceptable to time.ParseDuration.
   812  func DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
   813  	CommandLine.Var(newDurationValue(value, p), name, usage)
   814  }
   815  
   816  // Duration defines a time.Duration flag with specified name, default value, and usage string.
   817  // The return value is the address of a time.Duration variable that stores the value of the flag.
   818  // The flag accepts a value acceptable to time.ParseDuration.
   819  func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration {
   820  	p := new(time.Duration)
   821  	f.DurationVar(p, name, value, usage)
   822  	return p
   823  }
   824  
   825  // Duration defines a time.Duration flag with specified name, default value, and usage string.
   826  // The return value is the address of a time.Duration variable that stores the value of the flag.
   827  // The flag accepts a value acceptable to time.ParseDuration.
   828  func Duration(name string, value time.Duration, usage string) *time.Duration {
   829  	return CommandLine.Duration(name, value, usage)
   830  }
   831  
   832  // Var defines a flag with the specified name and usage string. The type and
   833  // value of the flag are represented by the first argument, of type Value, which
   834  // typically holds a user-defined implementation of Value. For instance, the
   835  // caller could create a flag that turns a comma-separated string into a slice
   836  // of strings by giving the slice the methods of Value; in particular, Set would
   837  // decompose the comma-separated string into the slice.
   838  func (f *FlagSet) Var(value Value, name string, usage string) {
   839  	// Remember the default value as a string; it won't change.
   840  	flag := &Flag{name, usage, value, value.String()}
   841  	_, alreadythere := f.formal[name]
   842  	if alreadythere {
   843  		var msg string
   844  		if f.name == "" {
   845  			msg = fmt.Sprintf("flag redefined: %s", name)
   846  		} else {
   847  			msg = fmt.Sprintf("%s flag redefined: %s", f.name, name)
   848  		}
   849  		fmt.Fprintln(f.Output(), msg)
   850  		panic(msg) // Happens only if flags are declared with identical names
   851  	}
   852  	if f.formal == nil {
   853  		f.formal = make(map[string]*Flag)
   854  	}
   855  	f.formal[name] = flag
   856  }
   857  
   858  // Var defines a flag with the specified name and usage string. The type and
   859  // value of the flag are represented by the first argument, of type Value, which
   860  // typically holds a user-defined implementation of Value. For instance, the
   861  // caller could create a flag that turns a comma-separated string into a slice
   862  // of strings by giving the slice the methods of Value; in particular, Set would
   863  // decompose the comma-separated string into the slice.
   864  func Var(value Value, name string, usage string) {
   865  	CommandLine.Var(value, name, usage)
   866  }
   867  
   868  // failf prints to standard error a formatted error and usage message and
   869  // returns the error.
   870  func (f *FlagSet) failf(format string, a ...interface{}) error {
   871  	err := fmt.Errorf(format, a...)
   872  	fmt.Fprintln(f.Output(), err)
   873  	f.usage()
   874  	return err
   875  }
   876  
   877  // usage calls the Usage method for the flag set if one is specified,
   878  // or the appropriate default usage function otherwise.
   879  func (f *FlagSet) usage() {
   880  	if f.Usage == nil {
   881  		f.defaultUsage()
   882  	} else {
   883  		f.Usage()
   884  	}
   885  }
   886  
   887  // parseOne parses one flag. It reports whether a flag was seen.
   888  func (f *FlagSet) parseOne() (bool, error) {
   889  	if len(f.args) == 0 {
   890  		return false, nil
   891  	}
   892  	s := f.args[0]
   893  	if len(s) < 2 || s[0] != '-' {
   894  		return false, nil
   895  	}
   896  	numMinuses := 1
   897  	if s[1] == '-' {
   898  		numMinuses++
   899  		if len(s) == 2 { // "--" terminates the flags
   900  			f.args = f.args[1:]
   901  			return false, nil
   902  		}
   903  	}
   904  	name := s[numMinuses:]
   905  	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
   906  		return false, f.failf("bad flag syntax: %s", s)
   907  	}
   908  
   909  	// it's a flag. does it have an argument?
   910  	f.args = f.args[1:]
   911  	hasValue := false
   912  	value := ""
   913  	for i := 1; i < len(name); i++ { // equals cannot be first
   914  		if name[i] == '=' {
   915  			value = name[i+1:]
   916  			hasValue = true
   917  			name = name[0:i]
   918  			break
   919  		}
   920  	}
   921  	m := f.formal
   922  	flag, alreadythere := m[name] // BUG
   923  	if !alreadythere {
   924  		if name == "help" || name == "h" { // special case for nice help message.
   925  			f.usage()
   926  			return false, ErrHelp
   927  		}
   928  		return false, f.failf("flag provided but not defined: -%s", name)
   929  	}
   930  
   931  	if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
   932  		if hasValue {
   933  			if err := fv.Set(value); err != nil {
   934  				return false, f.failf("invalid boolean value %q for -%s: %v", value, name, err)
   935  			}
   936  		} else {
   937  			if err := fv.Set("true"); err != nil {
   938  				return false, f.failf("invalid boolean flag %s: %v", name, err)
   939  			}
   940  		}
   941  	} else {
   942  		// It must have a value, which might be the next argument.
   943  		if !hasValue && len(f.args) > 0 {
   944  			// value is the next arg
   945  			hasValue = true
   946  			value, f.args = f.args[0], f.args[1:]
   947  		}
   948  		if !hasValue {
   949  			return false, f.failf("flag needs an argument: -%s", name)
   950  		}
   951  		if err := flag.Value.Set(value); err != nil {
   952  			return false, f.failf("invalid value %q for flag -%s: %v", value, name, err)
   953  		}
   954  	}
   955  	if f.actual == nil {
   956  		f.actual = make(map[string]*Flag)
   957  	}
   958  	f.actual[name] = flag
   959  	return true, nil
   960  }
   961  
   962  // Parse parses flag definitions from the argument list, which should not
   963  // include the command name. Must be called after all flags in the FlagSet
   964  // are defined and before flags are accessed by the program.
   965  // The return value will be ErrHelp if -help or -h were set but not defined.
   966  func (f *FlagSet) Parse(arguments []string) error {
   967  	f.parsed = true
   968  	f.args = arguments
   969  	for {
   970  		seen, err := f.parseOne()
   971  		if seen {
   972  			continue
   973  		}
   974  		if err == nil {
   975  			break
   976  		}
   977  		switch f.errorHandling {
   978  		case ContinueOnError:
   979  			return err
   980  		case ExitOnError:
   981  			os.Exit(2)
   982  		case PanicOnError:
   983  			panic(err)
   984  		}
   985  	}
   986  	return nil
   987  }
   988  
   989  // Parsed reports whether f.Parse has been called.
   990  func (f *FlagSet) Parsed() bool {
   991  	return f.parsed
   992  }
   993  
   994  // Parse parses the command-line flags from os.Args[1:]. Must be called
   995  // after all flags are defined and before flags are accessed by the program.
   996  func Parse() {
   997  	// Ignore errors; CommandLine is set for ExitOnError.
   998  	CommandLine.Parse(os.Args[1:])
   999  }
  1000  
  1001  // Parsed reports whether the command-line flags have been parsed.
  1002  func Parsed() bool {
  1003  	return CommandLine.Parsed()
  1004  }
  1005  
  1006  // CommandLine is the default set of command-line flags, parsed from os.Args.
  1007  // The top-level functions such as BoolVar, Arg, and so on are wrappers for the
  1008  // methods of CommandLine.
  1009  var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
  1010  
  1011  func init() {
  1012  	// Override generic FlagSet default Usage with call to global Usage.
  1013  	// Note: This is not CommandLine.Usage = Usage,
  1014  	// because we want any eventual call to use any updated value of Usage,
  1015  	// not the value it has when this line is run.
  1016  	CommandLine.Usage = commandLineUsage
  1017  }
  1018  
  1019  func commandLineUsage() {
  1020  	Usage()
  1021  }
  1022  
  1023  // NewFlagSet returns a new, empty flag set with the specified name and
  1024  // error handling property. If the name is not empty, it will be printed
  1025  // in the default usage message and in error messages.
  1026  func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
  1027  	f := &FlagSet{
  1028  		name:          name,
  1029  		errorHandling: errorHandling,
  1030  	}
  1031  	f.Usage = f.defaultUsage
  1032  	return f
  1033  }
  1034  
  1035  // Init sets the name and error handling property for a flag set.
  1036  // By default, the zero FlagSet uses an empty name and the
  1037  // ContinueOnError error handling policy.
  1038  func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
  1039  	f.name = name
  1040  	f.errorHandling = errorHandling
  1041  }
  1042  

View as plain text