github.com/hbdrawn/golang@v0.0.0-20141214014649-6b835209aba2/src/flag/flag.go (about) 1 // Copyright 2009 The 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, -flagname, stored in the pointer ip, with type *int. 13 import "flag" 14 var ip = flag.Int("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 flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname") 19 } 20 Or you can create custom flags that satisfy the Value interface (with 21 pointer receivers) and couple them to flag parsing by 22 flag.Var(&flagVal, "name", "help message for flagname") 23 For such flags, the default value is just the initial value of the variable. 24 25 After all flags are defined, call 26 flag.Parse() 27 to parse the command line into the defined flags. 28 29 Flags may then be used directly. If you're using the flags themselves, 30 they are all pointers; if you bind to variables, they're values. 31 fmt.Println("ip has value ", *ip) 32 fmt.Println("flagvar has value ", flagvar) 33 34 After parsing, the arguments after the flag are available as the 35 slice flag.Args() or individually as flag.Arg(i). 36 The arguments are indexed from 0 through flag.NArg()-1. 37 38 Command line flag syntax: 39 -flag 40 -flag=x 41 -flag x // non-boolean flags only 42 One or two minus signs may be used; they are equivalent. 43 The last form is not permitted for boolean flags because the 44 meaning of the command 45 cmd -x * 46 will change if there is a file called 0, false, etc. You must 47 use the -flag=false form to turn off a boolean flag. 48 49 Flag parsing stops just before the first non-flag argument 50 ("-" is a non-flag argument) or after the terminator "--". 51 52 Integer flags accept 1234, 0664, 0x1234 and may be negative. 53 Boolean flags may be: 54 1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False 55 Duration flags accept any input valid for time.ParseDuration. 56 57 The default set of command-line flags is controlled by 58 top-level functions. The FlagSet type allows one to define 59 independent sets of flags, such as to implement subcommands 60 in a command-line interface. The methods of FlagSet are 61 analogous to the top-level functions for the command-line 62 flag set. 63 */ 64 package flag 65 66 import ( 67 "errors" 68 "fmt" 69 "io" 70 "os" 71 "sort" 72 "strconv" 73 "time" 74 ) 75 76 // ErrHelp is the error returned if the -help or -h flag is invoked 77 // but no such flag is defined. 78 var ErrHelp = errors.New("flag: help requested") 79 80 // -- bool Value 81 type boolValue bool 82 83 func newBoolValue(val bool, p *bool) *boolValue { 84 *p = val 85 return (*boolValue)(p) 86 } 87 88 func (b *boolValue) Set(s string) error { 89 v, err := strconv.ParseBool(s) 90 *b = boolValue(v) 91 return err 92 } 93 94 func (b *boolValue) Get() interface{} { return bool(*b) } 95 96 func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) } 97 98 func (b *boolValue) IsBoolFlag() bool { return true } 99 100 // optional interface to indicate boolean flags that can be 101 // supplied without "=value" text 102 type boolFlag interface { 103 Value 104 IsBoolFlag() bool 105 } 106 107 // -- int Value 108 type intValue int 109 110 func newIntValue(val int, p *int) *intValue { 111 *p = val 112 return (*intValue)(p) 113 } 114 115 func (i *intValue) Set(s string) error { 116 v, err := strconv.ParseInt(s, 0, 64) 117 *i = intValue(v) 118 return err 119 } 120 121 func (i *intValue) Get() interface{} { return int(*i) } 122 123 func (i *intValue) String() string { return fmt.Sprintf("%v", *i) } 124 125 // -- int64 Value 126 type int64Value int64 127 128 func newInt64Value(val int64, p *int64) *int64Value { 129 *p = val 130 return (*int64Value)(p) 131 } 132 133 func (i *int64Value) Set(s string) error { 134 v, err := strconv.ParseInt(s, 0, 64) 135 *i = int64Value(v) 136 return err 137 } 138 139 func (i *int64Value) Get() interface{} { return int64(*i) } 140 141 func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) } 142 143 // -- uint Value 144 type uintValue uint 145 146 func newUintValue(val uint, p *uint) *uintValue { 147 *p = val 148 return (*uintValue)(p) 149 } 150 151 func (i *uintValue) Set(s string) error { 152 v, err := strconv.ParseUint(s, 0, 64) 153 *i = uintValue(v) 154 return err 155 } 156 157 func (i *uintValue) Get() interface{} { return uint(*i) } 158 159 func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) } 160 161 // -- uint64 Value 162 type uint64Value uint64 163 164 func newUint64Value(val uint64, p *uint64) *uint64Value { 165 *p = val 166 return (*uint64Value)(p) 167 } 168 169 func (i *uint64Value) Set(s string) error { 170 v, err := strconv.ParseUint(s, 0, 64) 171 *i = uint64Value(v) 172 return err 173 } 174 175 func (i *uint64Value) Get() interface{} { return uint64(*i) } 176 177 func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) } 178 179 // -- string Value 180 type stringValue string 181 182 func newStringValue(val string, p *string) *stringValue { 183 *p = val 184 return (*stringValue)(p) 185 } 186 187 func (s *stringValue) Set(val string) error { 188 *s = stringValue(val) 189 return nil 190 } 191 192 func (s *stringValue) Get() interface{} { return string(*s) } 193 194 func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) } 195 196 // -- float64 Value 197 type float64Value float64 198 199 func newFloat64Value(val float64, p *float64) *float64Value { 200 *p = val 201 return (*float64Value)(p) 202 } 203 204 func (f *float64Value) Set(s string) error { 205 v, err := strconv.ParseFloat(s, 64) 206 *f = float64Value(v) 207 return err 208 } 209 210 func (f *float64Value) Get() interface{} { return float64(*f) } 211 212 func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) } 213 214 // -- time.Duration Value 215 type durationValue time.Duration 216 217 func newDurationValue(val time.Duration, p *time.Duration) *durationValue { 218 *p = val 219 return (*durationValue)(p) 220 } 221 222 func (d *durationValue) Set(s string) error { 223 v, err := time.ParseDuration(s) 224 *d = durationValue(v) 225 return err 226 } 227 228 func (d *durationValue) Get() interface{} { return time.Duration(*d) } 229 230 func (d *durationValue) String() string { return (*time.Duration)(d).String() } 231 232 // Value is the interface to the dynamic value stored in a flag. 233 // (The default value is represented as a string.) 234 // 235 // If a Value has an IsBoolFlag() bool method returning true, 236 // the command-line parser makes -name equivalent to -name=true 237 // rather than using the next command-line argument. 238 type Value interface { 239 String() string 240 Set(string) error 241 } 242 243 // Getter is an interface that allows the contents of a Value to be retrieved. 244 // It wraps the Value interface, rather than being part of it, because it 245 // appeared after Go 1 and its compatibility rules. All Value types provided 246 // by this package satisfy the Getter interface. 247 type Getter interface { 248 Value 249 Get() interface{} 250 } 251 252 // ErrorHandling defines how to handle flag parsing errors. 253 type ErrorHandling int 254 255 const ( 256 ContinueOnError ErrorHandling = iota 257 ExitOnError 258 PanicOnError 259 ) 260 261 // A FlagSet represents a set of defined flags. The zero value of a FlagSet 262 // has no name and has ContinueOnError error handling. 263 type FlagSet struct { 264 // Usage is the function called when an error occurs while parsing flags. 265 // The field is a function (not a method) that may be changed to point to 266 // a custom error handler. 267 Usage func() 268 269 name string 270 parsed bool 271 actual map[string]*Flag 272 formal map[string]*Flag 273 args []string // arguments after flags 274 errorHandling ErrorHandling 275 output io.Writer // nil means stderr; use out() accessor 276 } 277 278 // A Flag represents the state of a flag. 279 type Flag struct { 280 Name string // name as it appears on command line 281 Usage string // help message 282 Value Value // value as set 283 DefValue string // default value (as text); for usage message 284 } 285 286 // sortFlags returns the flags as a slice in lexicographical sorted order. 287 func sortFlags(flags map[string]*Flag) []*Flag { 288 list := make(sort.StringSlice, len(flags)) 289 i := 0 290 for _, f := range flags { 291 list[i] = f.Name 292 i++ 293 } 294 list.Sort() 295 result := make([]*Flag, len(list)) 296 for i, name := range list { 297 result[i] = flags[name] 298 } 299 return result 300 } 301 302 func (f *FlagSet) out() io.Writer { 303 if f.output == nil { 304 return os.Stderr 305 } 306 return f.output 307 } 308 309 // SetOutput sets the destination for usage and error messages. 310 // If output is nil, os.Stderr is used. 311 func (f *FlagSet) SetOutput(output io.Writer) { 312 f.output = output 313 } 314 315 // VisitAll visits the flags in lexicographical order, calling fn for each. 316 // It visits all flags, even those not set. 317 func (f *FlagSet) VisitAll(fn func(*Flag)) { 318 for _, flag := range sortFlags(f.formal) { 319 fn(flag) 320 } 321 } 322 323 // VisitAll visits the command-line flags in lexicographical order, calling 324 // fn for each. It visits all flags, even those not set. 325 func VisitAll(fn func(*Flag)) { 326 CommandLine.VisitAll(fn) 327 } 328 329 // Visit visits the flags in lexicographical order, calling fn for each. 330 // It visits only those flags that have been set. 331 func (f *FlagSet) Visit(fn func(*Flag)) { 332 for _, flag := range sortFlags(f.actual) { 333 fn(flag) 334 } 335 } 336 337 // Visit visits the command-line flags in lexicographical order, calling fn 338 // for each. It visits only those flags that have been set. 339 func Visit(fn func(*Flag)) { 340 CommandLine.Visit(fn) 341 } 342 343 // Lookup returns the Flag structure of the named flag, returning nil if none exists. 344 func (f *FlagSet) Lookup(name string) *Flag { 345 return f.formal[name] 346 } 347 348 // Lookup returns the Flag structure of the named command-line flag, 349 // returning nil if none exists. 350 func Lookup(name string) *Flag { 351 return CommandLine.formal[name] 352 } 353 354 // Set sets the value of the named flag. 355 func (f *FlagSet) Set(name, value string) error { 356 flag, ok := f.formal[name] 357 if !ok { 358 return fmt.Errorf("no such flag -%v", name) 359 } 360 err := flag.Value.Set(value) 361 if err != nil { 362 return err 363 } 364 if f.actual == nil { 365 f.actual = make(map[string]*Flag) 366 } 367 f.actual[name] = flag 368 return nil 369 } 370 371 // Set sets the value of the named command-line flag. 372 func Set(name, value string) error { 373 return CommandLine.Set(name, value) 374 } 375 376 // PrintDefaults prints, to standard error unless configured 377 // otherwise, the default values of all defined flags in the set. 378 func (f *FlagSet) PrintDefaults() { 379 f.VisitAll(func(flag *Flag) { 380 format := " -%s=%s: %s\n" 381 if _, ok := flag.Value.(*stringValue); ok { 382 // put quotes on the value 383 format = " -%s=%q: %s\n" 384 } 385 fmt.Fprintf(f.out(), format, flag.Name, flag.DefValue, flag.Usage) 386 }) 387 } 388 389 // PrintDefaults prints to standard error the default values of all defined command-line flags. 390 func PrintDefaults() { 391 CommandLine.PrintDefaults() 392 } 393 394 // defaultUsage is the default function to print a usage message. 395 func defaultUsage(f *FlagSet) { 396 if f.name == "" { 397 fmt.Fprintf(f.out(), "Usage:\n") 398 } else { 399 fmt.Fprintf(f.out(), "Usage of %s:\n", f.name) 400 } 401 f.PrintDefaults() 402 } 403 404 // NOTE: Usage is not just defaultUsage(CommandLine) 405 // because it serves (via godoc flag Usage) as the example 406 // for how to write your own usage function. 407 408 // Usage prints to standard error a usage message documenting all defined command-line flags. 409 // It is called when an error occurs while parsing flags. 410 // The function is a variable that may be changed to point to a custom function. 411 var Usage = func() { 412 fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) 413 PrintDefaults() 414 } 415 416 // NFlag returns the number of flags that have been set. 417 func (f *FlagSet) NFlag() int { return len(f.actual) } 418 419 // NFlag returns the number of command-line flags that have been set. 420 func NFlag() int { return len(CommandLine.actual) } 421 422 // Arg returns the i'th argument. Arg(0) is the first remaining argument 423 // after flags have been processed. 424 func (f *FlagSet) Arg(i int) string { 425 if i < 0 || i >= len(f.args) { 426 return "" 427 } 428 return f.args[i] 429 } 430 431 // Arg returns the i'th command-line argument. Arg(0) is the first remaining argument 432 // after flags have been processed. 433 func Arg(i int) string { 434 return CommandLine.Arg(i) 435 } 436 437 // NArg is the number of arguments remaining after flags have been processed. 438 func (f *FlagSet) NArg() int { return len(f.args) } 439 440 // NArg is the number of arguments remaining after flags have been processed. 441 func NArg() int { return len(CommandLine.args) } 442 443 // Args returns the non-flag arguments. 444 func (f *FlagSet) Args() []string { return f.args } 445 446 // Args returns the non-flag command-line arguments. 447 func Args() []string { return CommandLine.args } 448 449 // BoolVar defines a bool flag with specified name, default value, and usage string. 450 // The argument p points to a bool variable in which to store the value of the flag. 451 func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) { 452 f.Var(newBoolValue(value, p), name, usage) 453 } 454 455 // BoolVar defines a bool flag with specified name, default value, and usage string. 456 // The argument p points to a bool variable in which to store the value of the flag. 457 func BoolVar(p *bool, name string, value bool, usage string) { 458 CommandLine.Var(newBoolValue(value, p), name, usage) 459 } 460 461 // Bool defines a bool flag with specified name, default value, and usage string. 462 // The return value is the address of a bool variable that stores the value of the flag. 463 func (f *FlagSet) Bool(name string, value bool, usage string) *bool { 464 p := new(bool) 465 f.BoolVar(p, name, value, usage) 466 return p 467 } 468 469 // Bool defines a bool flag with specified name, default value, and usage string. 470 // The return value is the address of a bool variable that stores the value of the flag. 471 func Bool(name string, value bool, usage string) *bool { 472 return CommandLine.Bool(name, value, usage) 473 } 474 475 // IntVar defines an int flag with specified name, default value, and usage string. 476 // The argument p points to an int variable in which to store the value of the flag. 477 func (f *FlagSet) IntVar(p *int, name string, value int, usage string) { 478 f.Var(newIntValue(value, p), name, usage) 479 } 480 481 // IntVar defines an int flag with specified name, default value, and usage string. 482 // The argument p points to an int variable in which to store the value of the flag. 483 func IntVar(p *int, name string, value int, usage string) { 484 CommandLine.Var(newIntValue(value, p), name, usage) 485 } 486 487 // Int defines an int flag with specified name, default value, and usage string. 488 // The return value is the address of an int variable that stores the value of the flag. 489 func (f *FlagSet) Int(name string, value int, usage string) *int { 490 p := new(int) 491 f.IntVar(p, name, value, usage) 492 return p 493 } 494 495 // Int defines an int flag with specified name, default value, and usage string. 496 // The return value is the address of an int variable that stores the value of the flag. 497 func Int(name string, value int, usage string) *int { 498 return CommandLine.Int(name, value, usage) 499 } 500 501 // Int64Var defines an int64 flag with specified name, default value, and usage string. 502 // The argument p points to an int64 variable in which to store the value of the flag. 503 func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) { 504 f.Var(newInt64Value(value, p), name, usage) 505 } 506 507 // Int64Var defines an int64 flag with specified name, default value, and usage string. 508 // The argument p points to an int64 variable in which to store the value of the flag. 509 func Int64Var(p *int64, name string, value int64, usage string) { 510 CommandLine.Var(newInt64Value(value, p), name, usage) 511 } 512 513 // Int64 defines an int64 flag with specified name, default value, and usage string. 514 // The return value is the address of an int64 variable that stores the value of the flag. 515 func (f *FlagSet) Int64(name string, value int64, usage string) *int64 { 516 p := new(int64) 517 f.Int64Var(p, name, value, usage) 518 return p 519 } 520 521 // Int64 defines an int64 flag with specified name, default value, and usage string. 522 // The return value is the address of an int64 variable that stores the value of the flag. 523 func Int64(name string, value int64, usage string) *int64 { 524 return CommandLine.Int64(name, value, usage) 525 } 526 527 // UintVar defines a uint flag with specified name, default value, and usage string. 528 // The argument p points to a uint variable in which to store the value of the flag. 529 func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) { 530 f.Var(newUintValue(value, p), name, usage) 531 } 532 533 // UintVar defines a uint flag with specified name, default value, and usage string. 534 // The argument p points to a uint variable in which to store the value of the flag. 535 func UintVar(p *uint, name string, value uint, usage string) { 536 CommandLine.Var(newUintValue(value, p), name, usage) 537 } 538 539 // Uint defines a uint flag with specified name, default value, and usage string. 540 // The return value is the address of a uint variable that stores the value of the flag. 541 func (f *FlagSet) Uint(name string, value uint, usage string) *uint { 542 p := new(uint) 543 f.UintVar(p, name, value, usage) 544 return p 545 } 546 547 // Uint defines a uint flag with specified name, default value, and usage string. 548 // The return value is the address of a uint variable that stores the value of the flag. 549 func Uint(name string, value uint, usage string) *uint { 550 return CommandLine.Uint(name, value, usage) 551 } 552 553 // Uint64Var defines a uint64 flag with specified name, default value, and usage string. 554 // The argument p points to a uint64 variable in which to store the value of the flag. 555 func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) { 556 f.Var(newUint64Value(value, p), name, usage) 557 } 558 559 // Uint64Var defines a uint64 flag with specified name, default value, and usage string. 560 // The argument p points to a uint64 variable in which to store the value of the flag. 561 func Uint64Var(p *uint64, name string, value uint64, usage string) { 562 CommandLine.Var(newUint64Value(value, p), name, usage) 563 } 564 565 // Uint64 defines a uint64 flag with specified name, default value, and usage string. 566 // The return value is the address of a uint64 variable that stores the value of the flag. 567 func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 { 568 p := new(uint64) 569 f.Uint64Var(p, name, value, usage) 570 return p 571 } 572 573 // Uint64 defines a uint64 flag with specified name, default value, and usage string. 574 // The return value is the address of a uint64 variable that stores the value of the flag. 575 func Uint64(name string, value uint64, usage string) *uint64 { 576 return CommandLine.Uint64(name, value, usage) 577 } 578 579 // StringVar defines a string flag with specified name, default value, and usage string. 580 // The argument p points to a string variable in which to store the value of the flag. 581 func (f *FlagSet) StringVar(p *string, name string, value string, usage string) { 582 f.Var(newStringValue(value, p), name, usage) 583 } 584 585 // StringVar defines a string flag with specified name, default value, and usage string. 586 // The argument p points to a string variable in which to store the value of the flag. 587 func StringVar(p *string, name string, value string, usage string) { 588 CommandLine.Var(newStringValue(value, p), name, usage) 589 } 590 591 // String defines a string flag with specified name, default value, and usage string. 592 // The return value is the address of a string variable that stores the value of the flag. 593 func (f *FlagSet) String(name string, value string, usage string) *string { 594 p := new(string) 595 f.StringVar(p, name, value, usage) 596 return p 597 } 598 599 // String defines a string flag with specified name, default value, and usage string. 600 // The return value is the address of a string variable that stores the value of the flag. 601 func String(name string, value string, usage string) *string { 602 return CommandLine.String(name, value, usage) 603 } 604 605 // Float64Var defines a float64 flag with specified name, default value, and usage string. 606 // The argument p points to a float64 variable in which to store the value of the flag. 607 func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) { 608 f.Var(newFloat64Value(value, p), name, usage) 609 } 610 611 // Float64Var defines a float64 flag with specified name, default value, and usage string. 612 // The argument p points to a float64 variable in which to store the value of the flag. 613 func Float64Var(p *float64, name string, value float64, usage string) { 614 CommandLine.Var(newFloat64Value(value, p), name, usage) 615 } 616 617 // Float64 defines a float64 flag with specified name, default value, and usage string. 618 // The return value is the address of a float64 variable that stores the value of the flag. 619 func (f *FlagSet) Float64(name string, value float64, usage string) *float64 { 620 p := new(float64) 621 f.Float64Var(p, name, value, usage) 622 return p 623 } 624 625 // Float64 defines a float64 flag with specified name, default value, and usage string. 626 // The return value is the address of a float64 variable that stores the value of the flag. 627 func Float64(name string, value float64, usage string) *float64 { 628 return CommandLine.Float64(name, value, usage) 629 } 630 631 // DurationVar defines a time.Duration flag with specified name, default value, and usage string. 632 // The argument p points to a time.Duration variable in which to store the value of the flag. 633 // The flag accepts a value acceptable to time.ParseDuration. 634 func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) { 635 f.Var(newDurationValue(value, p), name, usage) 636 } 637 638 // DurationVar defines a time.Duration flag with specified name, default value, and usage string. 639 // The argument p points to a time.Duration variable in which to store the value of the flag. 640 // The flag accepts a value acceptable to time.ParseDuration. 641 func DurationVar(p *time.Duration, name string, value time.Duration, usage string) { 642 CommandLine.Var(newDurationValue(value, p), name, usage) 643 } 644 645 // Duration defines a time.Duration flag with specified name, default value, and usage string. 646 // The return value is the address of a time.Duration variable that stores the value of the flag. 647 // The flag accepts a value acceptable to time.ParseDuration. 648 func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration { 649 p := new(time.Duration) 650 f.DurationVar(p, name, value, usage) 651 return p 652 } 653 654 // Duration defines a time.Duration flag with specified name, default value, and usage string. 655 // The return value is the address of a time.Duration variable that stores the value of the flag. 656 // The flag accepts a value acceptable to time.ParseDuration. 657 func Duration(name string, value time.Duration, usage string) *time.Duration { 658 return CommandLine.Duration(name, value, usage) 659 } 660 661 // Var defines a flag with the specified name and usage string. The type and 662 // value of the flag are represented by the first argument, of type Value, which 663 // typically holds a user-defined implementation of Value. For instance, the 664 // caller could create a flag that turns a comma-separated string into a slice 665 // of strings by giving the slice the methods of Value; in particular, Set would 666 // decompose the comma-separated string into the slice. 667 func (f *FlagSet) Var(value Value, name string, usage string) { 668 // Remember the default value as a string; it won't change. 669 flag := &Flag{name, usage, value, value.String()} 670 _, alreadythere := f.formal[name] 671 if alreadythere { 672 var msg string 673 if f.name == "" { 674 msg = fmt.Sprintf("flag redefined: %s", name) 675 } else { 676 msg = fmt.Sprintf("%s flag redefined: %s", f.name, name) 677 } 678 fmt.Fprintln(f.out(), msg) 679 panic(msg) // Happens only if flags are declared with identical names 680 } 681 if f.formal == nil { 682 f.formal = make(map[string]*Flag) 683 } 684 f.formal[name] = flag 685 } 686 687 // Var defines a flag with the specified name and usage string. The type and 688 // value of the flag are represented by the first argument, of type Value, which 689 // typically holds a user-defined implementation of Value. For instance, the 690 // caller could create a flag that turns a comma-separated string into a slice 691 // of strings by giving the slice the methods of Value; in particular, Set would 692 // decompose the comma-separated string into the slice. 693 func Var(value Value, name string, usage string) { 694 CommandLine.Var(value, name, usage) 695 } 696 697 // failf prints to standard error a formatted error and usage message and 698 // returns the error. 699 func (f *FlagSet) failf(format string, a ...interface{}) error { 700 err := fmt.Errorf(format, a...) 701 fmt.Fprintln(f.out(), err) 702 f.usage() 703 return err 704 } 705 706 // usage calls the Usage method for the flag set if one is specified, 707 // or the appropriate default usage function otherwise. 708 func (f *FlagSet) usage() { 709 if f.Usage == nil { 710 if f == CommandLine { 711 Usage() 712 } else { 713 defaultUsage(f) 714 } 715 } else { 716 f.Usage() 717 } 718 } 719 720 // parseOne parses one flag. It reports whether a flag was seen. 721 func (f *FlagSet) parseOne() (bool, error) { 722 if len(f.args) == 0 { 723 return false, nil 724 } 725 s := f.args[0] 726 if len(s) == 0 || s[0] != '-' || len(s) == 1 { 727 return false, nil 728 } 729 num_minuses := 1 730 if s[1] == '-' { 731 num_minuses++ 732 if len(s) == 2 { // "--" terminates the flags 733 f.args = f.args[1:] 734 return false, nil 735 } 736 } 737 name := s[num_minuses:] 738 if len(name) == 0 || name[0] == '-' || name[0] == '=' { 739 return false, f.failf("bad flag syntax: %s", s) 740 } 741 742 // it's a flag. does it have an argument? 743 f.args = f.args[1:] 744 has_value := false 745 value := "" 746 for i := 1; i < len(name); i++ { // equals cannot be first 747 if name[i] == '=' { 748 value = name[i+1:] 749 has_value = true 750 name = name[0:i] 751 break 752 } 753 } 754 m := f.formal 755 flag, alreadythere := m[name] // BUG 756 if !alreadythere { 757 if name == "help" || name == "h" { // special case for nice help message. 758 f.usage() 759 return false, ErrHelp 760 } 761 return false, f.failf("flag provided but not defined: -%s", name) 762 } 763 764 if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg 765 if has_value { 766 if err := fv.Set(value); err != nil { 767 return false, f.failf("invalid boolean value %q for -%s: %v", value, name, err) 768 } 769 } else { 770 fv.Set("true") 771 } 772 } else { 773 // It must have a value, which might be the next argument. 774 if !has_value && len(f.args) > 0 { 775 // value is the next arg 776 has_value = true 777 value, f.args = f.args[0], f.args[1:] 778 } 779 if !has_value { 780 return false, f.failf("flag needs an argument: -%s", name) 781 } 782 if err := flag.Value.Set(value); err != nil { 783 return false, f.failf("invalid value %q for flag -%s: %v", value, name, err) 784 } 785 } 786 if f.actual == nil { 787 f.actual = make(map[string]*Flag) 788 } 789 f.actual[name] = flag 790 return true, nil 791 } 792 793 // Parse parses flag definitions from the argument list, which should not 794 // include the command name. Must be called after all flags in the FlagSet 795 // are defined and before flags are accessed by the program. 796 // The return value will be ErrHelp if -help or -h were set but not defined. 797 func (f *FlagSet) Parse(arguments []string) error { 798 f.parsed = true 799 f.args = arguments 800 for { 801 seen, err := f.parseOne() 802 if seen { 803 continue 804 } 805 if err == nil { 806 break 807 } 808 switch f.errorHandling { 809 case ContinueOnError: 810 return err 811 case ExitOnError: 812 os.Exit(2) 813 case PanicOnError: 814 panic(err) 815 } 816 } 817 return nil 818 } 819 820 // Parsed reports whether f.Parse has been called. 821 func (f *FlagSet) Parsed() bool { 822 return f.parsed 823 } 824 825 // Parse parses the command-line flags from os.Args[1:]. Must be called 826 // after all flags are defined and before flags are accessed by the program. 827 func Parse() { 828 // Ignore errors; CommandLine is set for ExitOnError. 829 CommandLine.Parse(os.Args[1:]) 830 } 831 832 // Parsed returns true if the command-line flags have been parsed. 833 func Parsed() bool { 834 return CommandLine.Parsed() 835 } 836 837 // CommandLine is the default set of command-line flags, parsed from os.Args. 838 // The top-level functions such as BoolVar, Arg, and so on are wrappers for the 839 // methods of CommandLine. 840 var CommandLine = NewFlagSet(os.Args[0], ExitOnError) 841 842 // NewFlagSet returns a new, empty flag set with the specified name and 843 // error handling property. 844 func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet { 845 f := &FlagSet{ 846 name: name, 847 errorHandling: errorHandling, 848 } 849 return f 850 } 851 852 // Init sets the name and error handling property for a flag set. 853 // By default, the zero FlagSet uses an empty name and the 854 // ContinueOnError error handling policy. 855 func (f *FlagSet) Init(name string, errorHandling ErrorHandling) { 856 f.name = name 857 f.errorHandling = errorHandling 858 }