LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 /* | 5 /* |
6 Package flag implements command-line flag parsing in the GNU style. | 6 Package flag implements command-line flag parsing in the GNU style. |
7 It is almost exactly the same as the standard flag package, | 7 It is almost exactly the same as the standard flag package, |
8 the only difference being the extra argument to Parse. | 8 the only difference being the extra argument to Parse. |
9 | 9 |
10 Command line flag syntax: | 10 Command line flag syntax: |
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
682 func (f *FlagSet) usage() { | 682 func (f *FlagSet) usage() { |
683 if f == commandLine { | 683 if f == commandLine { |
684 Usage() | 684 Usage() |
685 } else if f.Usage == nil { | 685 } else if f.Usage == nil { |
686 defaultUsage(f) | 686 defaultUsage(f) |
687 } else { | 687 } else { |
688 f.Usage() | 688 f.Usage() |
689 } | 689 } |
690 } | 690 } |
691 | 691 |
692 func (f *FlagSet) parseOneGnu() (flagName string, finished bool, err error) { | 692 func (f *FlagSet) parseOneGnu() (flagName string, long, finished bool, err error
) { |
693 if len(f.procArgs) == 0 { | 693 if len(f.procArgs) == 0 { |
694 » » return "", true, nil | 694 » » finished = true |
| 695 » » return |
695 } | 696 } |
696 | 697 |
697 // processing previously encountered single-rune flag | 698 // processing previously encountered single-rune flag |
698 if flag := f.procFlag; len(flag) > 0 { | 699 if flag := f.procFlag; len(flag) > 0 { |
699 _, n := utf8.DecodeRuneInString(flag) | 700 _, n := utf8.DecodeRuneInString(flag) |
700 f.procFlag = flag[n:] | 701 f.procFlag = flag[n:] |
701 » » return flag[0:n], false, nil | 702 » » flagName = flag[0:n] |
| 703 » » return |
702 } | 704 } |
703 | 705 |
704 a := f.procArgs[0] | 706 a := f.procArgs[0] |
705 | 707 |
706 // one non-flag argument | 708 // one non-flag argument |
707 if a == "-" || a == "" || a[0] != '-' { | 709 if a == "-" || a == "" || a[0] != '-' { |
708 if f.allowIntersperse { | 710 if f.allowIntersperse { |
709 f.args = append(f.args, a) | 711 f.args = append(f.args, a) |
710 f.procArgs = f.procArgs[1:] | 712 f.procArgs = f.procArgs[1:] |
711 » » » return "", false, nil | 713 » » » return |
712 } | 714 } |
713 f.args = append(f.args, f.procArgs...) | 715 f.args = append(f.args, f.procArgs...) |
714 f.procArgs = nil | 716 f.procArgs = nil |
715 » » return "", true, nil | 717 » » finished = true |
| 718 » » return |
716 } | 719 } |
717 | 720 |
718 // end of flags | 721 // end of flags |
719 if f.procArgs[0] == "--" { | 722 if f.procArgs[0] == "--" { |
720 f.args = append(f.args, f.procArgs[1:]...) | 723 f.args = append(f.args, f.procArgs[1:]...) |
721 f.procArgs = nil | 724 f.procArgs = nil |
722 » » return "", true, nil | 725 » » finished = true |
| 726 » » return |
723 } | 727 } |
724 | 728 |
725 // long flag signified with "--" prefix | 729 // long flag signified with "--" prefix |
726 if a[1] == '-' { | 730 if a[1] == '-' { |
| 731 long = true |
727 i := strings.Index(a, "=") | 732 i := strings.Index(a, "=") |
728 if i < 0 { | 733 if i < 0 { |
| 734 f.procArgs = f.procArgs[1:] |
729 flagName = a[2:] | 735 flagName = a[2:] |
730 f.procArgs = f.procArgs[1:] | |
731 return | 736 return |
732 } | 737 } |
733 flagName = a[2:i] | 738 flagName = a[2:i] |
734 if flagName == "" { | 739 if flagName == "" { |
735 » » » return "", true, fmt.Errorf("empty flag in argument %q",
a) | 740 » » » err = fmt.Errorf("empty flag in argument %q", a) |
| 741 » » » return |
736 } | 742 } |
737 f.procArgs = f.procArgs[1:] | 743 f.procArgs = f.procArgs[1:] |
738 f.procFlag = a[i:] | 744 f.procFlag = a[i:] |
739 return | 745 return |
740 } | 746 } |
741 | 747 |
742 // some number of single-rune flags | 748 // some number of single-rune flags |
743 a = a[1:] | 749 a = a[1:] |
744 _, n := utf8.DecodeRuneInString(a) | 750 _, n := utf8.DecodeRuneInString(a) |
745 flagName = a[0:n] | 751 flagName = a[0:n] |
746 f.procFlag = a[n:] | 752 f.procFlag = a[n:] |
747 f.procArgs = f.procArgs[1:] | 753 f.procArgs = f.procArgs[1:] |
748 return | 754 return |
749 } | 755 } |
750 | 756 |
751 func flagWithMinus(name string) string { | 757 func flagWithMinus(name string) string { |
752 if len(name) > 1 { | 758 if len(name) > 1 { |
753 return "--" + name | 759 return "--" + name |
754 } | 760 } |
755 return "-" + name | 761 return "-" + name |
756 } | 762 } |
757 | 763 |
758 func (f *FlagSet) parseGnuFlagArg(name string) (finished bool, err error) { | 764 func (f *FlagSet) parseGnuFlagArg(name string, long bool) (finished bool, err er
ror) { |
759 m := f.formal | 765 m := f.formal |
760 flag, alreadythere := m[name] // BUG | 766 flag, alreadythere := m[name] // BUG |
761 if !alreadythere { | 767 if !alreadythere { |
762 if name == "help" || name == "h" { // special case for nice help
message. | 768 if name == "help" || name == "h" { // special case for nice help
message. |
763 f.usage() | 769 f.usage() |
764 return false, ErrHelp | 770 return false, ErrHelp |
765 } | 771 } |
766 // TODO print --xxx when flag is more than one rune. | 772 // TODO print --xxx when flag is more than one rune. |
767 return false, f.failf("flag provided but not defined: %s", flagW
ithMinus(name)) | 773 return false, f.failf("flag provided but not defined: %s", flagW
ithMinus(name)) |
768 } | 774 } |
769 if fv, ok := flag.Value.(*boolValue); ok && !strings.HasPrefix(f.procFla
g, "=") { | 775 if fv, ok := flag.Value.(*boolValue); ok && !strings.HasPrefix(f.procFla
g, "=") { |
770 // special case: doesn't need an arg, and an arg hasn't | 776 // special case: doesn't need an arg, and an arg hasn't |
771 // been provided explicitly. | 777 // been provided explicitly. |
772 fv.Set("true") | 778 fv.Set("true") |
773 } else { | 779 } else { |
774 // It must have a value, which might be the next argument. | 780 // It must have a value, which might be the next argument. |
775 var hasValue bool | 781 var hasValue bool |
776 var value string | 782 var value string |
777 if f.procFlag != "" { | 783 if f.procFlag != "" { |
778 // value directly follows flag | 784 // value directly follows flag |
779 value = f.procFlag | 785 value = f.procFlag |
780 » » » if value[0] == '=' { | 786 » » » if long { |
| 787 » » » » if value[0] != '=' { |
| 788 » » » » » panic("no leading '=' in long flag") |
| 789 » » » » } |
781 value = value[1:] | 790 value = value[1:] |
782 } | 791 } |
783 hasValue = true | 792 hasValue = true |
784 f.procFlag = "" | 793 f.procFlag = "" |
785 } | 794 } |
786 if !hasValue && len(f.procArgs) > 0 { | 795 if !hasValue && len(f.procArgs) > 0 { |
787 // value is the next arg | 796 // value is the next arg |
788 hasValue = true | 797 hasValue = true |
789 value, f.procArgs = f.procArgs[0], f.procArgs[1:] | 798 value, f.procArgs = f.procArgs[0], f.procArgs[1:] |
790 } | 799 } |
(...skipping 17 matching lines...) Expand all Loading... |
808 // The return value will be ErrHelp if --help was set but not defined. | 817 // The return value will be ErrHelp if --help was set but not defined. |
809 // If allowIntersperse is set, arguments and flags can be interspersed, that | 818 // If allowIntersperse is set, arguments and flags can be interspersed, that |
810 // is flags can follow positional arguments. | 819 // is flags can follow positional arguments. |
811 func (f *FlagSet) Parse(allowIntersperse bool, arguments []string) error { | 820 func (f *FlagSet) Parse(allowIntersperse bool, arguments []string) error { |
812 f.parsed = true | 821 f.parsed = true |
813 f.procArgs = arguments | 822 f.procArgs = arguments |
814 f.procFlag = "" | 823 f.procFlag = "" |
815 f.args = nil | 824 f.args = nil |
816 f.allowIntersperse = allowIntersperse | 825 f.allowIntersperse = allowIntersperse |
817 for { | 826 for { |
818 » » name, finished, err := f.parseOneGnu() | 827 » » name, long, finished, err := f.parseOneGnu() |
819 if !finished { | 828 if !finished { |
820 if name != "" { | 829 if name != "" { |
821 » » » » finished, err = f.parseGnuFlagArg(name) | 830 » » » » finished, err = f.parseGnuFlagArg(name, long) |
822 } | 831 } |
823 } | 832 } |
824 if err != nil { | 833 if err != nil { |
825 switch f.errorHandling { | 834 switch f.errorHandling { |
826 case ContinueOnError: | 835 case ContinueOnError: |
827 return err | 836 return err |
828 case ExitOnError: | 837 case ExitOnError: |
829 os.Exit(2) | 838 os.Exit(2) |
830 case PanicOnError: | 839 case PanicOnError: |
831 panic(err) | 840 panic(err) |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
873 return f | 882 return f |
874 } | 883 } |
875 | 884 |
876 // Init sets the name and error handling property for a flag set. | 885 // Init sets the name and error handling property for a flag set. |
877 // By default, the zero FlagSet uses an empty name and the | 886 // By default, the zero FlagSet uses an empty name and the |
878 // ContinueOnError error handling policy. | 887 // ContinueOnError error handling policy. |
879 func (f *FlagSet) Init(name string, errorHandling ErrorHandling) { | 888 func (f *FlagSet) Init(name string, errorHandling ErrorHandling) { |
880 f.name = name | 889 f.name = name |
881 f.errorHandling = errorHandling | 890 f.errorHandling = errorHandling |
882 } | 891 } |
LEFT | RIGHT |