github.com/puellanivis/breton@v0.2.16/lib/gnuflag/flag.go (about)

     1  // Code generated by THIS IS A DERIVATIVE OF OTHER PEOPLES CODE AND golint CANNOT BE TURNED OFF. DO NOT EDIT.
     2  // Copyright 2009 The Go Authors. All rights reserved.
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSE file.
     5  
     6  /*
     7  Package gnuflag implements command-line flag parsing compatible with GNU longopts.
     8  
     9  Usage:
    10  
    11  Define flags using flag.String(), Bool(), Int(), etc.
    12  
    13  This declares an integer flag, --flagname, with short flagname -f stored in the pointer ip, with type *int.
    14  
    15  	import flag "github.com/puellanivis/breton/lib/gnuflag"
    16  	var ip = flag.Int("flagname", 1234, "help message for flagname", flag.WithShort('f'))
    17  
    18  Or you can create custom flags that satisfy the Value interface (with
    19  pointer receivers) and couple them to flag parsing by
    20  
    21  	flag.Var(&flagVal, "name", "help message for flagname")
    22  
    23  For such flags, the default value is just the initial value of the variable.
    24  
    25  After all flags are defined, call
    26  
    27  	flag.Parse()
    28  
    29  to parse the command line into the defined flags.
    30  
    31  Flags may then be used directly. If you're using the flags themselves,
    32  they are all pointers; if you bind to variables, they're values.
    33  
    34  	fmt.Println("ip has value ", *ip)
    35  	fmt.Println("flagvar has value ", flagvar)
    36  
    37  After parsing, the arguments following the flags are available as the
    38  slice flag.Args() or individually as flag.Arg(i).
    39  The arguments are indexed from 0 through flag.NArg()-1.
    40  
    41  Command line flag syntax:
    42  
    43  	-f    --flag
    44  	-f=x  --flag=x
    45  	-f x  --flag x  // non-boolean flags only
    46  
    47  One minus sign signifies a short flag, while two indicates a long name.
    48  The last form is not permitted for boolean flags because the
    49  meaning of the commands
    50  
    51  	cmd --flag *
    52  	cmd -f *
    53  
    54  where * is a Unix shell wildcard, will change if there is a file
    55  called 0, false, etc.  You must use the --flag=false or -f=false
    56  form to turn off a boolean flag.
    57  
    58  Flag parsing stops just before the first non-flag argument
    59  ("-" is a non-flag argument) or just after the terminator "--".
    60  
    61  Integer flags accept 1234, 0664, 0x1234 and may be negative.
    62  Boolean flags may be:
    63  
    64  	1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False
    65  
    66  Duration flags accept any input valid for time.ParseDuration.
    67  
    68  The default set of command-line flags is controlled by
    69  top-level functions.  The FlagSet type allows one to define
    70  independent sets of flags, such as to implement subcommands
    71  in a command-line interface. The methods of FlagSet are
    72  analogous to the top-level functions for the command-line
    73  flag set.
    74  */
    75  package gnuflag
    76  
    77  import (
    78  	"errors"
    79  	"fmt"
    80  	"io"
    81  	"os"
    82  	"reflect"
    83  	"sort"
    84  	"strings"
    85  	"unicode/utf8"
    86  )
    87  
    88  // ErrHelp is the error returned if the --help or -? flag is invoked
    89  // but no such flag is defined.
    90  var ErrHelp = errors.New("flag: help requested")
    91  
    92  // Value is the interface to the dynamic value stored in a flag.
    93  // (The default value is represented as a string.)
    94  //
    95  // If a Value has an IsBoolFlag() bool method returning true,
    96  // the command-line parser makes --name equivalent to --name=true
    97  // rather than using the next command-line argument.
    98  //
    99  // Additionally, if the flag has a WithShort() alternative, then
   100  // -f is equilvalent to -f=true, and can appear in the non-last
   101  // position of a -shortFlagSeries.
   102  //
   103  // Set is called once, in command line order, for each flag present.
   104  // The flag package may call the String method with a zero-valued receiver,
   105  // such as a nil pointer.
   106  type Value interface {
   107  	String() string
   108  
   109  	Set(string) error
   110  	Get() interface{}
   111  }
   112  
   113  // ErrorHandling defines how FlagSet.Parse behaves if the parse fails.
   114  type ErrorHandling int
   115  
   116  // These constants cause FlagSet.Parse to behave as described if the parse fails.
   117  const (
   118  	ContinueOnError ErrorHandling = iota // Return a descriptive error.
   119  	ExitOnError                          // Call os.Exit(2).
   120  	PanicOnError                         // Call panic with a descriptive error.
   121  )
   122  
   123  // A FlagSet represents a set of defined flags. The zero value of a FlagSet
   124  // has no name and has ContinueOnError error handling.
   125  type FlagSet struct {
   126  	// Usage is the function called when an error occurs while parsing flags.
   127  	// The field is a function (not a method) that may be changed to point to
   128  	// a custom error handler. What happens after Usage is called depends
   129  	// on the ErrorHandling setting; for the command line, this defaults
   130  	// to ExitOnError, which exits the program after calling Usage.
   131  	Usage func()
   132  
   133  	name   string
   134  	parsed bool
   135  
   136  	actual map[string]*Flag
   137  	formal map[string]*Flag
   138  	short  map[rune]*Flag
   139  
   140  	args          []string // arguments after flags
   141  	errorHandling ErrorHandling
   142  	output        io.Writer // nil means stderr; use out() accessor
   143  }
   144  
   145  // A Flag represents the state of a flag.
   146  type Flag struct {
   147  	Name     string // name as it appears on command line
   148  	Short    rune   // short flag as it appears on command line
   149  	Usage    string // help message
   150  	Value    Value  // value as set
   151  	DefValue string // default value (as text); for usage message
   152  }
   153  
   154  // sortFlags returns the flags as a slice in lexicographical sorted order.
   155  func sortFlags(flags map[string]*Flag) []*Flag {
   156  	list := make(sort.StringSlice, len(flags))
   157  
   158  	i := 0
   159  	for name := range flags {
   160  		list[i] = name
   161  		i++
   162  	}
   163  
   164  	list.Sort()
   165  
   166  	result := make([]*Flag, len(list))
   167  	for i, name := range list {
   168  		result[i] = flags[name]
   169  	}
   170  
   171  	return result
   172  }
   173  
   174  // Output returns the destination for usage and error messages. os.Stderr is returned if
   175  // output was not set or was set to nil.
   176  func (f *FlagSet) Output() io.Writer {
   177  	if f.output == nil {
   178  		return os.Stderr
   179  	}
   180  	return f.output
   181  }
   182  
   183  // Name returns the name of the flag set.
   184  func (f *FlagSet) Name() string {
   185  	return f.name
   186  }
   187  
   188  // ErrorHandling returns the error handling behavior of the flag set.
   189  func (f *FlagSet) ErrorHandling() ErrorHandling {
   190  	return f.errorHandling
   191  }
   192  
   193  // SetOutput sets the destination for usage and error messages.
   194  // If output is nil, os.Stderr is used.
   195  func (f *FlagSet) SetOutput(output io.Writer) {
   196  	f.output = output
   197  }
   198  
   199  // VisitAll visits the flags in lexicographical order, calling fn for each.
   200  // It visits all flags, even those not set.
   201  func (f *FlagSet) VisitAll(fn func(*Flag)) {
   202  	for _, flag := range sortFlags(f.formal) {
   203  		fn(flag)
   204  	}
   205  }
   206  
   207  // VisitAll visits the command-line flags in lexicographical order, calling
   208  // fn for each. It visits all flags, even those not set.
   209  func VisitAll(fn func(*Flag)) {
   210  	CommandLine.VisitAll(fn)
   211  }
   212  
   213  // Visit visits the flags in lexicographical order, calling fn for each.
   214  // It visits only those flags that have been set.
   215  func (f *FlagSet) Visit(fn func(*Flag)) {
   216  	for _, flag := range sortFlags(f.actual) {
   217  		fn(flag)
   218  	}
   219  }
   220  
   221  // Visit visits the command-line flags in lexicographical order, calling fn
   222  // for each. It visits only those flags that have been set.
   223  func Visit(fn func(*Flag)) {
   224  	CommandLine.Visit(fn)
   225  }
   226  
   227  // Lookup returns the Flag structure of the named flag, returning nil if none exists.
   228  func (f *FlagSet) Lookup(name string) *Flag {
   229  	if flag, ok := f.formal[name]; ok {
   230  		return flag
   231  	}
   232  
   233  	// if the first rune in a string is the same length as a string in bytes,
   234  	// then we have a single rune as the string.
   235  	if r, n := utf8.DecodeRuneInString(name); n == len(name) {
   236  		return f.short[r]
   237  	}
   238  
   239  	return nil
   240  }
   241  
   242  // Lookup returns the Flag structure of the named command-line flag,
   243  // returning nil if none exists.
   244  func Lookup(name string) *Flag {
   245  	return CommandLine.Lookup(name)
   246  }
   247  
   248  // Set sets the value of the named flag.
   249  func (f *FlagSet) Set(name, value string) error {
   250  	flag, ok := f.formal[name]
   251  	if !ok {
   252  		r, n := utf8.DecodeRuneInString(name)
   253  
   254  		// if the length of a string in bytes is > the length of the first rune, then it’s multiple-runes.
   255  		if n < len(name) {
   256  			return fmt.Errorf("no such flag --%v", name)
   257  		}
   258  
   259  		flag, ok = f.short[r]
   260  		if !ok {
   261  			return fmt.Errorf("no such flag -%v", name)
   262  		}
   263  	}
   264  
   265  	if err := flag.Value.Set(value); err != nil {
   266  		return err
   267  	}
   268  
   269  	if f.actual == nil {
   270  		f.actual = make(map[string]*Flag)
   271  	}
   272  
   273  	f.actual[name] = flag
   274  	return nil
   275  }
   276  
   277  // Set sets the value of the named command-line flag.
   278  func Set(name, value string) error {
   279  	return CommandLine.Set(name, value)
   280  }
   281  
   282  // isZeroValue guesses whether the string represents the zero
   283  // value for a flag. It is not accurate but in practice works OK.
   284  func isZeroValue(flag *Flag, value string) bool {
   285  	// Build a zero value of the flag's Value type, and see if the
   286  	// result of calling its String method equals the value passed in.
   287  	// This works unless the Value type is itself an interface type.
   288  	typ := reflect.TypeOf(flag.Value)
   289  	var z reflect.Value
   290  
   291  	if typ.Kind() == reflect.Ptr {
   292  		z = reflect.New(typ.Elem())
   293  	} else {
   294  		z = reflect.Zero(typ)
   295  	}
   296  
   297  	if value == z.Interface().(Value).String() {
   298  		return true
   299  	}
   300  
   301  	switch value {
   302  	case "false", "", "0":
   303  		return true
   304  	}
   305  
   306  	return false
   307  }
   308  
   309  // UnquoteUsage extracts a back-quoted name from the usage
   310  // string for a flag and returns it and the un-quoted usage.
   311  // Given "a `name` to show" it returns ("name", "a name to show").
   312  // If there are no back quotes, the name is an educated guess of the
   313  // type of the flag's value, or the empty string if the flag is boolean.
   314  func UnquoteUsage(flag *Flag) (name string, usage string) {
   315  	type valueTyper interface {
   316  		ValueType() string
   317  	}
   318  
   319  	// Look for a back-quoted name, but avoid the strings package.
   320  	usage = flag.Usage
   321  	for i, r := range usage {
   322  		if r == '`' || r == '·' {
   323  			l := 1
   324  			if r == '·' {
   325  				l = 2
   326  			}
   327  
   328  			for j, r2 := range usage[i+l:] {
   329  				if r2 == r {
   330  					j += i + l
   331  					name = usage[i+l : j]
   332  					usage = usage[:i] + name + usage[j+l:]
   333  					return name, usage
   334  				}
   335  			}
   336  			break // Only one backquote or middot; use type name.
   337  		}
   338  	}
   339  
   340  	// No explicit name, so use type if we can find one.
   341  	name = "value"
   342  	switch f := flag.Value.(type) {
   343  	case boolFlag:
   344  		name = ""
   345  	case valueTyper:
   346  		name = f.ValueType()
   347  	case *durationValue:
   348  		name = "duration"
   349  	case *float64Value:
   350  		name = "float"
   351  	case *intValue, *int64Value:
   352  		name = "int"
   353  	case *stringValue:
   354  		name = "string"
   355  	case *uintValue, *uint64Value:
   356  		name = "uint"
   357  	}
   358  
   359  	return
   360  }
   361  
   362  // PrintDefaults prints, to standard error unless configured otherwise, the
   363  // default values of all defined command-line flags in the set. See the
   364  // documentation for the global function PrintDefaults for more information.
   365  func (f *FlagSet) PrintDefaults() {
   366  	f.VisitAll(func(flag *Flag) {
   367  		// This function is rarely called, as such, we can afford to
   368  		// just += a string, and keep things simple.
   369  		var s string
   370  
   371  		_, n := utf8.DecodeRuneInString(flag.Name)
   372  
   373  		switch {
   374  		// special case: flag.Name is one rune long, so it is only short
   375  		case n == len(flag.Name):
   376  			s = " -" + flag.Name
   377  
   378  		default:
   379  			s = " --" + flag.Name
   380  
   381  			if flag.Short != 0 {
   382  				s += " | -" + string(flag.Short)
   383  			}
   384  		}
   385  
   386  		name, usage := UnquoteUsage(flag)
   387  		if len(name) > 0 {
   388  			s += " <" + name + ">"
   389  		}
   390  
   391  		// If the flag signature is longer than a tab, put its usage on the next line
   392  		// BUG: we want to use the display width, not the rune-length (there are zero-width runes)
   393  		if utf8.RuneCountInString(s) > 7 {
   394  			// Four spaces before the tab triggers good alignment
   395  			// for both 4- and 8-space tab stops.
   396  			s += "\n    "
   397  		}
   398  
   399  		s += "\t" + strings.Replace(usage, "\n", "\n    \t", -1)
   400  
   401  		// TODO: we should be checking here to make sure the funcValue.value is non zero
   402  		if f, isFunc := flag.Value.(*funcValue); isFunc {
   403  			if f.value != "" {
   404  				// put quotes on the value
   405  				s += fmt.Sprintf(" (default %q)", f.value)
   406  			}
   407  
   408  		} else if !isZeroValue(flag, flag.DefValue) {
   409  			if _, ok := flag.Value.(*stringValue); ok {
   410  				// put quotes on the value
   411  				s += fmt.Sprintf(" (default %q)", flag.DefValue)
   412  			} else {
   413  				s += fmt.Sprintf(" (default %v)", flag.DefValue)
   414  			}
   415  		}
   416  		fmt.Fprint(f.Output(), s, "\n")
   417  	})
   418  }
   419  
   420  // PrintDefaults prints, to standard error unless configured otherwise,
   421  // a usage message showing the default settings of all defined
   422  // command-line flags.
   423  // For an integer-valued flag named "flag" with short-name "f", the default output has the form:
   424  //
   425  //	--flag | -f <int>
   426  //		usage-message-for-flag (default 42)
   427  //
   428  // For an integer-valued flag named "f" (automatically short) the default output has the form:
   429  //
   430  //	-f <int>
   431  //		usage-message-for-f (default 42)
   432  //
   433  // The usage message will appear on a separate line for anything but
   434  // a bool flag with a one-byte name. For bool flags, the type is
   435  // omitted and if the flag name is one byte the usage message appears
   436  // on the same line. The parenthetical default is omitted if the
   437  // default is the zero value for the type. The listed type, here int,
   438  // can be changed by placing a back-quoted name in the flag's usage
   439  // string; the first such item in the message is taken to be a parameter
   440  // name to show in the message and the back quotes are stripped from
   441  // the message when displayed. For instance, given
   442  //
   443  //	flag.String("I", "", "search `directory` for include files")
   444  //
   445  // the output will be
   446  //
   447  //	-I <directory>
   448  //		search directory for include files.
   449  func PrintDefaults() {
   450  	CommandLine.PrintDefaults()
   451  }
   452  
   453  // defaultUsage is the default function to print a usage message.
   454  func (f *FlagSet) defaultUsage() {
   455  	if f.name == "" {
   456  		fmt.Fprintf(f.Output(), "Usage:\n")
   457  	} else {
   458  		fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name)
   459  	}
   460  	f.PrintDefaults()
   461  }
   462  
   463  // NOTE: Usage is not just defaultUsage(CommandLine)
   464  // because it serves (via godoc flag Usage) as the example
   465  // for how to write your own usage function.
   466  
   467  // Usage prints a usage message documenting all defined command-line flags
   468  // to CommandLine's output, which by default is os.Stderr.
   469  // It is called when an error occurs while parsing flags.
   470  // The function is a variable that may be changed to point to a custom function.
   471  // By default it prints a simple header and calls PrintDefaults; for details about the
   472  // format of the output and how to control it, see the documentation for PrintDefaults.
   473  // Custom usage functions may choose to exit the program; by default exiting
   474  // happens anyway as the command line's error handling strategy is set to
   475  // ExitOnError.
   476  var Usage = func() {
   477  	fmt.Fprintf(CommandLine.Output(), "Usage of %s:\n", os.Args[0])
   478  	PrintDefaults()
   479  }
   480  
   481  // NFlag returns the number of flags that have been set.
   482  func (f *FlagSet) NFlag() int { return len(f.actual) }
   483  
   484  // NFlag returns the number of command-line flags that have been set.
   485  func NFlag() int { return len(CommandLine.actual) }
   486  
   487  // Arg returns the i'th argument. Arg(0) is the first remaining argument
   488  // after flags have been processed. Arg returns an empty string if the
   489  // requested element does not exist.
   490  func (f *FlagSet) Arg(i int) string {
   491  	if i < 0 || i >= len(f.args) {
   492  		return ""
   493  	}
   494  	return f.args[i]
   495  }
   496  
   497  // Arg returns the i'th command-line argument. Arg(0) is the first remaining argument
   498  // after flags have been processed. Arg returns an empty string if the
   499  // requested element does not exist.
   500  func Arg(i int) string {
   501  	return CommandLine.Arg(i)
   502  }
   503  
   504  // NArg is the number of arguments remaining after flags have been processed.
   505  func (f *FlagSet) NArg() int { return len(f.args) }
   506  
   507  // NArg is the number of arguments remaining after flags have been processed.
   508  func NArg() int { return len(CommandLine.args) }
   509  
   510  // Args returns the non-flag arguments.
   511  func (f *FlagSet) Args() []string { return f.args }
   512  
   513  // Args returns the non-flag command-line arguments.
   514  func Args() []string { return CommandLine.args }
   515  
   516  func (f *FlagSet) set(flag *Flag, name string) {
   517  	if len(name) < 1 {
   518  		return
   519  	}
   520  
   521  	if f.formal == nil {
   522  		f.formal = make(map[string]*Flag)
   523  	}
   524  
   525  	_, alreadythere := f.formal[name]
   526  	if alreadythere {
   527  		var msg string
   528  
   529  		if f.name != "" {
   530  			msg = f.name + " "
   531  		}
   532  
   533  		msg += fmt.Sprintf("longflag redefined: %q", name)
   534  
   535  		fmt.Fprintln(f.Output(), msg)
   536  		panic(msg) // Happens only if flags are declared with identical names
   537  	}
   538  
   539  	f.formal[name] = flag
   540  }
   541  
   542  func (f *FlagSet) setShort(flag *Flag, name rune) {
   543  	if name < 1 {
   544  		return
   545  	}
   546  
   547  	if f.short == nil {
   548  		f.short = make(map[rune]*Flag)
   549  	}
   550  
   551  	_, alreadythere := f.short[name]
   552  	if alreadythere {
   553  		var msg string
   554  
   555  		if f.name != "" {
   556  			msg = f.name + " "
   557  		}
   558  
   559  		msg += fmt.Sprintf("shortflag redefined: %q", string(name))
   560  
   561  		fmt.Fprintln(f.Output(), msg)
   562  		panic(msg) // Happens only if flags are declared with identical names
   563  	}
   564  
   565  	f.short[name] = flag
   566  }
   567  
   568  // Copy copies an existing flag into this FlagSet.
   569  // This uses the already given name, short, usage, and default.
   570  // It will panic if you attempt to copy a Flag into a FlagSet where the name or short name already exist.
   571  //
   572  //	fs := flag.NewFlagSet("example", flag.ExitOnError)
   573  //	fs.Copy(flag.Lookup("output"))
   574  func (f *FlagSet) Copy(flag *Flag) {
   575  	f.set(flag, flag.Name)
   576  	f.setShort(flag, flag.Short)
   577  }
   578  
   579  // CopyFrom does a lookup of the flagname on the given FlagSet, and the Copies that flag into this Flagset.
   580  // It will panic if you attempt to copy a Flag into a FlagSet where the name or short name already exist.
   581  //
   582  //	fs := flag.NewFlagSet("example", flag.ExitOnError)
   583  //	fs.CopyFrom(flag.CommandLine, "output")
   584  func (f *FlagSet) CopyFrom(from *FlagSet, name string) {
   585  	f.Copy(from.Lookup(name))
   586  }
   587  
   588  // Var defines a flag with the specified name and usage string. The type and
   589  // value of the flag are represented by the first argument, of type Value, which
   590  // typically holds a user-defined implementation of Value. For instance, the
   591  // caller could create a flag that turns a comma-separated string into a slice
   592  // of strings by giving the slice the methods of Value; in particular, Set would
   593  // decompose the comma-separated string into the slice.
   594  func (f *FlagSet) Var(value Value, name string, usage string, options ...Option) error {
   595  	// Remember the default value is a string; it won't change.
   596  	// Well, unless a WithDefault Option is passed…
   597  	flag := &Flag{
   598  		Name:     name,
   599  		Usage:    usage,
   600  		Value:    value,
   601  		DefValue: value.String(),
   602  	}
   603  
   604  	// if name is only one rune long, then alias it as a short-flag name.
   605  	if r, n := utf8.DecodeRuneInString(name); n == len(name) {
   606  		flag.Short = r
   607  	}
   608  
   609  	for _, opt := range options {
   610  		// during initialization we discard all reversing functionality
   611  		_, err := opt(flag)
   612  		if err != nil {
   613  			return err
   614  		}
   615  	}
   616  
   617  	f.set(flag, name)
   618  	f.setShort(flag, flag.Short)
   619  	return nil
   620  }
   621  
   622  // Var defines a flag with the specified name and usage string. The type and
   623  // value of the flag are represented by the first argument, of type Value, which
   624  // typically holds a user-defined implementation of Value. For instance, the
   625  // caller could create a flag that turns a comma-separated string into a slice
   626  // of strings by giving the slice the methods of Value; in particular, Set would
   627  // decompose the comma-separated string into the slice.
   628  func Var(value Value, name string, usage string, options ...Option) error {
   629  	return CommandLine.Var(value, name, usage, options...)
   630  }
   631  
   632  // failf prints to standard error a formatted error and usage message and
   633  // returns the error.
   634  func (f *FlagSet) failf(format string, a ...interface{}) error {
   635  	err := fmt.Errorf(format, a...)
   636  	fmt.Fprintln(f.Output(), err)
   637  	f.usage()
   638  	return err
   639  }
   640  
   641  // usage calls the Usage method for the flag set if one is specified,
   642  // or the appropriate default usage function otherwise.
   643  func (f *FlagSet) usage() {
   644  	if f.Usage == nil {
   645  		f.defaultUsage()
   646  	} else {
   647  		f.Usage()
   648  	}
   649  }
   650  
   651  func (f *FlagSet) undefinedShortFlag(name rune) (bool, error) {
   652  	if name == '?' {
   653  		// special case for nice help message.
   654  		f.usage()
   655  		return false, ErrHelp
   656  	}
   657  
   658  	return false, f.failf("flag provided but not defined: -%c", name)
   659  }
   660  
   661  func (f *FlagSet) undefinedFlag(name string) (bool, error) {
   662  	if name == "help" || name == "?" {
   663  		// special case for nice help message.
   664  		f.usage()
   665  		return false, ErrHelp
   666  	}
   667  
   668  	return false, f.failf("flag provided but not defined: --%s", name)
   669  }
   670  
   671  // parseOne parses one flag. It reports whether a flag was seen.
   672  func (f *FlagSet) parseOne() (bool, error) {
   673  	if len(f.args) < 1 {
   674  		return false, nil
   675  	}
   676  
   677  	// we’re accepting em-dash and en-dash as aliases for "--", so
   678  	// we need to convert things into runes to deal with things properly.
   679  	r := []rune(f.args[0])
   680  
   681  	// if the argument is only one character long, it cannot be
   682  	// any form of flag whatsoever, so we stop parsing.
   683  	if len(r) < 2 {
   684  		return false, nil
   685  	}
   686  
   687  	var long bool
   688  
   689  	switch r[0] {
   690  	case '–', '—':
   691  		long = true
   692  	case '-':
   693  		// for now, assume short form flag
   694  	default:
   695  		return false, nil
   696  	}
   697  
   698  	numMinuses := 1
   699  
   700  	// this allows [em-dash, en-dash], hyphen, but… eh, whatever
   701  	if r[1] == '-' { // oh, it is a long form flag after all
   702  		long = true
   703  		numMinuses++
   704  	}
   705  
   706  	// if we're all minuses, terminate flag parsing, and pass over this terminator
   707  	if len(r) <= numMinuses {
   708  		f.args = f.args[1:]
   709  		return false, nil
   710  	}
   711  
   712  	switch r[numMinuses] {
   713  	// we’re not supposed to be having any dashes at this point.
   714  	case '-', '–', '—':
   715  		return false, f.failf("bad flag syntax: %s", string(r))
   716  	// likewise, no '='.
   717  	case '=':
   718  		return false, f.failf("no flag name given: %s", string(r))
   719  	}
   720  
   721  	// ok, _now_ we have the name we’re going to use.
   722  	name := string(r[numMinuses:])
   723  
   724  	// ok, it’s a flag, so shift the arguments
   725  	f.args = f.args[1:]
   726  
   727  	var hasValue bool
   728  	var value string
   729  
   730  	// now, let’s check to see if we have an argument
   731  	if i := strings.IndexByte(name, '='); i > 0 {
   732  		value = name[i+1:]
   733  		hasValue = true
   734  		name = name[0:i]
   735  	}
   736  
   737  	if long {
   738  		flag, ok := f.formal[name] // BUG: [explanation needed]
   739  		if !ok {
   740  			return f.undefinedFlag(name)
   741  		}
   742  
   743  		return f.doFlag(flag, name, value, hasValue)
   744  	}
   745  
   746  	return f.parseShort(name, value, hasValue)
   747  }
   748  
   749  func (f *FlagSet) parseShort(name, value string, hasValue bool) (bool, error) {
   750  	// we need to not only range over the runes of name, but we
   751  	// need to be able to ensure we know we’re on the last rune
   752  	// of the series. And then, we need to potentially convert the rune
   753  	// series into a value for a flag. (à la -m"git message here")
   754  	r := []rune(name)
   755  	last := len(r) - 1
   756  
   757  	for i, n := range r {
   758  		flag, ok := f.short[n] // BUG: [explanation needed]
   759  		if !ok {
   760  			return f.undefinedShortFlag(n)
   761  		}
   762  
   763  		// easy, -…n[=value]
   764  		if i == last {
   765  			// support things like: cut -d= -f1
   766  			if hasValue && value == "" {
   767  				return f.doFlag(flag, string(n), "=", true)
   768  			}
   769  
   770  			return f.doFlag(flag, string(n), value, hasValue)
   771  		}
   772  
   773  		// allowed: -…n…[=value], if flag.IsBoolFlag() == true
   774  		if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() {
   775  			// hasValue == true to be extra sure about preventing
   776  			//  accidentally pulling the next argument in as the value.
   777  			if _, err := f.doFlag(flag, string(n), "true", true); err != nil {
   778  				return false, err
   779  			}
   780  			continue
   781  		}
   782  
   783  		// not allowed: -…n…=value, if flag requires a value
   784  		if hasValue {
   785  			return false, f.failf("bad flag format -%c requires an argument, but does not appear at the end: -%s=%s", n, name, value)
   786  		}
   787  
   788  		// allowed: -…n"value here, like -m flag in git"
   789  		return f.doFlag(flag, string(n), string(r[i+1:]), true)
   790  	}
   791  
   792  	return true, nil
   793  }
   794  
   795  func (f *FlagSet) doFlag(flag *Flag, name string, value string, hasValue bool) (bool, error) {
   796  	if f.actual == nil {
   797  		f.actual = make(map[string]*Flag)
   798  	}
   799  	f.actual[name] = flag
   800  
   801  	var prefix = "--"
   802  	// if the first rune is the length of the whole string, then RuneCount == 1
   803  	if _, n := utf8.DecodeRuneInString(name); n == len(name) {
   804  		prefix = "-"
   805  	}
   806  
   807  	if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() {
   808  		// special case: doesn't need an arg
   809  		if !hasValue {
   810  			value = "true"
   811  		}
   812  
   813  		if err := fv.Set(value); err != nil {
   814  			return false, f.failf("invalid boolean value %q for %s%s: %v", value, prefix, name, err)
   815  		}
   816  
   817  		return true, nil
   818  	}
   819  
   820  	// It must have a value, which might be the next argument.
   821  	if !hasValue {
   822  		if len(f.args) < 1 {
   823  			return false, f.failf("flag needs an argument: %s%s", prefix, name)
   824  		}
   825  
   826  		// value is the next arg
   827  		value, f.args = f.args[0], f.args[1:]
   828  	}
   829  
   830  	if err := flag.Value.Set(value); err != nil {
   831  		return false, f.failf("invalid value %q for flag %s%s: %v", value, prefix, name, err)
   832  	}
   833  
   834  	return true, nil
   835  }
   836  
   837  // Parse parses flag definitions from the argument list, which should not
   838  // include the command name. Must be called after all flags in the FlagSet
   839  // are defined and before flags are accessed by the program.
   840  // The return value will be ErrHelp if --help or -? were set but not defined.
   841  func (f *FlagSet) Parse(arguments []string) error {
   842  	f.parsed = true
   843  	f.args = arguments
   844  
   845  	if len(f.args) < 1 {
   846  		return nil
   847  	}
   848  
   849  	for {
   850  		seen, err := f.parseOne()
   851  		if seen {
   852  			continue
   853  		}
   854  		if err == nil {
   855  			break
   856  		}
   857  
   858  		switch f.errorHandling {
   859  		case ContinueOnError:
   860  			return err
   861  		case ExitOnError:
   862  			os.Exit(2)
   863  		case PanicOnError:
   864  			panic(err)
   865  		}
   866  	}
   867  
   868  	return nil
   869  }
   870  
   871  // Parsed reports whether f.Parse has been called.
   872  func (f *FlagSet) Parsed() bool {
   873  	return f.parsed
   874  }
   875  
   876  // Parse parses the command-line flags from os.Args[1:]. Must be called
   877  // after all flags are defined and before flags are accessed by the program.
   878  func Parse() {
   879  	// Ignore errors; CommandLine is set for ExitOnError.
   880  	CommandLine.Parse(os.Args[1:])
   881  }
   882  
   883  // Parsed reports whether the command-line flags have been parsed.
   884  func Parsed() bool {
   885  	return CommandLine.Parsed()
   886  }
   887  
   888  // CommandLine is the default set of command-line flags, parsed from os.Args.
   889  // The top-level functions such as BoolVar, Arg, and so on are wrappers for the
   890  // methods of CommandLine.
   891  var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
   892  
   893  func init() {
   894  	// Override generic FlagSet default Usage with call to global Usage.
   895  	// Note: This is not CommandLine.Usage = Usage,
   896  	// because we want any eventual call to use any updated value of Usage,
   897  	// not the value it has when this line is run.
   898  	CommandLine.Usage = func() {
   899  		Usage()
   900  	}
   901  }
   902  
   903  // NewFlagSet returns a new, empty flag set with the specified name and
   904  // error handling property.
   905  func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
   906  	f := &FlagSet{
   907  		name:          name,
   908  		errorHandling: errorHandling,
   909  	}
   910  	f.Usage = f.defaultUsage
   911  	return f
   912  }
   913  
   914  // Init sets the name and error handling property for a flag set.
   915  // By default, the zero FlagSet uses an empty name and the
   916  // ContinueOnError error handling policy.
   917  func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
   918  	f.name = name
   919  	f.errorHandling = errorHandling
   920  }