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