github.com/pmorton/docker@v1.5.0/pkg/mflag/flag.go (about) 1 // Copyright 2014-2015 The Docker & 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, -f or --flagname, stored in the pointer ip, with type *int. 13 import "flag /github.com/docker/docker/pkg/mflag" 14 var ip = flag.Int([]string{"f", "-flagname"}, 1234, "help message for flagname") 15 If you like, you can bind the flag to a variable using the Var() functions. 16 var flagvar int 17 func init() { 18 // -flaghidden will work, but will be hidden from the usage 19 flag.IntVar(&flagvar, []string{"f", "#flaghidden", "-flagname"}, 1234, "help message for flagname") 20 } 21 Or you can create custom flags that satisfy the Value interface (with 22 pointer receivers) and couple them to flag parsing by 23 flag.Var(&flagVal, []string{"name"}, "help message for flagname") 24 For such flags, the default value is just the initial value of the variable. 25 26 You can also add "deprecated" flags, they are still usable, but are not shown 27 in the usage and will display a warning when you try to use them. `#` before 28 an option means this option is deprecated, if there is an following option 29 without `#` ahead, then that's the replacement, if not, it will just be removed: 30 var ip = flag.Int([]string{"#f", "#flagname", "-flagname"}, 1234, "help message for flagname") 31 this will display: `Warning: '-f' is deprecated, it will be replaced by '--flagname' soon. See usage.` or 32 this will display: `Warning: '-flagname' is deprecated, it will be replaced by '--flagname' soon. See usage.` 33 var ip = flag.Int([]string{"f", "#flagname"}, 1234, "help message for flagname") 34 will display: `Warning: '-flagname' is deprecated, it will be removed soon. See usage.` 35 so you can only use `-f`. 36 37 You can also group one letter flags, bif you declare 38 var v = flag.Bool([]string{"v", "-verbose"}, false, "help message for verbose") 39 var s = flag.Bool([]string{"s", "-slow"}, false, "help message for slow") 40 you will be able to use the -vs or -sv 41 42 After all flags are defined, call 43 flag.Parse() 44 to parse the command line into the defined flags. 45 46 Flags may then be used directly. If you're using the flags themselves, 47 they are all pointers; if you bind to variables, they're values. 48 fmt.Println("ip has value ", *ip) 49 fmt.Println("flagvar has value ", flagvar) 50 51 After parsing, the arguments after the flag are available as the 52 slice flag.Args() or individually as flag.Arg(i). 53 The arguments are indexed from 0 through flag.NArg()-1. 54 55 Command line flag syntax: 56 -flag 57 -flag=x 58 -flag="x" 59 -flag='x' 60 -flag x // non-boolean flags only 61 One or two minus signs may be used; they are equivalent. 62 The last form is not permitted for boolean flags because the 63 meaning of the command 64 cmd -x * 65 will change if there is a file called 0, false, etc. You must 66 use the -flag=false form to turn off a boolean flag. 67 68 Flag parsing stops just before the first non-flag argument 69 ("-" is a non-flag argument) or after the terminator "--". 70 71 Integer flags accept 1234, 0664, 0x1234 and may be negative. 72 Boolean flags may be 1, 0, t, f, true, false, TRUE, FALSE, True, False. 73 Duration flags accept any input valid for time.ParseDuration. 74 75 The default set of command-line flags is controlled by 76 top-level functions. The FlagSet type allows one to define 77 independent sets of flags, such as to implement subcommands 78 in a command-line interface. The methods of FlagSet are 79 analogous to the top-level functions for the command-line 80 flag set. 81 */ 82 package mflag 83 84 import ( 85 "errors" 86 "fmt" 87 "io" 88 "os" 89 "sort" 90 "strconv" 91 "strings" 92 "text/tabwriter" 93 "time" 94 ) 95 96 // ErrHelp is the error returned if the flag -help is invoked but no such flag is defined. 97 var ErrHelp = errors.New("flag: help requested") 98 99 // ErrRetry is the error returned if you need to try letter by letter 100 var ErrRetry = errors.New("flag: retry") 101 102 // -- bool Value 103 type boolValue bool 104 105 func newBoolValue(val bool, p *bool) *boolValue { 106 *p = val 107 return (*boolValue)(p) 108 } 109 110 func (b *boolValue) Set(s string) error { 111 v, err := strconv.ParseBool(s) 112 *b = boolValue(v) 113 return err 114 } 115 116 func (b *boolValue) Get() interface{} { return bool(*b) } 117 118 func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) } 119 120 func (b *boolValue) IsBoolFlag() bool { return true } 121 122 // optional interface to indicate boolean flags that can be 123 // supplied without "=value" text 124 type boolFlag interface { 125 Value 126 IsBoolFlag() bool 127 } 128 129 // -- int Value 130 type intValue int 131 132 func newIntValue(val int, p *int) *intValue { 133 *p = val 134 return (*intValue)(p) 135 } 136 137 func (i *intValue) Set(s string) error { 138 v, err := strconv.ParseInt(s, 0, 64) 139 *i = intValue(v) 140 return err 141 } 142 143 func (i *intValue) Get() interface{} { return int(*i) } 144 145 func (i *intValue) String() string { return fmt.Sprintf("%v", *i) } 146 147 // -- int64 Value 148 type int64Value int64 149 150 func newInt64Value(val int64, p *int64) *int64Value { 151 *p = val 152 return (*int64Value)(p) 153 } 154 155 func (i *int64Value) Set(s string) error { 156 v, err := strconv.ParseInt(s, 0, 64) 157 *i = int64Value(v) 158 return err 159 } 160 161 func (i *int64Value) Get() interface{} { return int64(*i) } 162 163 func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) } 164 165 // -- uint Value 166 type uintValue uint 167 168 func newUintValue(val uint, p *uint) *uintValue { 169 *p = val 170 return (*uintValue)(p) 171 } 172 173 func (i *uintValue) Set(s string) error { 174 v, err := strconv.ParseUint(s, 0, 64) 175 *i = uintValue(v) 176 return err 177 } 178 179 func (i *uintValue) Get() interface{} { return uint(*i) } 180 181 func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) } 182 183 // -- uint64 Value 184 type uint64Value uint64 185 186 func newUint64Value(val uint64, p *uint64) *uint64Value { 187 *p = val 188 return (*uint64Value)(p) 189 } 190 191 func (i *uint64Value) Set(s string) error { 192 v, err := strconv.ParseUint(s, 0, 64) 193 *i = uint64Value(v) 194 return err 195 } 196 197 func (i *uint64Value) Get() interface{} { return uint64(*i) } 198 199 func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) } 200 201 // -- string Value 202 type stringValue string 203 204 func newStringValue(val string, p *string) *stringValue { 205 *p = val 206 return (*stringValue)(p) 207 } 208 209 func (s *stringValue) Set(val string) error { 210 *s = stringValue(val) 211 return nil 212 } 213 214 func (s *stringValue) Get() interface{} { return string(*s) } 215 216 func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) } 217 218 // -- float64 Value 219 type float64Value float64 220 221 func newFloat64Value(val float64, p *float64) *float64Value { 222 *p = val 223 return (*float64Value)(p) 224 } 225 226 func (f *float64Value) Set(s string) error { 227 v, err := strconv.ParseFloat(s, 64) 228 *f = float64Value(v) 229 return err 230 } 231 232 func (f *float64Value) Get() interface{} { return float64(*f) } 233 234 func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) } 235 236 // -- time.Duration Value 237 type durationValue time.Duration 238 239 func newDurationValue(val time.Duration, p *time.Duration) *durationValue { 240 *p = val 241 return (*durationValue)(p) 242 } 243 244 func (d *durationValue) Set(s string) error { 245 v, err := time.ParseDuration(s) 246 *d = durationValue(v) 247 return err 248 } 249 250 func (d *durationValue) Get() interface{} { return time.Duration(*d) } 251 252 func (d *durationValue) String() string { return (*time.Duration)(d).String() } 253 254 // Value is the interface to the dynamic value stored in a flag. 255 // (The default value is represented as a string.) 256 // 257 // If a Value has an IsBoolFlag() bool method returning true, 258 // the command-line parser makes -name equivalent to -name=true 259 // rather than using the next command-line argument. 260 type Value interface { 261 String() string 262 Set(string) error 263 } 264 265 // Getter is an interface that allows the contents of a Value to be retrieved. 266 // It wraps the Value interface, rather than being part of it, because it 267 // appeared after Go 1 and its compatibility rules. All Value types provided 268 // by this package satisfy the Getter interface. 269 type Getter interface { 270 Value 271 Get() interface{} 272 } 273 274 // ErrorHandling defines how to handle flag parsing errors. 275 type ErrorHandling int 276 277 const ( 278 ContinueOnError ErrorHandling = iota 279 ExitOnError 280 PanicOnError 281 ) 282 283 // A FlagSet represents a set of defined flags. The zero value of a FlagSet 284 // has no name and has ContinueOnError error handling. 285 type FlagSet struct { 286 // Usage is the function called when an error occurs while parsing flags. 287 // The field is a function (not a method) that may be changed to point to 288 // a custom error handler. 289 Usage func() 290 291 name string 292 parsed bool 293 actual map[string]*Flag 294 formal map[string]*Flag 295 args []string // arguments after flags 296 errorHandling ErrorHandling 297 output io.Writer // nil means stderr; use Out() accessor 298 nArgRequirements []nArgRequirement 299 } 300 301 // A Flag represents the state of a flag. 302 type Flag struct { 303 Names []string // name as it appears on command line 304 Usage string // help message 305 Value Value // value as set 306 DefValue string // default value (as text); for usage message 307 } 308 309 type flagSlice []string 310 311 func (p flagSlice) Len() int { return len(p) } 312 func (p flagSlice) Less(i, j int) bool { 313 pi, pj := strings.TrimPrefix(p[i], "-"), strings.TrimPrefix(p[j], "-") 314 lpi, lpj := strings.ToLower(pi), strings.ToLower(pj) 315 if lpi != lpj { 316 return lpi < lpj 317 } 318 return pi < pj 319 } 320 func (p flagSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } 321 322 // sortFlags returns the flags as a slice in lexicographical sorted order. 323 func sortFlags(flags map[string]*Flag) []*Flag { 324 var list flagSlice 325 326 // The sorted list is based on the first name, when flag map might use the other names. 327 nameMap := make(map[string]string) 328 329 for n, f := range flags { 330 fName := strings.TrimPrefix(f.Names[0], "#") 331 nameMap[fName] = n 332 if len(f.Names) == 1 { 333 list = append(list, fName) 334 continue 335 } 336 337 found := false 338 for _, name := range list { 339 if name == fName { 340 found = true 341 break 342 } 343 } 344 if !found { 345 list = append(list, fName) 346 } 347 } 348 sort.Sort(list) 349 result := make([]*Flag, len(list)) 350 for i, name := range list { 351 result[i] = flags[nameMap[name]] 352 } 353 return result 354 } 355 356 // Name returns the name of the FlagSet. 357 func (f *FlagSet) Name() string { 358 return f.name 359 } 360 361 // Out returns the destination for usage and error messages. 362 func (f *FlagSet) Out() io.Writer { 363 if f.output == nil { 364 return os.Stderr 365 } 366 return f.output 367 } 368 369 // SetOutput sets the destination for usage and error messages. 370 // If output is nil, os.Stderr is used. 371 func (f *FlagSet) SetOutput(output io.Writer) { 372 f.output = output 373 } 374 375 // VisitAll visits the flags in lexicographical order, calling fn for each. 376 // It visits all flags, even those not set. 377 func (f *FlagSet) VisitAll(fn func(*Flag)) { 378 for _, flag := range sortFlags(f.formal) { 379 fn(flag) 380 } 381 } 382 383 // VisitAll visits the command-line flags in lexicographical order, calling 384 // fn for each. It visits all flags, even those not set. 385 func VisitAll(fn func(*Flag)) { 386 CommandLine.VisitAll(fn) 387 } 388 389 // Visit visits the flags in lexicographical order, calling fn for each. 390 // It visits only those flags that have been set. 391 func (f *FlagSet) Visit(fn func(*Flag)) { 392 for _, flag := range sortFlags(f.actual) { 393 fn(flag) 394 } 395 } 396 397 // Visit visits the command-line flags in lexicographical order, calling fn 398 // for each. It visits only those flags that have been set. 399 func Visit(fn func(*Flag)) { 400 CommandLine.Visit(fn) 401 } 402 403 // Lookup returns the Flag structure of the named flag, returning nil if none exists. 404 func (f *FlagSet) Lookup(name string) *Flag { 405 return f.formal[name] 406 } 407 408 // Indicates whether the specified flag was specified at all on the cmd line 409 func (f *FlagSet) IsSet(name string) bool { 410 return f.actual[name] != nil 411 } 412 413 // Lookup returns the Flag structure of the named command-line flag, 414 // returning nil if none exists. 415 func Lookup(name string) *Flag { 416 return CommandLine.formal[name] 417 } 418 419 // Indicates whether the specified flag was specified at all on the cmd line 420 func IsSet(name string) bool { 421 return CommandLine.IsSet(name) 422 } 423 424 type nArgRequirementType int 425 426 // Indicator used to pass to BadArgs function 427 const ( 428 Exact nArgRequirementType = iota 429 Max 430 Min 431 ) 432 433 type nArgRequirement struct { 434 Type nArgRequirementType 435 N int 436 } 437 438 // Require adds a requirement about the number of arguments for the FlagSet. 439 // The first parameter can be Exact, Max, or Min to respectively specify the exact, 440 // the maximum, or the minimal number of arguments required. 441 // The actual check is done in FlagSet.CheckArgs(). 442 func (f *FlagSet) Require(nArgRequirementType nArgRequirementType, nArg int) { 443 f.nArgRequirements = append(f.nArgRequirements, nArgRequirement{nArgRequirementType, nArg}) 444 } 445 446 // CheckArgs uses the requirements set by FlagSet.Require() to validate 447 // the number of arguments. If the requirements are not met, 448 // an error message string is returned. 449 func (f *FlagSet) CheckArgs() (message string) { 450 for _, req := range f.nArgRequirements { 451 var arguments string 452 if req.N == 1 { 453 arguments = "1 argument" 454 } else { 455 arguments = fmt.Sprintf("%d arguments", req.N) 456 } 457 458 str := func(kind string) string { 459 return fmt.Sprintf("%q requires %s%s", f.name, kind, arguments) 460 } 461 462 switch req.Type { 463 case Exact: 464 if f.NArg() != req.N { 465 return str("") 466 } 467 case Max: 468 if f.NArg() > req.N { 469 return str("a maximum of ") 470 } 471 case Min: 472 if f.NArg() < req.N { 473 return str("a minimum of ") 474 } 475 } 476 } 477 return "" 478 } 479 480 // Set sets the value of the named flag. 481 func (f *FlagSet) Set(name, value string) error { 482 flag, ok := f.formal[name] 483 if !ok { 484 return fmt.Errorf("no such flag -%v", name) 485 } 486 err := flag.Value.Set(value) 487 if err != nil { 488 return err 489 } 490 if f.actual == nil { 491 f.actual = make(map[string]*Flag) 492 } 493 f.actual[name] = flag 494 return nil 495 } 496 497 // Set sets the value of the named command-line flag. 498 func Set(name, value string) error { 499 return CommandLine.Set(name, value) 500 } 501 502 // PrintDefaults prints, to standard error unless configured 503 // otherwise, the default values of all defined flags in the set. 504 func (f *FlagSet) PrintDefaults() { 505 writer := tabwriter.NewWriter(f.Out(), 20, 1, 3, ' ', 0) 506 f.VisitAll(func(flag *Flag) { 507 format := " -%s=%s" 508 if _, ok := flag.Value.(*stringValue); ok { 509 // put quotes on the value 510 format = " -%s=%q" 511 } 512 names := []string{} 513 for _, name := range flag.Names { 514 if name[0] != '#' { 515 names = append(names, name) 516 } 517 } 518 if len(names) > 0 { 519 fmt.Fprintf(writer, format, strings.Join(names, ", -"), flag.DefValue) 520 for i, line := range strings.Split(flag.Usage, "\n") { 521 if i != 0 { 522 line = " " + line 523 } 524 fmt.Fprintln(writer, "\t", line) 525 } 526 } 527 }) 528 writer.Flush() 529 } 530 531 // PrintDefaults prints to standard error the default values of all defined command-line flags. 532 func PrintDefaults() { 533 CommandLine.PrintDefaults() 534 } 535 536 // defaultUsage is the default function to print a usage message. 537 func defaultUsage(f *FlagSet) { 538 if f.name == "" { 539 fmt.Fprintf(f.Out(), "Usage:\n") 540 } else { 541 fmt.Fprintf(f.Out(), "Usage of %s:\n", f.name) 542 } 543 f.PrintDefaults() 544 } 545 546 // NOTE: Usage is not just defaultUsage(CommandLine) 547 // because it serves (via godoc flag Usage) as the example 548 // for how to write your own usage function. 549 550 // Usage prints to standard error a usage message documenting all defined command-line flags. 551 // The function is a variable that may be changed to point to a custom function. 552 var Usage = func() { 553 fmt.Fprintf(CommandLine.output, "Usage of %s:\n", os.Args[0]) 554 PrintDefaults() 555 } 556 557 // FlagCount returns the number of flags that have been defined. 558 func (f *FlagSet) FlagCount() int { return len(sortFlags(f.formal)) } 559 560 // FlagCountUndeprecated returns the number of undeprecated flags that have been defined. 561 func (f *FlagSet) FlagCountUndeprecated() int { 562 count := 0 563 for _, flag := range sortFlags(f.formal) { 564 for _, name := range flag.Names { 565 if name[0] != '#' { 566 count++ 567 break 568 } 569 } 570 } 571 return count 572 } 573 574 // NFlag returns the number of flags that have been set. 575 func (f *FlagSet) NFlag() int { return len(f.actual) } 576 577 // NFlag returns the number of command-line flags that have been set. 578 func NFlag() int { return len(CommandLine.actual) } 579 580 // Arg returns the i'th argument. Arg(0) is the first remaining argument 581 // after flags have been processed. 582 func (f *FlagSet) Arg(i int) string { 583 if i < 0 || i >= len(f.args) { 584 return "" 585 } 586 return f.args[i] 587 } 588 589 // Arg returns the i'th command-line argument. Arg(0) is the first remaining argument 590 // after flags have been processed. 591 func Arg(i int) string { 592 return CommandLine.Arg(i) 593 } 594 595 // NArg is the number of arguments remaining after flags have been processed. 596 func (f *FlagSet) NArg() int { return len(f.args) } 597 598 // NArg is the number of arguments remaining after flags have been processed. 599 func NArg() int { return len(CommandLine.args) } 600 601 // Args returns the non-flag arguments. 602 func (f *FlagSet) Args() []string { return f.args } 603 604 // Args returns the non-flag command-line arguments. 605 func Args() []string { return CommandLine.args } 606 607 // BoolVar defines a bool flag with specified name, default value, and usage string. 608 // The argument p points to a bool variable in which to store the value of the flag. 609 func (f *FlagSet) BoolVar(p *bool, names []string, value bool, usage string) { 610 f.Var(newBoolValue(value, p), names, usage) 611 } 612 613 // BoolVar defines a bool flag with specified name, default value, and usage string. 614 // The argument p points to a bool variable in which to store the value of the flag. 615 func BoolVar(p *bool, names []string, value bool, usage string) { 616 CommandLine.Var(newBoolValue(value, p), names, usage) 617 } 618 619 // Bool defines a bool flag with specified name, default value, and usage string. 620 // The return value is the address of a bool variable that stores the value of the flag. 621 func (f *FlagSet) Bool(names []string, value bool, usage string) *bool { 622 p := new(bool) 623 f.BoolVar(p, names, value, usage) 624 return p 625 } 626 627 // Bool defines a bool flag with specified name, default value, and usage string. 628 // The return value is the address of a bool variable that stores the value of the flag. 629 func Bool(names []string, value bool, usage string) *bool { 630 return CommandLine.Bool(names, value, usage) 631 } 632 633 // IntVar defines an int flag with specified name, default value, and usage string. 634 // The argument p points to an int variable in which to store the value of the flag. 635 func (f *FlagSet) IntVar(p *int, names []string, value int, usage string) { 636 f.Var(newIntValue(value, p), names, usage) 637 } 638 639 // IntVar defines an int flag with specified name, default value, and usage string. 640 // The argument p points to an int variable in which to store the value of the flag. 641 func IntVar(p *int, names []string, value int, usage string) { 642 CommandLine.Var(newIntValue(value, p), names, usage) 643 } 644 645 // Int defines an int flag with specified name, default value, and usage string. 646 // The return value is the address of an int variable that stores the value of the flag. 647 func (f *FlagSet) Int(names []string, value int, usage string) *int { 648 p := new(int) 649 f.IntVar(p, names, value, usage) 650 return p 651 } 652 653 // Int defines an int flag with specified name, default value, and usage string. 654 // The return value is the address of an int variable that stores the value of the flag. 655 func Int(names []string, value int, usage string) *int { 656 return CommandLine.Int(names, value, usage) 657 } 658 659 // Int64Var defines an int64 flag with specified name, default value, and usage string. 660 // The argument p points to an int64 variable in which to store the value of the flag. 661 func (f *FlagSet) Int64Var(p *int64, names []string, value int64, usage string) { 662 f.Var(newInt64Value(value, p), names, usage) 663 } 664 665 // Int64Var defines an int64 flag with specified name, default value, and usage string. 666 // The argument p points to an int64 variable in which to store the value of the flag. 667 func Int64Var(p *int64, names []string, value int64, usage string) { 668 CommandLine.Var(newInt64Value(value, p), names, usage) 669 } 670 671 // Int64 defines an int64 flag with specified name, default value, and usage string. 672 // The return value is the address of an int64 variable that stores the value of the flag. 673 func (f *FlagSet) Int64(names []string, value int64, usage string) *int64 { 674 p := new(int64) 675 f.Int64Var(p, names, value, usage) 676 return p 677 } 678 679 // Int64 defines an int64 flag with specified name, default value, and usage string. 680 // The return value is the address of an int64 variable that stores the value of the flag. 681 func Int64(names []string, value int64, usage string) *int64 { 682 return CommandLine.Int64(names, value, usage) 683 } 684 685 // UintVar defines a uint flag with specified name, default value, and usage string. 686 // The argument p points to a uint variable in which to store the value of the flag. 687 func (f *FlagSet) UintVar(p *uint, names []string, value uint, usage string) { 688 f.Var(newUintValue(value, p), names, usage) 689 } 690 691 // UintVar defines a uint flag with specified name, default value, and usage string. 692 // The argument p points to a uint variable in which to store the value of the flag. 693 func UintVar(p *uint, names []string, value uint, usage string) { 694 CommandLine.Var(newUintValue(value, p), names, usage) 695 } 696 697 // Uint defines a uint flag with specified name, default value, and usage string. 698 // The return value is the address of a uint variable that stores the value of the flag. 699 func (f *FlagSet) Uint(names []string, value uint, usage string) *uint { 700 p := new(uint) 701 f.UintVar(p, names, value, usage) 702 return p 703 } 704 705 // Uint defines a uint flag with specified name, default value, and usage string. 706 // The return value is the address of a uint variable that stores the value of the flag. 707 func Uint(names []string, value uint, usage string) *uint { 708 return CommandLine.Uint(names, value, usage) 709 } 710 711 // Uint64Var defines a uint64 flag with specified name, default value, and usage string. 712 // The argument p points to a uint64 variable in which to store the value of the flag. 713 func (f *FlagSet) Uint64Var(p *uint64, names []string, value uint64, usage string) { 714 f.Var(newUint64Value(value, p), names, usage) 715 } 716 717 // Uint64Var defines a uint64 flag with specified name, default value, and usage string. 718 // The argument p points to a uint64 variable in which to store the value of the flag. 719 func Uint64Var(p *uint64, names []string, value uint64, usage string) { 720 CommandLine.Var(newUint64Value(value, p), names, usage) 721 } 722 723 // Uint64 defines a uint64 flag with specified name, default value, and usage string. 724 // The return value is the address of a uint64 variable that stores the value of the flag. 725 func (f *FlagSet) Uint64(names []string, value uint64, usage string) *uint64 { 726 p := new(uint64) 727 f.Uint64Var(p, names, value, usage) 728 return p 729 } 730 731 // Uint64 defines a uint64 flag with specified name, default value, and usage string. 732 // The return value is the address of a uint64 variable that stores the value of the flag. 733 func Uint64(names []string, value uint64, usage string) *uint64 { 734 return CommandLine.Uint64(names, value, usage) 735 } 736 737 // StringVar defines a string flag with specified name, default value, and usage string. 738 // The argument p points to a string variable in which to store the value of the flag. 739 func (f *FlagSet) StringVar(p *string, names []string, value string, usage string) { 740 f.Var(newStringValue(value, p), names, usage) 741 } 742 743 // StringVar defines a string flag with specified name, default value, and usage string. 744 // The argument p points to a string variable in which to store the value of the flag. 745 func StringVar(p *string, names []string, value string, usage string) { 746 CommandLine.Var(newStringValue(value, p), names, usage) 747 } 748 749 // String defines a string flag with specified name, default value, and usage string. 750 // The return value is the address of a string variable that stores the value of the flag. 751 func (f *FlagSet) String(names []string, value string, usage string) *string { 752 p := new(string) 753 f.StringVar(p, names, value, usage) 754 return p 755 } 756 757 // String defines a string flag with specified name, default value, and usage string. 758 // The return value is the address of a string variable that stores the value of the flag. 759 func String(names []string, value string, usage string) *string { 760 return CommandLine.String(names, value, usage) 761 } 762 763 // Float64Var defines a float64 flag with specified name, default value, and usage string. 764 // The argument p points to a float64 variable in which to store the value of the flag. 765 func (f *FlagSet) Float64Var(p *float64, names []string, value float64, usage string) { 766 f.Var(newFloat64Value(value, p), names, usage) 767 } 768 769 // Float64Var defines a float64 flag with specified name, default value, and usage string. 770 // The argument p points to a float64 variable in which to store the value of the flag. 771 func Float64Var(p *float64, names []string, value float64, usage string) { 772 CommandLine.Var(newFloat64Value(value, p), names, usage) 773 } 774 775 // Float64 defines a float64 flag with specified name, default value, and usage string. 776 // The return value is the address of a float64 variable that stores the value of the flag. 777 func (f *FlagSet) Float64(names []string, value float64, usage string) *float64 { 778 p := new(float64) 779 f.Float64Var(p, names, value, usage) 780 return p 781 } 782 783 // Float64 defines a float64 flag with specified name, default value, and usage string. 784 // The return value is the address of a float64 variable that stores the value of the flag. 785 func Float64(names []string, value float64, usage string) *float64 { 786 return CommandLine.Float64(names, value, usage) 787 } 788 789 // DurationVar defines a time.Duration flag with specified name, default value, and usage string. 790 // The argument p points to a time.Duration variable in which to store the value of the flag. 791 func (f *FlagSet) DurationVar(p *time.Duration, names []string, value time.Duration, usage string) { 792 f.Var(newDurationValue(value, p), names, usage) 793 } 794 795 // DurationVar defines a time.Duration flag with specified name, default value, and usage string. 796 // The argument p points to a time.Duration variable in which to store the value of the flag. 797 func DurationVar(p *time.Duration, names []string, value time.Duration, usage string) { 798 CommandLine.Var(newDurationValue(value, p), names, usage) 799 } 800 801 // Duration defines a time.Duration flag with specified name, default value, and usage string. 802 // The return value is the address of a time.Duration variable that stores the value of the flag. 803 func (f *FlagSet) Duration(names []string, value time.Duration, usage string) *time.Duration { 804 p := new(time.Duration) 805 f.DurationVar(p, names, value, usage) 806 return p 807 } 808 809 // Duration defines a time.Duration flag with specified name, default value, and usage string. 810 // The return value is the address of a time.Duration variable that stores the value of the flag. 811 func Duration(names []string, value time.Duration, usage string) *time.Duration { 812 return CommandLine.Duration(names, value, usage) 813 } 814 815 // Var defines a flag with the specified name and usage string. The type and 816 // value of the flag are represented by the first argument, of type Value, which 817 // typically holds a user-defined implementation of Value. For instance, the 818 // caller could create a flag that turns a comma-separated string into a slice 819 // of strings by giving the slice the methods of Value; in particular, Set would 820 // decompose the comma-separated string into the slice. 821 func (f *FlagSet) Var(value Value, names []string, usage string) { 822 // Remember the default value as a string; it won't change. 823 flag := &Flag{names, usage, value, value.String()} 824 for _, name := range names { 825 name = strings.TrimPrefix(name, "#") 826 _, alreadythere := f.formal[name] 827 if alreadythere { 828 var msg string 829 if f.name == "" { 830 msg = fmt.Sprintf("flag redefined: %s", name) 831 } else { 832 msg = fmt.Sprintf("%s flag redefined: %s", f.name, name) 833 } 834 fmt.Fprintln(f.Out(), msg) 835 panic(msg) // Happens only if flags are declared with identical names 836 } 837 if f.formal == nil { 838 f.formal = make(map[string]*Flag) 839 } 840 f.formal[name] = flag 841 } 842 } 843 844 // Var defines a flag with the specified name and usage string. The type and 845 // value of the flag are represented by the first argument, of type Value, which 846 // typically holds a user-defined implementation of Value. For instance, the 847 // caller could create a flag that turns a comma-separated string into a slice 848 // of strings by giving the slice the methods of Value; in particular, Set would 849 // decompose the comma-separated string into the slice. 850 func Var(value Value, names []string, usage string) { 851 CommandLine.Var(value, names, usage) 852 } 853 854 // failf prints to standard error a formatted error and usage message and 855 // returns the error. 856 func (f *FlagSet) failf(format string, a ...interface{}) error { 857 err := fmt.Errorf(format, a...) 858 fmt.Fprintln(f.Out(), err) 859 if os.Args[0] == f.name { 860 fmt.Fprintf(f.Out(), "See '%s --help'.\n", os.Args[0]) 861 } else { 862 fmt.Fprintf(f.Out(), "See '%s %s --help'.\n", os.Args[0], f.name) 863 } 864 return err 865 } 866 867 // usage calls the Usage method for the flag set, or the usage function if 868 // the flag set is CommandLine. 869 func (f *FlagSet) usage() { 870 if f == CommandLine { 871 Usage() 872 } else if f.Usage == nil { 873 defaultUsage(f) 874 } else { 875 f.Usage() 876 } 877 } 878 879 func trimQuotes(str string) string { 880 if len(str) == 0 { 881 return str 882 } 883 type quote struct { 884 start, end byte 885 } 886 887 // All valid quote types. 888 quotes := []quote{ 889 // Double quotes 890 { 891 start: '"', 892 end: '"', 893 }, 894 895 // Single quotes 896 { 897 start: '\'', 898 end: '\'', 899 }, 900 } 901 902 for _, quote := range quotes { 903 // Only strip if outermost match. 904 if str[0] == quote.start && str[len(str)-1] == quote.end { 905 str = str[1 : len(str)-1] 906 break 907 } 908 } 909 910 return str 911 } 912 913 // parseOne parses one flag. It reports whether a flag was seen. 914 func (f *FlagSet) parseOne() (bool, string, error) { 915 if len(f.args) == 0 { 916 return false, "", nil 917 } 918 s := f.args[0] 919 if len(s) == 0 || s[0] != '-' || len(s) == 1 { 920 return false, "", nil 921 } 922 if s[1] == '-' && len(s) == 2 { // "--" terminates the flags 923 f.args = f.args[1:] 924 return false, "", nil 925 } 926 name := s[1:] 927 if len(name) == 0 || name[0] == '=' { 928 return false, "", f.failf("bad flag syntax: %s", s) 929 } 930 931 // it's a flag. does it have an argument? 932 f.args = f.args[1:] 933 has_value := false 934 value := "" 935 if i := strings.Index(name, "="); i != -1 { 936 value = trimQuotes(name[i+1:]) 937 has_value = true 938 name = name[:i] 939 } 940 941 m := f.formal 942 flag, alreadythere := m[name] // BUG 943 if !alreadythere { 944 if name == "-help" || name == "help" || name == "h" { // special case for nice help message. 945 f.usage() 946 return false, "", ErrHelp 947 } 948 if len(name) > 0 && name[0] == '-' { 949 return false, "", f.failf("flag provided but not defined: -%s", name) 950 } 951 return false, name, ErrRetry 952 } 953 if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg 954 if has_value { 955 if err := fv.Set(value); err != nil { 956 return false, "", f.failf("invalid boolean value %q for -%s: %v", value, name, err) 957 } 958 } else { 959 fv.Set("true") 960 } 961 } else { 962 // It must have a value, which might be the next argument. 963 if !has_value && len(f.args) > 0 { 964 // value is the next arg 965 has_value = true 966 value, f.args = f.args[0], f.args[1:] 967 } 968 if !has_value { 969 return false, "", f.failf("flag needs an argument: -%s", name) 970 } 971 if err := flag.Value.Set(value); err != nil { 972 return false, "", f.failf("invalid value %q for flag -%s: %v", value, name, err) 973 } 974 } 975 if f.actual == nil { 976 f.actual = make(map[string]*Flag) 977 } 978 f.actual[name] = flag 979 for i, n := range flag.Names { 980 if n == fmt.Sprintf("#%s", name) { 981 replacement := "" 982 for j := i; j < len(flag.Names); j++ { 983 if flag.Names[j][0] != '#' { 984 replacement = flag.Names[j] 985 break 986 } 987 } 988 if replacement != "" { 989 fmt.Fprintf(f.Out(), "Warning: '-%s' is deprecated, it will be replaced by '-%s' soon. See usage.\n", name, replacement) 990 } else { 991 fmt.Fprintf(f.Out(), "Warning: '-%s' is deprecated, it will be removed soon. See usage.\n", name) 992 } 993 } 994 } 995 return true, "", nil 996 } 997 998 // Parse parses flag definitions from the argument list, which should not 999 // include the command name. Must be called after all flags in the FlagSet 1000 // are defined and before flags are accessed by the program. 1001 // The return value will be ErrHelp if -help was set but not defined. 1002 func (f *FlagSet) Parse(arguments []string) error { 1003 f.parsed = true 1004 f.args = arguments 1005 for { 1006 seen, name, err := f.parseOne() 1007 if seen { 1008 continue 1009 } 1010 if err == nil { 1011 break 1012 } 1013 if err == ErrRetry { 1014 if len(name) > 1 { 1015 err = nil 1016 for _, letter := range strings.Split(name, "") { 1017 f.args = append([]string{"-" + letter}, f.args...) 1018 seen2, _, err2 := f.parseOne() 1019 if seen2 { 1020 continue 1021 } 1022 if err2 != nil { 1023 err = f.failf("flag provided but not defined: -%s", name) 1024 break 1025 } 1026 } 1027 if err == nil { 1028 continue 1029 } 1030 } else { 1031 err = f.failf("flag provided but not defined: -%s", name) 1032 } 1033 } 1034 switch f.errorHandling { 1035 case ContinueOnError: 1036 return err 1037 case ExitOnError: 1038 os.Exit(2) 1039 case PanicOnError: 1040 panic(err) 1041 } 1042 } 1043 return nil 1044 } 1045 1046 // Parsed reports whether f.Parse has been called. 1047 func (f *FlagSet) Parsed() bool { 1048 return f.parsed 1049 } 1050 1051 // Parse parses the command-line flags from os.Args[1:]. Must be called 1052 // after all flags are defined and before flags are accessed by the program. 1053 func Parse() { 1054 // Ignore errors; CommandLine is set for ExitOnError. 1055 CommandLine.Parse(os.Args[1:]) 1056 } 1057 1058 // Parsed returns true if the command-line flags have been parsed. 1059 func Parsed() bool { 1060 return CommandLine.Parsed() 1061 } 1062 1063 // CommandLine is the default set of command-line flags, parsed from os.Args. 1064 // The top-level functions such as BoolVar, Arg, and on are wrappers for the 1065 // methods of CommandLine. 1066 var CommandLine = NewFlagSet(os.Args[0], ExitOnError) 1067 1068 // NewFlagSet returns a new, empty flag set with the specified name and 1069 // error handling property. 1070 func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet { 1071 f := &FlagSet{ 1072 name: name, 1073 errorHandling: errorHandling, 1074 } 1075 return f 1076 } 1077 1078 // Init sets the name and error handling property for a flag set. 1079 // By default, the zero FlagSet uses an empty name and the 1080 // ContinueOnError error handling policy. 1081 func (f *FlagSet) Init(name string, errorHandling ErrorHandling) { 1082 f.name = name 1083 f.errorHandling = errorHandling 1084 }