...

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

View as plain text