| // Copyright 2009 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| /* |
| Package flag implements command-line flag parsing. |
| |
| # Usage |
| |
| Define flags using flag.String(), Bool(), Int(), etc. |
| |
| This declares an integer flag, -n, stored in the pointer nFlag, with type *int: |
| |
| import "flag" |
| var nFlag = flag.Int("n", 1234, "help message for flag n") |
| |
| If you like, you can bind the flag to a variable using the Var() functions. |
| |
| var flagvar int |
| func init() { |
| flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname") |
| } |
| |
| Or you can create custom flags that satisfy the Value interface (with |
| pointer receivers) and couple them to flag parsing by |
| |
| flag.Var(&flagVal, "name", "help message for flagname") |
| |
| For such flags, the default value is just the initial value of the variable. |
| |
| After all flags are defined, call |
| |
| flag.Parse() |
| |
| to parse the command line into the defined flags. |
| |
| Flags may then be used directly. If you're using the flags themselves, |
| they are all pointers; if you bind to variables, they're values. |
| |
| fmt.Println("ip has value ", *ip) |
| fmt.Println("flagvar has value ", flagvar) |
| |
| After parsing, the arguments following the flags are available as the |
| slice flag.Args() or individually as flag.Arg(i). |
| The arguments are indexed from 0 through flag.NArg()-1. |
| |
| # Command line flag syntax |
| |
| The following forms are permitted: |
| |
| -flag |
| -flag=x |
| -flag x // non-boolean flags only |
| |
| One or two minus signs may be used; they are equivalent. |
| The last form is not permitted for boolean flags because the |
| meaning of the command |
| |
| cmd -x * |
| |
| where * is a Unix shell wildcard, will change if there is a file |
| called 0, false, etc. You must use the -flag=false form to turn |
| off a boolean flag. |
| |
| Flag parsing stops just before the first non-flag argument |
| ("-" is a non-flag argument) or after the terminator "--". |
| |
| Integer flags accept 1234, 0664, 0x1234 and may be negative. |
| Boolean flags may be: |
| |
| 1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False |
| |
| Duration flags accept any input valid for time.ParseDuration. |
| |
| The default set of command-line flags is controlled by |
| top-level functions. The FlagSet type allows one to define |
| independent sets of flags, such as to implement subcommands |
| in a command-line interface. The methods of FlagSet are |
| analogous to the top-level functions for the command-line |
| flag set. |
| */ |
| package flag |
| |
| import ( |
| "encoding" |
| "errors" |
| "fmt" |
| "io" |
| "os" |
| "reflect" |
| "sort" |
| "strconv" |
| "strings" |
| "time" |
| ) |
| |
| // ErrHelp is the error returned if the -help or -h flag is invoked |
| // but no such flag is defined. |
| var ErrHelp = errors.New("flag: help requested") |
| |
| // errParse is returned by Set if a flag's value fails to parse, such as with an invalid integer for Int. |
| // It then gets wrapped through failf to provide more information. |
| var errParse = errors.New("parse error") |
| |
| // errRange is returned by Set if a flag's value is out of range. |
| // It then gets wrapped through failf to provide more information. |
| var errRange = errors.New("value out of range") |
| |
| func numError(err error) error { |
| ne, ok := err.(*strconv.NumError) |
| if !ok { |
| return err |
| } |
| if ne.Err == strconv.ErrSyntax { |
| return errParse |
| } |
| if ne.Err == strconv.ErrRange { |
| return errRange |
| } |
| return err |
| } |
| |
| // -- bool Value |
| type boolValue bool |
| |
| func newBoolValue(val bool, p *bool) *boolValue { |
| *p = val |
| return (*boolValue)(p) |
| } |
| |
| func (b *boolValue) Set(s string) error { |
| v, err := strconv.ParseBool(s) |
| if err != nil { |
| err = errParse |
| } |
| *b = boolValue(v) |
| return err |
| } |
| |
| func (b *boolValue) Get() any { return bool(*b) } |
| |
| func (b *boolValue) String() string { return strconv.FormatBool(bool(*b)) } |
| |
| func (b *boolValue) IsBoolFlag() bool { return true } |
| |
| // optional interface to indicate boolean flags that can be |
| // supplied without "=value" text |
| type boolFlag interface { |
| Value |
| IsBoolFlag() bool |
| } |
| |
| // -- int Value |
| type intValue int |
| |
| func newIntValue(val int, p *int) *intValue { |
| *p = val |
| return (*intValue)(p) |
| } |
| |
| func (i *intValue) Set(s string) error { |
| v, err := strconv.ParseInt(s, 0, strconv.IntSize) |
| if err != nil { |
| err = numError(err) |
| } |
| *i = intValue(v) |
| return err |
| } |
| |
| func (i *intValue) Get() any { return int(*i) } |
| |
| func (i *intValue) String() string { return strconv.Itoa(int(*i)) } |
| |
| // -- int64 Value |
| type int64Value int64 |
| |
| func newInt64Value(val int64, p *int64) *int64Value { |
| *p = val |
| return (*int64Value)(p) |
| } |
| |
| func (i *int64Value) Set(s string) error { |
| v, err := strconv.ParseInt(s, 0, 64) |
| if err != nil { |
| err = numError(err) |
| } |
| *i = int64Value(v) |
| return err |
| } |
| |
| func (i *int64Value) Get() any { return int64(*i) } |
| |
| func (i *int64Value) String() string { return strconv.FormatInt(int64(*i), 10) } |
| |
| // -- uint Value |
| type uintValue uint |
| |
| func newUintValue(val uint, p *uint) *uintValue { |
| *p = val |
| return (*uintValue)(p) |
| } |
| |
| func (i *uintValue) Set(s string) error { |
| v, err := strconv.ParseUint(s, 0, strconv.IntSize) |
| if err != nil { |
| err = numError(err) |
| } |
| *i = uintValue(v) |
| return err |
| } |
| |
| func (i *uintValue) Get() any { return uint(*i) } |
| |
| func (i *uintValue) String() string { return strconv.FormatUint(uint64(*i), 10) } |
| |
| // -- uint64 Value |
| type uint64Value uint64 |
| |
| func newUint64Value(val uint64, p *uint64) *uint64Value { |
| *p = val |
| return (*uint64Value)(p) |
| } |
| |
| func (i *uint64Value) Set(s string) error { |
| v, err := strconv.ParseUint(s, 0, 64) |
| if err != nil { |
| err = numError(err) |
| } |
| *i = uint64Value(v) |
| return err |
| } |
| |
| func (i *uint64Value) Get() any { return uint64(*i) } |
| |
| func (i *uint64Value) String() string { return strconv.FormatUint(uint64(*i), 10) } |
| |
| // -- string Value |
| type stringValue string |
| |
| func newStringValue(val string, p *string) *stringValue { |
| *p = val |
| return (*stringValue)(p) |
| } |
| |
| func (s *stringValue) Set(val string) error { |
| *s = stringValue(val) |
| return nil |
| } |
| |
| func (s *stringValue) Get() any { return string(*s) } |
| |
| func (s *stringValue) String() string { return string(*s) } |
| |
| // -- float64 Value |
| type float64Value float64 |
| |
| func newFloat64Value(val float64, p *float64) *float64Value { |
| *p = val |
| return (*float64Value)(p) |
| } |
| |
| func (f *float64Value) Set(s string) error { |
| v, err := strconv.ParseFloat(s, 64) |
| if err != nil { |
| err = numError(err) |
| } |
| *f = float64Value(v) |
| return err |
| } |
| |
| func (f *float64Value) Get() any { return float64(*f) } |
| |
| func (f *float64Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 64) } |
| |
| // -- time.Duration Value |
| type durationValue time.Duration |
| |
| func newDurationValue(val time.Duration, p *time.Duration) *durationValue { |
| *p = val |
| return (*durationValue)(p) |
| } |
| |
| func (d *durationValue) Set(s string) error { |
| v, err := time.ParseDuration(s) |
| if err != nil { |
| err = errParse |
| } |
| *d = durationValue(v) |
| return err |
| } |
| |
| func (d *durationValue) Get() any { return time.Duration(*d) } |
| |
| func (d *durationValue) String() string { return (*time.Duration)(d).String() } |
| |
| // -- encoding.TextUnmarshaler Value |
| type textValue struct{ p encoding.TextUnmarshaler } |
| |
| func newTextValue(val encoding.TextMarshaler, p encoding.TextUnmarshaler) textValue { |
| ptrVal := reflect.ValueOf(p) |
| if ptrVal.Kind() != reflect.Ptr { |
| panic("variable value type must be a pointer") |
| } |
| defVal := reflect.ValueOf(val) |
| if defVal.Kind() == reflect.Ptr { |
| defVal = defVal.Elem() |
| } |
| if defVal.Type() != ptrVal.Type().Elem() { |
| panic(fmt.Sprintf("default type does not match variable type: %v != %v", defVal.Type(), ptrVal.Type().Elem())) |
| } |
| ptrVal.Elem().Set(defVal) |
| return textValue{p} |
| } |
| |
| func (v textValue) Set(s string) error { |
| return v.p.UnmarshalText([]byte(s)) |
| } |
| |
| func (v textValue) Get() interface{} { |
| return v.p |
| } |
| |
| func (v textValue) String() string { |
| if m, ok := v.p.(encoding.TextMarshaler); ok { |
| if b, err := m.MarshalText(); err == nil { |
| return string(b) |
| } |
| } |
| return "" |
| } |
| |
| // -- func Value |
| type funcValue func(string) error |
| |
| func (f funcValue) Set(s string) error { return f(s) } |
| |
| func (f funcValue) String() string { return "" } |
| |
| // Value is the interface to the dynamic value stored in a flag. |
| // (The default value is represented as a string.) |
| // |
| // If a Value has an IsBoolFlag() bool method returning true, |
| // the command-line parser makes -name equivalent to -name=true |
| // rather than using the next command-line argument. |
| // |
| // Set is called once, in command line order, for each flag present. |
| // The flag package may call the String method with a zero-valued receiver, |
| // such as a nil pointer. |
| type Value interface { |
| String() string |
| Set(string) error |
| } |
| |
| // Getter is an interface that allows the contents of a Value to be retrieved. |
| // It wraps the Value interface, rather than being part of it, because it |
| // appeared after Go 1 and its compatibility rules. All Value types provided |
| // by this package satisfy the Getter interface, except the type used by Func. |
| type Getter interface { |
| Value |
| Get() any |
| } |
| |
| // ErrorHandling defines how FlagSet.Parse behaves if the parse fails. |
| type ErrorHandling int |
| |
| // These constants cause FlagSet.Parse to behave as described if the parse fails. |
| const ( |
| ContinueOnError ErrorHandling = iota // Return a descriptive error. |
| ExitOnError // Call os.Exit(2) or for -h/-help Exit(0). |
| PanicOnError // Call panic with a descriptive error. |
| ) |
| |
| // A FlagSet represents a set of defined flags. The zero value of a FlagSet |
| // has no name and has ContinueOnError error handling. |
| // |
| // Flag names must be unique within a FlagSet. An attempt to define a flag whose |
| // name is already in use will cause a panic. |
| type FlagSet struct { |
| // Usage is the function called when an error occurs while parsing flags. |
| // The field is a function (not a method) that may be changed to point to |
| // a custom error handler. What happens after Usage is called depends |
| // on the ErrorHandling setting; for the command line, this defaults |
| // to ExitOnError, which exits the program after calling Usage. |
| Usage func() |
| |
| name string |
| parsed bool |
| actual map[string]*Flag |
| formal map[string]*Flag |
| args []string // arguments after flags |
| errorHandling ErrorHandling |
| output io.Writer // nil means stderr; use Output() accessor |
| } |
| |
| // A Flag represents the state of a flag. |
| type Flag struct { |
| Name string // name as it appears on command line |
| Usage string // help message |
| Value Value // value as set |
| DefValue string // default value (as text); for usage message |
| } |
| |
| // sortFlags returns the flags as a slice in lexicographical sorted order. |
| func sortFlags(flags map[string]*Flag) []*Flag { |
| result := make([]*Flag, len(flags)) |
| i := 0 |
| for _, f := range flags { |
| result[i] = f |
| i++ |
| } |
| sort.Slice(result, func(i, j int) bool { |
| return result[i].Name < result[j].Name |
| }) |
| return result |
| } |
| |
| // Output returns the destination for usage and error messages. os.Stderr is returned if |
| // output was not set or was set to nil. |
| func (f *FlagSet) Output() io.Writer { |
| if f.output == nil { |
| return os.Stderr |
| } |
| return f.output |
| } |
| |
| // Name returns the name of the flag set. |
| func (f *FlagSet) Name() string { |
| return f.name |
| } |
| |
| // ErrorHandling returns the error handling behavior of the flag set. |
| func (f *FlagSet) ErrorHandling() ErrorHandling { |
| return f.errorHandling |
| } |
| |
| // SetOutput sets the destination for usage and error messages. |
| // If output is nil, os.Stderr is used. |
| func (f *FlagSet) SetOutput(output io.Writer) { |
| f.output = output |
| } |
| |
| // VisitAll visits the flags in lexicographical order, calling fn for each. |
| // It visits all flags, even those not set. |
| func (f *FlagSet) VisitAll(fn func(*Flag)) { |
| for _, flag := range sortFlags(f.formal) { |
| fn(flag) |
| } |
| } |
| |
| // VisitAll visits the command-line flags in lexicographical order, calling |
| // fn for each. It visits all flags, even those not set. |
| func VisitAll(fn func(*Flag)) { |
| CommandLine.VisitAll(fn) |
| } |
| |
| // Visit visits the flags in lexicographical order, calling fn for each. |
| // It visits only those flags that have been set. |
| func (f *FlagSet) Visit(fn func(*Flag)) { |
| for _, flag := range sortFlags(f.actual) { |
| fn(flag) |
| } |
| } |
| |
| // Visit visits the command-line flags in lexicographical order, calling fn |
| // for each. It visits only those flags that have been set. |
| func Visit(fn func(*Flag)) { |
| CommandLine.Visit(fn) |
| } |
| |
| // Lookup returns the Flag structure of the named flag, returning nil if none exists. |
| func (f *FlagSet) Lookup(name string) *Flag { |
| return f.formal[name] |
| } |
| |
| // Lookup returns the Flag structure of the named command-line flag, |
| // returning nil if none exists. |
| func Lookup(name string) *Flag { |
| return CommandLine.formal[name] |
| } |
| |
| // Set sets the value of the named flag. |
| func (f *FlagSet) Set(name, value string) error { |
| flag, ok := f.formal[name] |
| if !ok { |
| return fmt.Errorf("no such flag -%v", name) |
| } |
| err := flag.Value.Set(value) |
| if err != nil { |
| return err |
| } |
| if f.actual == nil { |
| f.actual = make(map[string]*Flag) |
| } |
| f.actual[name] = flag |
| return nil |
| } |
| |
| // Set sets the value of the named command-line flag. |
| func Set(name, value string) error { |
| return CommandLine.Set(name, value) |
| } |
| |
| // isZeroValue determines whether the string represents the zero |
| // value for a flag. |
| func isZeroValue(flag *Flag, value string) (ok bool, err error) { |
| // Build a zero value of the flag's Value type, and see if the |
| // result of calling its String method equals the value passed in. |
| // This works unless the Value type is itself an interface type. |
| typ := reflect.TypeOf(flag.Value) |
| var z reflect.Value |
| if typ.Kind() == reflect.Pointer { |
| z = reflect.New(typ.Elem()) |
| } else { |
| z = reflect.Zero(typ) |
| } |
| // Catch panics calling the String method, which shouldn't prevent the |
| // usage message from being printed, but that we should report to the |
| // user so that they know to fix their code. |
| defer func() { |
| if e := recover(); e != nil { |
| if typ.Kind() == reflect.Pointer { |
| typ = typ.Elem() |
| } |
| err = fmt.Errorf("panic calling String method on zero %v for flag %s: %v", typ, flag.Name, e) |
| } |
| }() |
| return value == z.Interface().(Value).String(), nil |
| } |
| |
| // UnquoteUsage extracts a back-quoted name from the usage |
| // string for a flag and returns it and the un-quoted usage. |
| // Given "a `name` to show" it returns ("name", "a name to show"). |
| // If there are no back quotes, the name is an educated guess of the |
| // type of the flag's value, or the empty string if the flag is boolean. |
| func UnquoteUsage(flag *Flag) (name string, usage string) { |
| // Look for a back-quoted name, but avoid the strings package. |
| usage = flag.Usage |
| for i := 0; i < len(usage); i++ { |
| if usage[i] == '`' { |
| for j := i + 1; j < len(usage); j++ { |
| if usage[j] == '`' { |
| name = usage[i+1 : j] |
| usage = usage[:i] + name + usage[j+1:] |
| return name, usage |
| } |
| } |
| break // Only one back quote; use type name. |
| } |
| } |
| // No explicit name, so use type if we can find one. |
| name = "value" |
| switch flag.Value.(type) { |
| case boolFlag: |
| name = "" |
| case *durationValue: |
| name = "duration" |
| case *float64Value: |
| name = "float" |
| case *intValue, *int64Value: |
| name = "int" |
| case *stringValue: |
| name = "string" |
| case *uintValue, *uint64Value: |
| name = "uint" |
| } |
| return |
| } |
| |
| // PrintDefaults prints, to standard error unless configured otherwise, the |
| // default values of all defined command-line flags in the set. See the |
| // documentation for the global function PrintDefaults for more information. |
| func (f *FlagSet) PrintDefaults() { |
| var isZeroValueErrs []error |
| f.VisitAll(func(flag *Flag) { |
| var b strings.Builder |
| fmt.Fprintf(&b, " -%s", flag.Name) // Two spaces before -; see next two comments. |
| name, usage := UnquoteUsage(flag) |
| if len(name) > 0 { |
| b.WriteString(" ") |
| b.WriteString(name) |
| } |
| // Boolean flags of one ASCII letter are so common we |
| // treat them specially, putting their usage on the same line. |
| if b.Len() <= 4 { // space, space, '-', 'x'. |
| b.WriteString("\t") |
| } else { |
| // Four spaces before the tab triggers good alignment |
| // for both 4- and 8-space tab stops. |
| b.WriteString("\n \t") |
| } |
| b.WriteString(strings.ReplaceAll(usage, "\n", "\n \t")) |
| |
| // Print the default value only if it differs to the zero value |
| // for this flag type. |
| if isZero, err := isZeroValue(flag, flag.DefValue); err != nil { |
| isZeroValueErrs = append(isZeroValueErrs, err) |
| } else if !isZero { |
| if _, ok := flag.Value.(*stringValue); ok { |
| // put quotes on the value |
| fmt.Fprintf(&b, " (default %q)", flag.DefValue) |
| } else { |
| fmt.Fprintf(&b, " (default %v)", flag.DefValue) |
| } |
| } |
| fmt.Fprint(f.Output(), b.String(), "\n") |
| }) |
| // If calling String on any zero flag.Values triggered a panic, print |
| // the messages after the full set of defaults so that the programmer |
| // knows to fix the panic. |
| if errs := isZeroValueErrs; len(errs) > 0 { |
| fmt.Fprintln(f.Output()) |
| for _, err := range errs { |
| fmt.Fprintln(f.Output(), err) |
| } |
| } |
| } |
| |
| // PrintDefaults prints, to standard error unless configured otherwise, |
| // a usage message showing the default settings of all defined |
| // command-line flags. |
| // For an integer valued flag x, the default output has the form |
| // |
| // -x int |
| // usage-message-for-x (default 7) |
| // |
| // The usage message will appear on a separate line for anything but |
| // a bool flag with a one-byte name. For bool flags, the type is |
| // omitted and if the flag name is one byte the usage message appears |
| // on the same line. The parenthetical default is omitted if the |
| // default is the zero value for the type. The listed type, here int, |
| // can be changed by placing a back-quoted name in the flag's usage |
| // string; the first such item in the message is taken to be a parameter |
| // name to show in the message and the back quotes are stripped from |
| // the message when displayed. For instance, given |
| // |
| // flag.String("I", "", "search `directory` for include files") |
| // |
| // the output will be |
| // |
| // -I directory |
| // search directory for include files. |
| // |
| // To change the destination for flag messages, call CommandLine.SetOutput. |
| func PrintDefaults() { |
| CommandLine.PrintDefaults() |
| } |
| |
| // defaultUsage is the default function to print a usage message. |
| func (f *FlagSet) defaultUsage() { |
| if f.name == "" { |
| fmt.Fprintf(f.Output(), "Usage:\n") |
| } else { |
| fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name) |
| } |
| f.PrintDefaults() |
| } |
| |
| // NOTE: Usage is not just defaultUsage(CommandLine) |
| // because it serves (via godoc flag Usage) as the example |
| // for how to write your own usage function. |
| |
| // Usage prints a usage message documenting all defined command-line flags |
| // to CommandLine's output, which by default is os.Stderr. |
| // It is called when an error occurs while parsing flags. |
| // The function is a variable that may be changed to point to a custom function. |
| // By default it prints a simple header and calls PrintDefaults; for details about the |
| // format of the output and how to control it, see the documentation for PrintDefaults. |
| // Custom usage functions may choose to exit the program; by default exiting |
| // happens anyway as the command line's error handling strategy is set to |
| // ExitOnError. |
| var Usage = func() { |
| fmt.Fprintf(CommandLine.Output(), "Usage of %s:\n", os.Args[0]) |
| PrintDefaults() |
| } |
| |
| // NFlag returns the number of flags that have been set. |
| func (f *FlagSet) NFlag() int { return len(f.actual) } |
| |
| // NFlag returns the number of command-line flags that have been set. |
| func NFlag() int { return len(CommandLine.actual) } |
| |
| // Arg returns the i'th argument. Arg(0) is the first remaining argument |
| // after flags have been processed. Arg returns an empty string if the |
| // requested element does not exist. |
| func (f *FlagSet) Arg(i int) string { |
| if i < 0 || i >= len(f.args) { |
| return "" |
| } |
| return f.args[i] |
| } |
| |
| // Arg returns the i'th command-line argument. Arg(0) is the first remaining argument |
| // after flags have been processed. Arg returns an empty string if the |
| // requested element does not exist. |
| func Arg(i int) string { |
| return CommandLine.Arg(i) |
| } |
| |
| // NArg is the number of arguments remaining after flags have been processed. |
| func (f *FlagSet) NArg() int { return len(f.args) } |
| |
| // NArg is the number of arguments remaining after flags have been processed. |
| func NArg() int { return len(CommandLine.args) } |
| |
| // Args returns the non-flag arguments. |
| func (f *FlagSet) Args() []string { return f.args } |
| |
| // Args returns the non-flag command-line arguments. |
| func Args() []string { return CommandLine.args } |
| |
| // BoolVar defines a bool flag with specified name, default value, and usage string. |
| // The argument p points to a bool variable in which to store the value of the flag. |
| func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) { |
| f.Var(newBoolValue(value, p), name, usage) |
| } |
| |
| // BoolVar defines a bool flag with specified name, default value, and usage string. |
| // The argument p points to a bool variable in which to store the value of the flag. |
| func BoolVar(p *bool, name string, value bool, usage string) { |
| CommandLine.Var(newBoolValue(value, p), name, usage) |
| } |
| |
| // Bool defines a bool flag with specified name, default value, and usage string. |
| // The return value is the address of a bool variable that stores the value of the flag. |
| func (f *FlagSet) Bool(name string, value bool, usage string) *bool { |
| p := new(bool) |
| f.BoolVar(p, name, value, usage) |
| return p |
| } |
| |
| // Bool defines a bool flag with specified name, default value, and usage string. |
| // The return value is the address of a bool variable that stores the value of the flag. |
| func Bool(name string, value bool, usage string) *bool { |
| return CommandLine.Bool(name, value, usage) |
| } |
| |
| // IntVar defines an int flag with specified name, default value, and usage string. |
| // The argument p points to an int variable in which to store the value of the flag. |
| func (f *FlagSet) IntVar(p *int, name string, value int, usage string) { |
| f.Var(newIntValue(value, p), name, usage) |
| } |
| |
| // IntVar defines an int flag with specified name, default value, and usage string. |
| // The argument p points to an int variable in which to store the value of the flag. |
| func IntVar(p *int, name string, value int, usage string) { |
| CommandLine.Var(newIntValue(value, p), name, usage) |
| } |
| |
| // Int defines an int flag with specified name, default value, and usage string. |
| // The return value is the address of an int variable that stores the value of the flag. |
| func (f *FlagSet) Int(name string, value int, usage string) *int { |
| p := new(int) |
| f.IntVar(p, name, value, usage) |
| return p |
| } |
| |
| // Int defines an int flag with specified name, default value, and usage string. |
| // The return value is the address of an int variable that stores the value of the flag. |
| func Int(name string, value int, usage string) *int { |
| return CommandLine.Int(name, value, usage) |
| } |
| |
| // Int64Var defines an int64 flag with specified name, default value, and usage string. |
| // The argument p points to an int64 variable in which to store the value of the flag. |
| func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) { |
| f.Var(newInt64Value(value, p), name, usage) |
| } |
| |
| // Int64Var defines an int64 flag with specified name, default value, and usage string. |
| // The argument p points to an int64 variable in which to store the value of the flag. |
| func Int64Var(p *int64, name string, value int64, usage string) { |
| CommandLine.Var(newInt64Value(value, p), name, usage) |
| } |
| |
| // Int64 defines an int64 flag with specified name, default value, and usage string. |
| // The return value is the address of an int64 variable that stores the value of the flag. |
| func (f *FlagSet) Int64(name string, value int64, usage string) *int64 { |
| p := new(int64) |
| f.Int64Var(p, name, value, usage) |
| return p |
| } |
| |
| // Int64 defines an int64 flag with specified name, default value, and usage string. |
| // The return value is the address of an int64 variable that stores the value of the flag. |
| func Int64(name string, value int64, usage string) *int64 { |
| return CommandLine.Int64(name, value, usage) |
| } |
| |
| // UintVar defines a uint flag with specified name, default value, and usage string. |
| // The argument p points to a uint variable in which to store the value of the flag. |
| func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) { |
| f.Var(newUintValue(value, p), name, usage) |
| } |
| |
| // UintVar defines a uint flag with specified name, default value, and usage string. |
| // The argument p points to a uint variable in which to store the value of the flag. |
| func UintVar(p *uint, name string, value uint, usage string) { |
| CommandLine.Var(newUintValue(value, p), name, usage) |
| } |
| |
| // Uint defines a uint flag with specified name, default value, and usage string. |
| // The return value is the address of a uint variable that stores the value of the flag. |
| func (f *FlagSet) Uint(name string, value uint, usage string) *uint { |
| p := new(uint) |
| f.UintVar(p, name, value, usage) |
| return p |
| } |
| |
| // Uint defines a uint flag with specified name, default value, and usage string. |
| // The return value is the address of a uint variable that stores the value of the flag. |
| func Uint(name string, value uint, usage string) *uint { |
| return CommandLine.Uint(name, value, usage) |
| } |
| |
| // Uint64Var defines a uint64 flag with specified name, default value, and usage string. |
| // The argument p points to a uint64 variable in which to store the value of the flag. |
| func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) { |
| f.Var(newUint64Value(value, p), name, usage) |
| } |
| |
| // Uint64Var defines a uint64 flag with specified name, default value, and usage string. |
| // The argument p points to a uint64 variable in which to store the value of the flag. |
| func Uint64Var(p *uint64, name string, value uint64, usage string) { |
| CommandLine.Var(newUint64Value(value, p), name, usage) |
| } |
| |
| // Uint64 defines a uint64 flag with specified name, default value, and usage string. |
| // The return value is the address of a uint64 variable that stores the value of the flag. |
| func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 { |
| p := new(uint64) |
| f.Uint64Var(p, name, value, usage) |
| return p |
| } |
| |
| // Uint64 defines a uint64 flag with specified name, default value, and usage string. |
| // The return value is the address of a uint64 variable that stores the value of the flag. |
| func Uint64(name string, value uint64, usage string) *uint64 { |
| return CommandLine.Uint64(name, value, usage) |
| } |
| |
| // StringVar defines a string flag with specified name, default value, and usage string. |
| // The argument p points to a string variable in which to store the value of the flag. |
| func (f *FlagSet) StringVar(p *string, name string, value string, usage string) { |
| f.Var(newStringValue(value, p), name, usage) |
| } |
| |
| // StringVar defines a string flag with specified name, default value, and usage string. |
| // The argument p points to a string variable in which to store the value of the flag. |
| func StringVar(p *string, name string, value string, usage string) { |
| CommandLine.Var(newStringValue(value, p), name, usage) |
| } |
| |
| // String defines a string flag with specified name, default value, and usage string. |
| // The return value is the address of a string variable that stores the value of the flag. |
| func (f *FlagSet) String(name string, value string, usage string) *string { |
| p := new(string) |
| f.StringVar(p, name, value, usage) |
| return p |
| } |
| |
| // String defines a string flag with specified name, default value, and usage string. |
| // The return value is the address of a string variable that stores the value of the flag. |
| func String(name string, value string, usage string) *string { |
| return CommandLine.String(name, value, usage) |
| } |
| |
| // Float64Var defines a float64 flag with specified name, default value, and usage string. |
| // The argument p points to a float64 variable in which to store the value of the flag. |
| func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) { |
| f.Var(newFloat64Value(value, p), name, usage) |
| } |
| |
| // Float64Var defines a float64 flag with specified name, default value, and usage string. |
| // The argument p points to a float64 variable in which to store the value of the flag. |
| func Float64Var(p *float64, name string, value float64, usage string) { |
| CommandLine.Var(newFloat64Value(value, p), name, usage) |
| } |
| |
| // Float64 defines a float64 flag with specified name, default value, and usage string. |
| // The return value is the address of a float64 variable that stores the value of the flag. |
| func (f *FlagSet) Float64(name string, value float64, usage string) *float64 { |
| p := new(float64) |
| f.Float64Var(p, name, value, usage) |
| return p |
| } |
| |
| // Float64 defines a float64 flag with specified name, default value, and usage string. |
| // The return value is the address of a float64 variable that stores the value of the flag. |
| func Float64(name string, value float64, usage string) *float64 { |
| return CommandLine.Float64(name, value, usage) |
| } |
| |
| // DurationVar defines a time.Duration flag with specified name, default value, and usage string. |
| // The argument p points to a time.Duration variable in which to store the value of the flag. |
| // The flag accepts a value acceptable to time.ParseDuration. |
| func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) { |
| f.Var(newDurationValue(value, p), name, usage) |
| } |
| |
| // DurationVar defines a time.Duration flag with specified name, default value, and usage string. |
| // The argument p points to a time.Duration variable in which to store the value of the flag. |
| // The flag accepts a value acceptable to time.ParseDuration. |
| func DurationVar(p *time.Duration, name string, value time.Duration, usage string) { |
| CommandLine.Var(newDurationValue(value, p), name, usage) |
| } |
| |
| // Duration defines a time.Duration flag with specified name, default value, and usage string. |
| // The return value is the address of a time.Duration variable that stores the value of the flag. |
| // The flag accepts a value acceptable to time.ParseDuration. |
| func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration { |
| p := new(time.Duration) |
| f.DurationVar(p, name, value, usage) |
| return p |
| } |
| |
| // Duration defines a time.Duration flag with specified name, default value, and usage string. |
| // The return value is the address of a time.Duration variable that stores the value of the flag. |
| // The flag accepts a value acceptable to time.ParseDuration. |
| func Duration(name string, value time.Duration, usage string) *time.Duration { |
| return CommandLine.Duration(name, value, usage) |
| } |
| |
| // TextVar defines a flag with a specified name, default value, and usage string. |
| // The argument p must be a pointer to a variable that will hold the value |
| // of the flag, and p must implement encoding.TextUnmarshaler. |
| // If the flag is used, the flag value will be passed to p's UnmarshalText method. |
| // The type of the default value must be the same as the type of p. |
| func (f *FlagSet) TextVar(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string) { |
| f.Var(newTextValue(value, p), name, usage) |
| } |
| |
| // TextVar defines a flag with a specified name, default value, and usage string. |
| // The argument p must be a pointer to a variable that will hold the value |
| // of the flag, and p must implement encoding.TextUnmarshaler. |
| // If the flag is used, the flag value will be passed to p's UnmarshalText method. |
| // The type of the default value must be the same as the type of p. |
| func TextVar(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string) { |
| CommandLine.Var(newTextValue(value, p), name, usage) |
| } |
| |
| // Func defines a flag with the specified name and usage string. |
| // Each time the flag is seen, fn is called with the value of the flag. |
| // If fn returns a non-nil error, it will be treated as a flag value parsing error. |
| func (f *FlagSet) Func(name, usage string, fn func(string) error) { |
| f.Var(funcValue(fn), name, usage) |
| } |
| |
| // Func defines a flag with the specified name and usage string. |
| // Each time the flag is seen, fn is called with the value of the flag. |
| // If fn returns a non-nil error, it will be treated as a flag value parsing error. |
| func Func(name, usage string, fn func(string) error) { |
| CommandLine.Func(name, usage, fn) |
| } |
| |
| // Var defines a flag with the specified name and usage string. The type and |
| // value of the flag are represented by the first argument, of type Value, which |
| // typically holds a user-defined implementation of Value. For instance, the |
| // caller could create a flag that turns a comma-separated string into a slice |
| // of strings by giving the slice the methods of Value; in particular, Set would |
| // decompose the comma-separated string into the slice. |
| func (f *FlagSet) Var(value Value, name string, usage string) { |
| // Flag must not begin "-" or contain "=". |
| if strings.HasPrefix(name, "-") { |
| panic(f.sprintf("flag %q begins with -", name)) |
| } else if strings.Contains(name, "=") { |
| panic(f.sprintf("flag %q contains =", name)) |
| } |
| |
| // Remember the default value as a string; it won't change. |
| flag := &Flag{name, usage, value, value.String()} |
| _, alreadythere := f.formal[name] |
| if alreadythere { |
| var msg string |
| if f.name == "" { |
| msg = f.sprintf("flag redefined: %s", name) |
| } else { |
| msg = f.sprintf("%s flag redefined: %s", f.name, name) |
| } |
| panic(msg) // Happens only if flags are declared with identical names |
| } |
| if f.formal == nil { |
| f.formal = make(map[string]*Flag) |
| } |
| f.formal[name] = flag |
| } |
| |
| // Var defines a flag with the specified name and usage string. The type and |
| // value of the flag are represented by the first argument, of type Value, which |
| // typically holds a user-defined implementation of Value. For instance, the |
| // caller could create a flag that turns a comma-separated string into a slice |
| // of strings by giving the slice the methods of Value; in particular, Set would |
| // decompose the comma-separated string into the slice. |
| func Var(value Value, name string, usage string) { |
| CommandLine.Var(value, name, usage) |
| } |
| |
| // sprintf formats the message, prints it to output, and returns it. |
| func (f *FlagSet) sprintf(format string, a ...any) string { |
| msg := fmt.Sprintf(format, a...) |
| fmt.Fprintln(f.Output(), msg) |
| return msg |
| } |
| |
| // failf prints to standard error a formatted error and usage message and |
| // returns the error. |
| func (f *FlagSet) failf(format string, a ...any) error { |
| msg := f.sprintf(format, a...) |
| f.usage() |
| return errors.New(msg) |
| } |
| |
| // usage calls the Usage method for the flag set if one is specified, |
| // or the appropriate default usage function otherwise. |
| func (f *FlagSet) usage() { |
| if f.Usage == nil { |
| f.defaultUsage() |
| } else { |
| f.Usage() |
| } |
| } |
| |
| // parseOne parses one flag. It reports whether a flag was seen. |
| func (f *FlagSet) parseOne() (bool, error) { |
| if len(f.args) == 0 { |
| return false, nil |
| } |
| s := f.args[0] |
| if len(s) < 2 || s[0] != '-' { |
| return false, nil |
| } |
| numMinuses := 1 |
| if s[1] == '-' { |
| numMinuses++ |
| if len(s) == 2 { // "--" terminates the flags |
| f.args = f.args[1:] |
| return false, nil |
| } |
| } |
| name := s[numMinuses:] |
| if len(name) == 0 || name[0] == '-' || name[0] == '=' { |
| return false, f.failf("bad flag syntax: %s", s) |
| } |
| |
| // it's a flag. does it have an argument? |
| f.args = f.args[1:] |
| hasValue := false |
| value := "" |
| for i := 1; i < len(name); i++ { // equals cannot be first |
| if name[i] == '=' { |
| value = name[i+1:] |
| hasValue = true |
| name = name[0:i] |
| break |
| } |
| } |
| m := f.formal |
| flag, alreadythere := m[name] // BUG |
| if !alreadythere { |
| if name == "help" || name == "h" { // special case for nice help message. |
| f.usage() |
| return false, ErrHelp |
| } |
| return false, f.failf("flag provided but not defined: -%s", name) |
| } |
| |
| if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg |
| if hasValue { |
| if err := fv.Set(value); err != nil { |
| return false, f.failf("invalid boolean value %q for -%s: %v", value, name, err) |
| } |
| } else { |
| if err := fv.Set("true"); err != nil { |
| return false, f.failf("invalid boolean flag %s: %v", name, err) |
| } |
| } |
| } else { |
| // It must have a value, which might be the next argument. |
| if !hasValue && len(f.args) > 0 { |
| // value is the next arg |
| hasValue = true |
| value, f.args = f.args[0], f.args[1:] |
| } |
| if !hasValue { |
| return false, f.failf("flag needs an argument: -%s", name) |
| } |
| if err := flag.Value.Set(value); err != nil { |
| return false, f.failf("invalid value %q for flag -%s: %v", value, name, err) |
| } |
| } |
| if f.actual == nil { |
| f.actual = make(map[string]*Flag) |
| } |
| f.actual[name] = flag |
| return true, nil |
| } |
| |
| // Parse parses flag definitions from the argument list, which should not |
| // include the command name. Must be called after all flags in the FlagSet |
| // are defined and before flags are accessed by the program. |
| // The return value will be ErrHelp if -help or -h were set but not defined. |
| func (f *FlagSet) Parse(arguments []string) error { |
| f.parsed = true |
| f.args = arguments |
| for { |
| seen, err := f.parseOne() |
| if seen { |
| continue |
| } |
| if err == nil { |
| break |
| } |
| switch f.errorHandling { |
| case ContinueOnError: |
| return err |
| case ExitOnError: |
| if err == ErrHelp { |
| os.Exit(0) |
| } |
| os.Exit(2) |
| case PanicOnError: |
| panic(err) |
| } |
| } |
| return nil |
| } |
| |
| // Parsed reports whether f.Parse has been called. |
| func (f *FlagSet) Parsed() bool { |
| return f.parsed |
| } |
| |
| // Parse parses the command-line flags from os.Args[1:]. Must be called |
| // after all flags are defined and before flags are accessed by the program. |
| func Parse() { |
| // Ignore errors; CommandLine is set for ExitOnError. |
| CommandLine.Parse(os.Args[1:]) |
| } |
| |
| // Parsed reports whether the command-line flags have been parsed. |
| func Parsed() bool { |
| return CommandLine.Parsed() |
| } |
| |
| // CommandLine is the default set of command-line flags, parsed from os.Args. |
| // The top-level functions such as BoolVar, Arg, and so on are wrappers for the |
| // methods of CommandLine. |
| var CommandLine = NewFlagSet(os.Args[0], ExitOnError) |
| |
| func init() { |
| // Override generic FlagSet default Usage with call to global Usage. |
| // Note: This is not CommandLine.Usage = Usage, |
| // because we want any eventual call to use any updated value of Usage, |
| // not the value it has when this line is run. |
| CommandLine.Usage = commandLineUsage |
| } |
| |
| func commandLineUsage() { |
| Usage() |
| } |
| |
| // NewFlagSet returns a new, empty flag set with the specified name and |
| // error handling property. If the name is not empty, it will be printed |
| // in the default usage message and in error messages. |
| func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet { |
| f := &FlagSet{ |
| name: name, |
| errorHandling: errorHandling, |
| } |
| f.Usage = f.defaultUsage |
| return f |
| } |
| |
| // Init sets the name and error handling property for a flag set. |
| // By default, the zero FlagSet uses an empty name and the |
| // ContinueOnError error handling policy. |
| func (f *FlagSet) Init(name string, errorHandling ErrorHandling) { |
| f.name = name |
| f.errorHandling = errorHandling |
| } |