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