Source file src/pkg/flag/flag.go
1
2
3
4
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
63 package flag
64
65 import (
66 "errors"
67 "fmt"
68 "io"
69 "os"
70 "sort"
71 "strconv"
72 "time"
73 )
74
75
76 var ErrHelp = errors.New("flag: help requested")
77
78
79 type boolValue bool
80
81 func newBoolValue(val bool, p *bool) *boolValue {
82 *p = val
83 return (*boolValue)(p)
84 }
85
86 func (b *boolValue) Set(s string) error {
87 v, err := strconv.ParseBool(s)
88 *b = boolValue(v)
89 return err
90 }
91
92 func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) }
93
94 func (b *boolValue) IsBoolFlag() bool { return true }
95
96
97
98 type boolFlag interface {
99 Value
100 IsBoolFlag() bool
101 }
102
103
104 type intValue int
105
106 func newIntValue(val int, p *int) *intValue {
107 *p = val
108 return (*intValue)(p)
109 }
110
111 func (i *intValue) Set(s string) error {
112 v, err := strconv.ParseInt(s, 0, 64)
113 *i = intValue(v)
114 return err
115 }
116
117 func (i *intValue) String() string { return fmt.Sprintf("%v", *i) }
118
119
120 type int64Value int64
121
122 func newInt64Value(val int64, p *int64) *int64Value {
123 *p = val
124 return (*int64Value)(p)
125 }
126
127 func (i *int64Value) Set(s string) error {
128 v, err := strconv.ParseInt(s, 0, 64)
129 *i = int64Value(v)
130 return err
131 }
132
133 func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) }
134
135
136 type uintValue uint
137
138 func newUintValue(val uint, p *uint) *uintValue {
139 *p = val
140 return (*uintValue)(p)
141 }
142
143 func (i *uintValue) Set(s string) error {
144 v, err := strconv.ParseUint(s, 0, 64)
145 *i = uintValue(v)
146 return err
147 }
148
149 func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
150
151
152 type uint64Value uint64
153
154 func newUint64Value(val uint64, p *uint64) *uint64Value {
155 *p = val
156 return (*uint64Value)(p)
157 }
158
159 func (i *uint64Value) Set(s string) error {
160 v, err := strconv.ParseUint(s, 0, 64)
161 *i = uint64Value(v)
162 return err
163 }
164
165 func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
166
167
168 type stringValue string
169
170 func newStringValue(val string, p *string) *stringValue {
171 *p = val
172 return (*stringValue)(p)
173 }
174
175 func (s *stringValue) Set(val string) error {
176 *s = stringValue(val)
177 return nil
178 }
179
180 func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) }
181
182
183 type float64Value float64
184
185 func newFloat64Value(val float64, p *float64) *float64Value {
186 *p = val
187 return (*float64Value)(p)
188 }
189
190 func (f *float64Value) Set(s string) error {
191 v, err := strconv.ParseFloat(s, 64)
192 *f = float64Value(v)
193 return err
194 }
195
196 func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
197
198
199 type durationValue time.Duration
200
201 func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
202 *p = val
203 return (*durationValue)(p)
204 }
205
206 func (d *durationValue) Set(s string) error {
207 v, err := time.ParseDuration(s)
208 *d = durationValue(v)
209 return err
210 }
211
212 func (d *durationValue) String() string { return (*time.Duration)(d).String() }
213
214
215
216
217
218
219
220 type Value interface {
221 String() string
222 Set(string) error
223 }
224
225
226 type ErrorHandling int
227
228 const (
229 ContinueOnError ErrorHandling = iota
230 ExitOnError
231 PanicOnError
232 )
233
234
235 type FlagSet struct {
236
237
238
239 Usage func()
240
241 name string
242 parsed bool
243 actual map[string]*Flag
244 formal map[string]*Flag
245 args []string
246 exitOnError bool
247 errorHandling ErrorHandling
248 output io.Writer
249 }
250
251
252 type Flag struct {
253 Name string
254 Usage string
255 Value Value
256 DefValue string
257 }
258
259
260 func sortFlags(flags map[string]*Flag) []*Flag {
261 list := make(sort.StringSlice, len(flags))
262 i := 0
263 for _, f := range flags {
264 list[i] = f.Name
265 i++
266 }
267 list.Sort()
268 result := make([]*Flag, len(list))
269 for i, name := range list {
270 result[i] = flags[name]
271 }
272 return result
273 }
274
275 func (f *FlagSet) out() io.Writer {
276 if f.output == nil {
277 return os.Stderr
278 }
279 return f.output
280 }
281
282
283
284 func (f *FlagSet) SetOutput(output io.Writer) {
285 f.output = output
286 }
287
288
289
290 func (f *FlagSet) VisitAll(fn func(*Flag)) {
291 for _, flag := range sortFlags(f.formal) {
292 fn(flag)
293 }
294 }
295
296
297
298 func VisitAll(fn func(*Flag)) {
299 commandLine.VisitAll(fn)
300 }
301
302
303
304 func (f *FlagSet) Visit(fn func(*Flag)) {
305 for _, flag := range sortFlags(f.actual) {
306 fn(flag)
307 }
308 }
309
310
311
312 func Visit(fn func(*Flag)) {
313 commandLine.Visit(fn)
314 }
315
316
317 func (f *FlagSet) Lookup(name string) *Flag {
318 return f.formal[name]
319 }
320
321
322
323 func Lookup(name string) *Flag {
324 return commandLine.formal[name]
325 }
326
327
328 func (f *FlagSet) Set(name, value string) error {
329 flag, ok := f.formal[name]
330 if !ok {
331 return fmt.Errorf("no such flag -%v", name)
332 }
333 err := flag.Value.Set(value)
334 if err != nil {
335 return err
336 }
337 if f.actual == nil {
338 f.actual = make(map[string]*Flag)
339 }
340 f.actual[name] = flag
341 return nil
342 }
343
344
345 func Set(name, value string) error {
346 return commandLine.Set(name, value)
347 }
348
349
350
351 func (f *FlagSet) PrintDefaults() {
352 f.VisitAll(func(flag *Flag) {
353 format := " -%s=%s: %s\n"
354 if _, ok := flag.Value.(*stringValue); ok {
355
356 format = " -%s=%q: %s\n"
357 }
358 fmt.Fprintf(f.out(), format, flag.Name, flag.DefValue, flag.Usage)
359 })
360 }
361
362
363 func PrintDefaults() {
364 commandLine.PrintDefaults()
365 }
366
367
368 func defaultUsage(f *FlagSet) {
369 fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
370 f.PrintDefaults()
371 }
372
373
374
375
376
377
378
379 var Usage = func() {
380 fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
381 PrintDefaults()
382 }
383
384
385 func (f *FlagSet) NFlag() int { return len(f.actual) }
386
387
388 func NFlag() int { return len(commandLine.actual) }
389
390
391
392 func (f *FlagSet) Arg(i int) string {
393 if i < 0 || i >= len(f.args) {
394 return ""
395 }
396 return f.args[i]
397 }
398
399
400
401 func Arg(i int) string {
402 return commandLine.Arg(i)
403 }
404
405
406 func (f *FlagSet) NArg() int { return len(f.args) }
407
408
409 func NArg() int { return len(commandLine.args) }
410
411
412 func (f *FlagSet) Args() []string { return f.args }
413
414
415 func Args() []string { return commandLine.args }
416
417
418
419 func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
420 f.Var(newBoolValue(value, p), name, usage)
421 }
422
423
424
425 func BoolVar(p *bool, name string, value bool, usage string) {
426 commandLine.Var(newBoolValue(value, p), name, usage)
427 }
428
429
430
431 func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
432 p := new(bool)
433 f.BoolVar(p, name, value, usage)
434 return p
435 }
436
437
438
439 func Bool(name string, value bool, usage string) *bool {
440 return commandLine.Bool(name, value, usage)
441 }
442
443
444
445 func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
446 f.Var(newIntValue(value, p), name, usage)
447 }
448
449
450
451 func IntVar(p *int, name string, value int, usage string) {
452 commandLine.Var(newIntValue(value, p), name, usage)
453 }
454
455
456
457 func (f *FlagSet) Int(name string, value int, usage string) *int {
458 p := new(int)
459 f.IntVar(p, name, value, usage)
460 return p
461 }
462
463
464
465 func Int(name string, value int, usage string) *int {
466 return commandLine.Int(name, value, usage)
467 }
468
469
470
471 func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {
472 f.Var(newInt64Value(value, p), name, usage)
473 }
474
475
476
477 func Int64Var(p *int64, name string, value int64, usage string) {
478 commandLine.Var(newInt64Value(value, p), name, usage)
479 }
480
481
482
483 func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
484 p := new(int64)
485 f.Int64Var(p, name, value, usage)
486 return p
487 }
488
489
490
491 func Int64(name string, value int64, usage string) *int64 {
492 return commandLine.Int64(name, value, usage)
493 }
494
495
496
497 func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
498 f.Var(newUintValue(value, p), name, usage)
499 }
500
501
502
503 func UintVar(p *uint, name string, value uint, usage string) {
504 commandLine.Var(newUintValue(value, p), name, usage)
505 }
506
507
508
509 func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
510 p := new(uint)
511 f.UintVar(p, name, value, usage)
512 return p
513 }
514
515
516
517 func Uint(name string, value uint, usage string) *uint {
518 return commandLine.Uint(name, value, usage)
519 }
520
521
522
523 func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
524 f.Var(newUint64Value(value, p), name, usage)
525 }
526
527
528
529 func Uint64Var(p *uint64, name string, value uint64, usage string) {
530 commandLine.Var(newUint64Value(value, p), name, usage)
531 }
532
533
534
535 func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
536 p := new(uint64)
537 f.Uint64Var(p, name, value, usage)
538 return p
539 }
540
541
542
543 func Uint64(name string, value uint64, usage string) *uint64 {
544 return commandLine.Uint64(name, value, usage)
545 }
546
547
548
549 func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
550 f.Var(newStringValue(value, p), name, usage)
551 }
552
553
554
555 func StringVar(p *string, name string, value string, usage string) {
556 commandLine.Var(newStringValue(value, p), name, usage)
557 }
558
559
560
561 func (f *FlagSet) String(name string, value string, usage string) *string {
562 p := new(string)
563 f.StringVar(p, name, value, usage)
564 return p
565 }
566
567
568
569 func String(name string, value string, usage string) *string {
570 return commandLine.String(name, value, usage)
571 }
572
573
574
575 func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) {
576 f.Var(newFloat64Value(value, p), name, usage)
577 }
578
579
580
581 func Float64Var(p *float64, name string, value float64, usage string) {
582 commandLine.Var(newFloat64Value(value, p), name, usage)
583 }
584
585
586
587 func (f *FlagSet) Float64(name string, value float64, usage string) *float64 {
588 p := new(float64)
589 f.Float64Var(p, name, value, usage)
590 return p
591 }
592
593
594
595 func Float64(name string, value float64, usage string) *float64 {
596 return commandLine.Float64(name, value, usage)
597 }
598
599
600
601 func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
602 f.Var(newDurationValue(value, p), name, usage)
603 }
604
605
606
607 func DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
608 commandLine.Var(newDurationValue(value, p), name, usage)
609 }
610
611
612
613 func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration {
614 p := new(time.Duration)
615 f.DurationVar(p, name, value, usage)
616 return p
617 }
618
619
620
621 func Duration(name string, value time.Duration, usage string) *time.Duration {
622 return commandLine.Duration(name, value, usage)
623 }
624
625
626
627
628
629
630
631 func (f *FlagSet) Var(value Value, name string, usage string) {
632
633 flag := &Flag{name, usage, value, value.String()}
634 _, alreadythere := f.formal[name]
635 if alreadythere {
636 msg := fmt.Sprintf("%s flag redefined: %s", f.name, name)
637 fmt.Fprintln(f.out(), msg)
638 panic(msg)
639 }
640 if f.formal == nil {
641 f.formal = make(map[string]*Flag)
642 }
643 f.formal[name] = flag
644 }
645
646
647
648
649
650
651
652 func Var(value Value, name string, usage string) {
653 commandLine.Var(value, name, usage)
654 }
655
656
657
658 func (f *FlagSet) failf(format string, a ...interface{}) error {
659 err := fmt.Errorf(format, a...)
660 fmt.Fprintln(f.out(), err)
661 f.usage()
662 return err
663 }
664
665
666
667 func (f *FlagSet) usage() {
668 if f == commandLine {
669 Usage()
670 } else if f.Usage == nil {
671 defaultUsage(f)
672 } else {
673 f.Usage()
674 }
675 }
676
677
678 func (f *FlagSet) parseOne() (bool, error) {
679 if len(f.args) == 0 {
680 return false, nil
681 }
682 s := f.args[0]
683 if len(s) == 0 || s[0] != '-' || len(s) == 1 {
684 return false, nil
685 }
686 num_minuses := 1
687 if s[1] == '-' {
688 num_minuses++
689 if len(s) == 2 {
690 f.args = f.args[1:]
691 return false, nil
692 }
693 }
694 name := s[num_minuses:]
695 if len(name) == 0 || name[0] == '-' || name[0] == '=' {
696 return false, f.failf("bad flag syntax: %s", s)
697 }
698
699
700 f.args = f.args[1:]
701 has_value := false
702 value := ""
703 for i := 1; i < len(name); i++ {
704 if name[i] == '=' {
705 value = name[i+1:]
706 has_value = true
707 name = name[0:i]
708 break
709 }
710 }
711 m := f.formal
712 flag, alreadythere := m[name]
713 if !alreadythere {
714 if name == "help" || name == "h" {
715 f.usage()
716 return false, ErrHelp
717 }
718 return false, f.failf("flag provided but not defined: -%s", name)
719 }
720 if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() {
721 if has_value {
722 if err := fv.Set(value); err != nil {
723 return false, f.failf("invalid boolean value %q for -%s: %v", value, name, err)
724 }
725 } else {
726 fv.Set("true")
727 }
728 } else {
729
730 if !has_value && len(f.args) > 0 {
731
732 has_value = true
733 value, f.args = f.args[0], f.args[1:]
734 }
735 if !has_value {
736 return false, f.failf("flag needs an argument: -%s", name)
737 }
738 if err := flag.Value.Set(value); err != nil {
739 return false, f.failf("invalid value %q for flag -%s: %v", value, name, err)
740 }
741 }
742 if f.actual == nil {
743 f.actual = make(map[string]*Flag)
744 }
745 f.actual[name] = flag
746 return true, nil
747 }
748
749
750
751
752
753 func (f *FlagSet) Parse(arguments []string) error {
754 f.parsed = true
755 f.args = arguments
756 for {
757 seen, err := f.parseOne()
758 if seen {
759 continue
760 }
761 if err == nil {
762 break
763 }
764 switch f.errorHandling {
765 case ContinueOnError:
766 return err
767 case ExitOnError:
768 os.Exit(2)
769 case PanicOnError:
770 panic(err)
771 }
772 }
773 return nil
774 }
775
776
777 func (f *FlagSet) Parsed() bool {
778 return f.parsed
779 }
780
781
782
783 func Parse() {
784
785 commandLine.Parse(os.Args[1:])
786 }
787
788
789 func Parsed() bool {
790 return commandLine.Parsed()
791 }
792
793
794 var commandLine = NewFlagSet(os.Args[0], ExitOnError)
795
796
797
798 func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
799 f := &FlagSet{
800 name: name,
801 errorHandling: errorHandling,
802 }
803 return f
804 }
805
806
807
808
809 func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
810 f.name = name
811 f.errorHandling = errorHandling
812 }
View as plain text