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