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