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