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