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