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 }