Source file
src/flag/flag.go
1
2
3
4
5
83 package flag
84
85 import (
86 "encoding"
87 "errors"
88 "fmt"
89 "io"
90 "iter"
91 "os"
92 "reflect"
93 "runtime"
94 "slices"
95 "strconv"
96 "strings"
97 "time"
98 )
99
100
101
102 var ErrHelp = errors.New("flag: help requested")
103
104
105
106 var errParse = errors.New("parse error")
107
108
109
110 var errRange = errors.New("value out of range")
111
112 func numError(err error) error {
113 ne, ok := err.(*strconv.NumError)
114 if !ok {
115 return err
116 }
117 if ne.Err == strconv.ErrSyntax {
118 return errParse
119 }
120 if ne.Err == strconv.ErrRange {
121 return errRange
122 }
123 return err
124 }
125
126
127 type boolValue bool
128
129 func newBoolValue(val bool, p *bool) *boolValue {
130 *p = val
131 return (*boolValue)(p)
132 }
133
134 func (b *boolValue) Set(s string) error {
135 v, err := strconv.ParseBool(s)
136 if err != nil {
137 err = errParse
138 }
139 *b = boolValue(v)
140 return err
141 }
142
143 func (b *boolValue) Get() any { return bool(*b) }
144
145 func (b *boolValue) String() string { return strconv.FormatBool(bool(*b)) }
146
147 func (b *boolValue) IsBoolFlag() bool { return true }
148
149
150
151 type boolFlag interface {
152 Value
153 IsBoolFlag() bool
154 }
155
156
157 type intValue int
158
159 func newIntValue(val int, p *int) *intValue {
160 *p = val
161 return (*intValue)(p)
162 }
163
164 func (i *intValue) Set(s string) error {
165 v, err := strconv.ParseInt(s, 0, strconv.IntSize)
166 if err != nil {
167 err = numError(err)
168 }
169 *i = intValue(v)
170 return err
171 }
172
173 func (i *intValue) Get() any { return int(*i) }
174
175 func (i *intValue) String() string { return strconv.Itoa(int(*i)) }
176
177
178 type int64Value int64
179
180 func newInt64Value(val int64, p *int64) *int64Value {
181 *p = val
182 return (*int64Value)(p)
183 }
184
185 func (i *int64Value) Set(s string) error {
186 v, err := strconv.ParseInt(s, 0, 64)
187 if err != nil {
188 err = numError(err)
189 }
190 *i = int64Value(v)
191 return err
192 }
193
194 func (i *int64Value) Get() any { return int64(*i) }
195
196 func (i *int64Value) String() string { return strconv.FormatInt(int64(*i), 10) }
197
198
199 type uintValue uint
200
201 func newUintValue(val uint, p *uint) *uintValue {
202 *p = val
203 return (*uintValue)(p)
204 }
205
206 func (i *uintValue) Set(s string) error {
207 v, err := strconv.ParseUint(s, 0, strconv.IntSize)
208 if err != nil {
209 err = numError(err)
210 }
211 *i = uintValue(v)
212 return err
213 }
214
215 func (i *uintValue) Get() any { return uint(*i) }
216
217 func (i *uintValue) String() string { return strconv.FormatUint(uint64(*i), 10) }
218
219
220 type uint64Value uint64
221
222 func newUint64Value(val uint64, p *uint64) *uint64Value {
223 *p = val
224 return (*uint64Value)(p)
225 }
226
227 func (i *uint64Value) Set(s string) error {
228 v, err := strconv.ParseUint(s, 0, 64)
229 if err != nil {
230 err = numError(err)
231 }
232 *i = uint64Value(v)
233 return err
234 }
235
236 func (i *uint64Value) Get() any { return uint64(*i) }
237
238 func (i *uint64Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
239
240
241 type stringValue string
242
243 func newStringValue(val string, p *string) *stringValue {
244 *p = val
245 return (*stringValue)(p)
246 }
247
248 func (s *stringValue) Set(val string) error {
249 *s = stringValue(val)
250 return nil
251 }
252
253 func (s *stringValue) Get() any { return string(*s) }
254
255 func (s *stringValue) String() string { return string(*s) }
256
257
258 type float64Value float64
259
260 func newFloat64Value(val float64, p *float64) *float64Value {
261 *p = val
262 return (*float64Value)(p)
263 }
264
265 func (f *float64Value) Set(s string) error {
266 v, err := strconv.ParseFloat(s, 64)
267 if err != nil {
268 err = numError(err)
269 }
270 *f = float64Value(v)
271 return err
272 }
273
274 func (f *float64Value) Get() any { return float64(*f) }
275
276 func (f *float64Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 64) }
277
278
279 type durationValue time.Duration
280
281 func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
282 *p = val
283 return (*durationValue)(p)
284 }
285
286 func (d *durationValue) Set(s string) error {
287 v, err := time.ParseDuration(s)
288 if err != nil {
289 err = errParse
290 }
291 *d = durationValue(v)
292 return err
293 }
294
295 func (d *durationValue) Get() any { return time.Duration(*d) }
296
297 func (d *durationValue) String() string { return (*time.Duration)(d).String() }
298
299
300 type textValue struct{ p encoding.TextUnmarshaler }
301
302 func newTextValue(val encoding.TextMarshaler, p encoding.TextUnmarshaler) textValue {
303 ptrVal := reflect.ValueOf(p)
304 if ptrVal.Kind() != reflect.Ptr {
305 panic("variable value type must be a pointer")
306 }
307 defVal := reflect.ValueOf(val)
308 if defVal.Kind() == reflect.Ptr {
309 defVal = defVal.Elem()
310 }
311 if defVal.Type() != ptrVal.Type().Elem() {
312 panic(fmt.Sprintf("default type does not match variable type: %v != %v", defVal.Type(), ptrVal.Type().Elem()))
313 }
314 ptrVal.Elem().Set(defVal)
315 return textValue{p}
316 }
317
318 func (v textValue) Set(s string) error {
319 return v.p.UnmarshalText([]byte(s))
320 }
321
322 func (v textValue) Get() any {
323 return v.p
324 }
325
326 func (v textValue) String() string {
327 if m, ok := v.p.(encoding.TextMarshaler); ok {
328 if b, err := m.MarshalText(); err == nil {
329 return string(b)
330 }
331 }
332 return ""
333 }
334
335
336 type funcValue func(string) error
337
338 func (f funcValue) Set(s string) error { return f(s) }
339
340 func (f funcValue) String() string { return "" }
341
342
343 type boolFuncValue func(string) error
344
345 func (f boolFuncValue) Set(s string) error { return f(s) }
346
347 func (f boolFuncValue) String() string { return "" }
348
349 func (f boolFuncValue) IsBoolFlag() bool { return true }
350
351
352
353
354
355
356
357
358
359
360
361 type Value interface {
362 String() string
363 Set(string) error
364 }
365
366
367
368
369
370 type Getter interface {
371 Value
372 Get() any
373 }
374
375
376 type ErrorHandling int
377
378
379 const (
380 ContinueOnError ErrorHandling = iota
381 ExitOnError
382 PanicOnError
383 )
384
385
386
387
388
389
390 type FlagSet struct {
391
392
393
394
395
396 Usage func()
397
398 name string
399 parsed bool
400 actual map[string]*Flag
401 formal map[string]*Flag
402 args []string
403 errorHandling ErrorHandling
404 output io.Writer
405 undef map[string]string
406 }
407
408
409 type Flag struct {
410 Name string
411 Usage string
412 Value Value
413 DefValue string
414 IsSet bool
415 }
416
417
418 func sortFlags(flags map[string]*Flag) []*Flag {
419 result := make([]*Flag, len(flags))
420 i := 0
421 for _, f := range flags {
422 result[i] = f
423 i++
424 }
425 slices.SortFunc(result, func(a, b *Flag) int {
426 return strings.Compare(a.Name, b.Name)
427 })
428 return result
429 }
430
431
432
433 func (f *FlagSet) Output() io.Writer {
434 if f.output == nil {
435 return os.Stderr
436 }
437 return f.output
438 }
439
440
441 func (f *FlagSet) Name() string {
442 return f.name
443 }
444
445
446 func (f *FlagSet) ErrorHandling() ErrorHandling {
447 return f.errorHandling
448 }
449
450
451
452 func (f *FlagSet) SetOutput(output io.Writer) {
453 f.output = output
454 }
455
456
457
458 func (f *FlagSet) VisitAll(fn func(*Flag)) {
459 for _, flag := range sortFlags(f.formal) {
460 fn(flag)
461 }
462 }
463
464
465
466 func (f *FlagSet) All() iter.Seq[*Flag] {
467 return func(yield func(*Flag) bool) {
468 for _, flag := range sortFlags(f.formal) {
469 if !yield(flag) {
470 break
471 }
472 }
473 }
474 }
475
476
477
478 func All() iter.Seq[*Flag] {
479 return CommandLine.All()
480 }
481
482
483
484 func VisitAll(fn func(*Flag)) {
485 CommandLine.VisitAll(fn)
486 }
487
488
489
490 func (f *FlagSet) Visit(fn func(*Flag)) {
491 for _, flag := range sortFlags(f.actual) {
492 fn(flag)
493 }
494 }
495
496
497
498 func Visit(fn func(*Flag)) {
499 CommandLine.Visit(fn)
500 }
501
502
503 func (f *FlagSet) Lookup(name string) *Flag {
504 return f.formal[name]
505 }
506
507
508
509 func Lookup(name string) *Flag {
510 return CommandLine.formal[name]
511 }
512
513
514 func (f *FlagSet) Set(name, value string) error {
515 return f.set(name, value)
516 }
517 func (f *FlagSet) set(name, value string) error {
518 flag, ok := f.formal[name]
519 if !ok {
520
521
522
523
524
525
526
527
528 _, file, line, ok := runtime.Caller(2)
529 if !ok {
530 file = "?"
531 line = 0
532 }
533 if f.undef == nil {
534 f.undef = map[string]string{}
535 }
536 f.undef[name] = fmt.Sprintf("%s:%d", file, line)
537
538 return fmt.Errorf("no such flag -%v", name)
539 }
540 err := flag.Value.Set(value)
541 if err != nil {
542 return err
543 }
544 flag.IsSet = true
545 if f.actual == nil {
546 f.actual = make(map[string]*Flag)
547 }
548 f.actual[name] = flag
549 return nil
550 }
551
552
553 func Set(name, value string) error {
554 return CommandLine.set(name, value)
555 }
556
557
558
559 func isZeroValue(flag *Flag, value string) (ok bool, err error) {
560
561
562
563 typ := reflect.TypeOf(flag.Value)
564 var z reflect.Value
565 if typ.Kind() == reflect.Pointer {
566 z = reflect.New(typ.Elem())
567 } else {
568 z = reflect.Zero(typ)
569 }
570
571
572
573 defer func() {
574 if e := recover(); e != nil {
575 if typ.Kind() == reflect.Pointer {
576 typ = typ.Elem()
577 }
578 err = fmt.Errorf("panic calling String method on zero %v for flag %s: %v", typ, flag.Name, e)
579 }
580 }()
581 return value == z.Interface().(Value).String(), nil
582 }
583
584
585
586
587
588
589 func UnquoteUsage(flag *Flag) (name string, usage string) {
590
591 usage = flag.Usage
592 for i := 0; i < len(usage); i++ {
593 if usage[i] == '`' {
594 for j := i + 1; j < len(usage); j++ {
595 if usage[j] == '`' {
596 name = usage[i+1 : j]
597 usage = usage[:i] + name + usage[j+1:]
598 return name, usage
599 }
600 }
601 break
602 }
603 }
604
605 name = "value"
606 switch fv := flag.Value.(type) {
607 case boolFlag:
608 if fv.IsBoolFlag() {
609 name = ""
610 }
611 case *durationValue:
612 name = "duration"
613 case *float64Value:
614 name = "float"
615 case *intValue, *int64Value:
616 name = "int"
617 case *stringValue:
618 name = "string"
619 case *uintValue, *uint64Value:
620 name = "uint"
621 }
622 return
623 }
624
625
626
627
628 func (f *FlagSet) PrintDefaults() {
629 var isZeroValueErrs []error
630 f.VisitAll(func(flag *Flag) {
631 var b strings.Builder
632 fmt.Fprintf(&b, " -%s", flag.Name)
633 name, usage := UnquoteUsage(flag)
634 if len(name) > 0 {
635 b.WriteString(" ")
636 b.WriteString(name)
637 }
638
639
640 if b.Len() <= 4 {
641 b.WriteString("\t")
642 } else {
643
644
645 b.WriteString("\n \t")
646 }
647 b.WriteString(strings.ReplaceAll(usage, "\n", "\n \t"))
648
649
650
651 if isZero, err := isZeroValue(flag, flag.DefValue); err != nil {
652 isZeroValueErrs = append(isZeroValueErrs, err)
653 } else if !isZero {
654 if _, ok := flag.Value.(*stringValue); ok {
655
656 fmt.Fprintf(&b, " (default %q)", flag.DefValue)
657 } else {
658 fmt.Fprintf(&b, " (default %v)", flag.DefValue)
659 }
660 }
661 fmt.Fprint(f.Output(), b.String(), "\n")
662 })
663
664
665
666 if errs := isZeroValueErrs; len(errs) > 0 {
667 fmt.Fprintln(f.Output())
668 for _, err := range errs {
669 fmt.Fprintln(f.Output(), err)
670 }
671 }
672 }
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700 func PrintDefaults() {
701 CommandLine.PrintDefaults()
702 }
703
704
705 func (f *FlagSet) defaultUsage() {
706 if f.name == "" {
707 fmt.Fprintf(f.Output(), "Usage:\n")
708 } else {
709 fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name)
710 }
711 f.PrintDefaults()
712 }
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727 var Usage = func() {
728 fmt.Fprintf(CommandLine.Output(), "Usage of %s:\n", os.Args[0])
729 PrintDefaults()
730 }
731
732
733 func (f *FlagSet) NFlag() int { return len(f.actual) }
734
735
736 func NFlag() int { return len(CommandLine.actual) }
737
738
739
740
741 func (f *FlagSet) Arg(i int) string {
742 if i < 0 || i >= len(f.args) {
743 return ""
744 }
745 return f.args[i]
746 }
747
748
749
750
751 func Arg(i int) string {
752 return CommandLine.Arg(i)
753 }
754
755
756 func (f *FlagSet) NArg() int { return len(f.args) }
757
758
759 func NArg() int { return len(CommandLine.args) }
760
761
762 func (f *FlagSet) Args() []string { return f.args }
763
764
765 func Args() []string { return CommandLine.args }
766
767
768
769 func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
770 f.Var(newBoolValue(value, p), name, usage)
771 }
772
773
774
775 func BoolVar(p *bool, name string, value bool, usage string) {
776 CommandLine.Var(newBoolValue(value, p), name, usage)
777 }
778
779
780
781 func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
782 p := new(bool)
783 f.BoolVar(p, name, value, usage)
784 return p
785 }
786
787
788
789 func Bool(name string, value bool, usage string) *bool {
790 return CommandLine.Bool(name, value, usage)
791 }
792
793
794
795 func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
796 f.Var(newIntValue(value, p), name, usage)
797 }
798
799
800
801 func IntVar(p *int, name string, value int, usage string) {
802 CommandLine.Var(newIntValue(value, p), name, usage)
803 }
804
805
806
807 func (f *FlagSet) Int(name string, value int, usage string) *int {
808 p := new(int)
809 f.IntVar(p, name, value, usage)
810 return p
811 }
812
813
814
815 func Int(name string, value int, usage string) *int {
816 return CommandLine.Int(name, value, usage)
817 }
818
819
820
821 func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {
822 f.Var(newInt64Value(value, p), name, usage)
823 }
824
825
826
827 func Int64Var(p *int64, name string, value int64, usage string) {
828 CommandLine.Var(newInt64Value(value, p), name, usage)
829 }
830
831
832
833 func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
834 p := new(int64)
835 f.Int64Var(p, name, value, usage)
836 return p
837 }
838
839
840
841 func Int64(name string, value int64, usage string) *int64 {
842 return CommandLine.Int64(name, value, usage)
843 }
844
845
846
847 func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
848 f.Var(newUintValue(value, p), name, usage)
849 }
850
851
852
853 func UintVar(p *uint, name string, value uint, usage string) {
854 CommandLine.Var(newUintValue(value, p), name, usage)
855 }
856
857
858
859 func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
860 p := new(uint)
861 f.UintVar(p, name, value, usage)
862 return p
863 }
864
865
866
867 func Uint(name string, value uint, usage string) *uint {
868 return CommandLine.Uint(name, value, usage)
869 }
870
871
872
873 func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
874 f.Var(newUint64Value(value, p), name, usage)
875 }
876
877
878
879 func Uint64Var(p *uint64, name string, value uint64, usage string) {
880 CommandLine.Var(newUint64Value(value, p), name, usage)
881 }
882
883
884
885 func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
886 p := new(uint64)
887 f.Uint64Var(p, name, value, usage)
888 return p
889 }
890
891
892
893 func Uint64(name string, value uint64, usage string) *uint64 {
894 return CommandLine.Uint64(name, value, usage)
895 }
896
897
898
899 func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
900 f.Var(newStringValue(value, p), name, usage)
901 }
902
903
904
905 func StringVar(p *string, name string, value string, usage string) {
906 CommandLine.Var(newStringValue(value, p), name, usage)
907 }
908
909
910
911 func (f *FlagSet) String(name string, value string, usage string) *string {
912 p := new(string)
913 f.StringVar(p, name, value, usage)
914 return p
915 }
916
917
918
919 func String(name string, value string, usage string) *string {
920 return CommandLine.String(name, value, usage)
921 }
922
923
924
925 func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) {
926 f.Var(newFloat64Value(value, p), name, usage)
927 }
928
929
930
931 func Float64Var(p *float64, name string, value float64, usage string) {
932 CommandLine.Var(newFloat64Value(value, p), name, usage)
933 }
934
935
936
937 func (f *FlagSet) Float64(name string, value float64, usage string) *float64 {
938 p := new(float64)
939 f.Float64Var(p, name, value, usage)
940 return p
941 }
942
943
944
945 func Float64(name string, value float64, usage string) *float64 {
946 return CommandLine.Float64(name, value, usage)
947 }
948
949
950
951
952 func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
953 f.Var(newDurationValue(value, p), name, usage)
954 }
955
956
957
958
959 func DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
960 CommandLine.Var(newDurationValue(value, p), name, usage)
961 }
962
963
964
965
966 func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration {
967 p := new(time.Duration)
968 f.DurationVar(p, name, value, usage)
969 return p
970 }
971
972
973
974
975 func Duration(name string, value time.Duration, usage string) *time.Duration {
976 return CommandLine.Duration(name, value, usage)
977 }
978
979
980
981
982
983
984 func (f *FlagSet) TextVar(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string) {
985 f.Var(newTextValue(value, p), name, usage)
986 }
987
988
989
990
991
992
993 func TextVar(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string) {
994 CommandLine.Var(newTextValue(value, p), name, usage)
995 }
996
997
998
999
1000 func (f *FlagSet) Func(name, usage string, fn func(string) error) {
1001 f.Var(funcValue(fn), name, usage)
1002 }
1003
1004
1005
1006
1007 func Func(name, usage string, fn func(string) error) {
1008 CommandLine.Func(name, usage, fn)
1009 }
1010
1011
1012
1013
1014 func (f *FlagSet) BoolFunc(name, usage string, fn func(string) error) {
1015 f.Var(boolFuncValue(fn), name, usage)
1016 }
1017
1018
1019
1020
1021 func BoolFunc(name, usage string, fn func(string) error) {
1022 CommandLine.BoolFunc(name, usage, fn)
1023 }
1024
1025
1026
1027
1028
1029
1030
1031 func (f *FlagSet) Var(value Value, name string, usage string) {
1032
1033 if strings.HasPrefix(name, "-") {
1034 panic(f.sprintf("flag %q begins with -", name))
1035 } else if strings.Contains(name, "=") {
1036 panic(f.sprintf("flag %q contains =", name))
1037 }
1038
1039
1040 flag := &Flag{name, usage, value, value.String(), false}
1041 _, alreadythere := f.formal[name]
1042 if alreadythere {
1043 var msg string
1044 if f.name == "" {
1045 msg = f.sprintf("flag redefined: %s", name)
1046 } else {
1047 msg = f.sprintf("%s flag redefined: %s", f.name, name)
1048 }
1049 panic(msg)
1050 }
1051 if pos := f.undef[name]; pos != "" {
1052 panic(fmt.Sprintf("flag %s set at %s before being defined", name, pos))
1053 }
1054 if f.formal == nil {
1055 f.formal = make(map[string]*Flag)
1056 }
1057 f.formal[name] = flag
1058 }
1059
1060
1061
1062
1063
1064
1065
1066 func Var(value Value, name string, usage string) {
1067 CommandLine.Var(value, name, usage)
1068 }
1069
1070
1071 func (f *FlagSet) sprintf(format string, a ...any) string {
1072 msg := fmt.Sprintf(format, a...)
1073 fmt.Fprintln(f.Output(), msg)
1074 return msg
1075 }
1076
1077
1078
1079 func (f *FlagSet) failf(format string, a ...any) error {
1080 msg := f.sprintf(format, a...)
1081 f.usage()
1082 return errors.New(msg)
1083 }
1084
1085
1086
1087 func (f *FlagSet) usage() {
1088 if f.Usage == nil {
1089 f.defaultUsage()
1090 } else {
1091 f.Usage()
1092 }
1093 }
1094
1095
1096 func (f *FlagSet) parseOne() (bool, error) {
1097 if len(f.args) == 0 {
1098 return false, nil
1099 }
1100 s := f.args[0]
1101 if len(s) < 2 || s[0] != '-' {
1102 return false, nil
1103 }
1104 numMinuses := 1
1105 if s[1] == '-' {
1106 numMinuses++
1107 if len(s) == 2 {
1108 f.args = f.args[1:]
1109 return false, nil
1110 }
1111 }
1112 name := s[numMinuses:]
1113 if len(name) == 0 || name[0] == '-' || name[0] == '=' {
1114 return false, f.failf("bad flag syntax: %s", s)
1115 }
1116
1117
1118 f.args = f.args[1:]
1119 hasValue := false
1120 value := ""
1121 for i := 1; i < len(name); i++ {
1122 if name[i] == '=' {
1123 value = name[i+1:]
1124 hasValue = true
1125 name = name[0:i]
1126 break
1127 }
1128 }
1129
1130 flag, ok := f.formal[name]
1131 if !ok {
1132 if name == "help" || name == "h" {
1133 f.usage()
1134 return false, ErrHelp
1135 }
1136 return false, f.failf("flag provided but not defined: -%s", name)
1137 }
1138
1139 if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() {
1140 if hasValue {
1141 if err := fv.Set(value); err != nil {
1142 return false, f.failf("invalid boolean value %q for -%s: %v", value, name, err)
1143 }
1144 } else {
1145 if err := fv.Set("true"); err != nil {
1146 return false, f.failf("invalid boolean flag %s: %v", name, err)
1147 }
1148 }
1149 } else {
1150
1151 if !hasValue && len(f.args) > 0 {
1152
1153 hasValue = true
1154 value, f.args = f.args[0], f.args[1:]
1155 }
1156 if !hasValue {
1157 return false, f.failf("flag needs an argument: -%s", name)
1158 }
1159 if err := flag.Value.Set(value); err != nil {
1160 return false, f.failf("invalid value %q for flag -%s: %v", value, name, err)
1161 }
1162 }
1163 flag.IsSet = true
1164 if f.actual == nil {
1165 f.actual = make(map[string]*Flag)
1166 }
1167 f.actual[name] = flag
1168 return true, nil
1169 }
1170
1171
1172
1173
1174
1175 func (f *FlagSet) Parse(arguments []string) error {
1176 f.parsed = true
1177 f.args = arguments
1178 for {
1179 seen, err := f.parseOne()
1180 if seen {
1181 continue
1182 }
1183 if err == nil {
1184 break
1185 }
1186 switch f.errorHandling {
1187 case ContinueOnError:
1188 return err
1189 case ExitOnError:
1190 if err == ErrHelp {
1191 os.Exit(0)
1192 }
1193 os.Exit(2)
1194 case PanicOnError:
1195 panic(err)
1196 }
1197 }
1198 return nil
1199 }
1200
1201
1202 func (f *FlagSet) Parsed() bool {
1203 return f.parsed
1204 }
1205
1206
1207
1208 func Parse() {
1209
1210 CommandLine.Parse(os.Args[1:])
1211 }
1212
1213
1214 func Parsed() bool {
1215 return CommandLine.Parsed()
1216 }
1217
1218
1219
1220
1221 var CommandLine *FlagSet
1222
1223 func init() {
1224
1225 if len(os.Args) == 0 {
1226 CommandLine = NewFlagSet("", ExitOnError)
1227 } else {
1228 CommandLine = NewFlagSet(os.Args[0], ExitOnError)
1229 }
1230
1231
1232
1233
1234
1235 CommandLine.Usage = commandLineUsage
1236 }
1237
1238 func commandLineUsage() {
1239 Usage()
1240 }
1241
1242
1243
1244
1245 func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
1246 f := &FlagSet{
1247 name: name,
1248 errorHandling: errorHandling,
1249 }
1250 f.Usage = f.defaultUsage
1251 return f
1252 }
1253
1254
1255
1256
1257 func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
1258 f.name = name
1259 f.errorHandling = errorHandling
1260 }
1261
View as plain text