Source file src/flag/flag.go

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

View as plain text