diff options
Diffstat (limited to 'libgo/go/flag')
-rw-r--r-- | libgo/go/flag/flag.go | 114 | ||||
-rw-r--r-- | libgo/go/flag/flag_test.go | 32 |
2 files changed, 98 insertions, 48 deletions
diff --git a/libgo/go/flag/flag.go b/libgo/go/flag/flag.go index 406ea77799d..964f5541b86 100644 --- a/libgo/go/flag/flag.go +++ b/libgo/go/flag/flag.go @@ -65,12 +65,13 @@ import ( "os" "sort" "strconv" + "time" ) // ErrHelp is the error returned if the flag -help is invoked but no such flag is defined. var ErrHelp = errors.New("flag: help requested") -// -- Bool Value +// -- bool Value type boolValue bool func newBoolValue(val bool, p *bool) *boolValue { @@ -78,15 +79,15 @@ func newBoolValue(val bool, p *bool) *boolValue { return (*boolValue)(p) } -func (b *boolValue) Set(s string) bool { +func (b *boolValue) Set(s string) error { v, err := strconv.ParseBool(s) *b = boolValue(v) - return err == nil + return err } func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) } -// -- Int Value +// -- int Value type intValue int func newIntValue(val int, p *int) *intValue { @@ -94,15 +95,15 @@ func newIntValue(val int, p *int) *intValue { return (*intValue)(p) } -func (i *intValue) Set(s string) bool { +func (i *intValue) Set(s string) error { v, err := strconv.ParseInt(s, 0, 64) *i = intValue(v) - return err == nil + return err } func (i *intValue) String() string { return fmt.Sprintf("%v", *i) } -// -- Int64 Value +// -- int64 Value type int64Value int64 func newInt64Value(val int64, p *int64) *int64Value { @@ -110,15 +111,15 @@ func newInt64Value(val int64, p *int64) *int64Value { return (*int64Value)(p) } -func (i *int64Value) Set(s string) bool { +func (i *int64Value) Set(s string) error { v, err := strconv.ParseInt(s, 0, 64) *i = int64Value(v) - return err == nil + return err } func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) } -// -- Uint Value +// -- uint Value type uintValue uint func newUintValue(val uint, p *uint) *uintValue { @@ -126,10 +127,10 @@ func newUintValue(val uint, p *uint) *uintValue { return (*uintValue)(p) } -func (i *uintValue) Set(s string) bool { +func (i *uintValue) Set(s string) error { v, err := strconv.ParseUint(s, 0, 64) *i = uintValue(v) - return err == nil + return err } func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) } @@ -142,10 +143,10 @@ func newUint64Value(val uint64, p *uint64) *uint64Value { return (*uint64Value)(p) } -func (i *uint64Value) Set(s string) bool { +func (i *uint64Value) Set(s string) error { v, err := strconv.ParseUint(s, 0, 64) *i = uint64Value(v) - return err == nil + return err } func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) } @@ -158,14 +159,14 @@ func newStringValue(val string, p *string) *stringValue { return (*stringValue)(p) } -func (s *stringValue) Set(val string) bool { +func (s *stringValue) Set(val string) error { *s = stringValue(val) - return true + return nil } func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) } -// -- Float64 Value +// -- float64 Value type float64Value float64 func newFloat64Value(val float64, p *float64) *float64Value { @@ -173,19 +174,35 @@ func newFloat64Value(val float64, p *float64) *float64Value { return (*float64Value)(p) } -func (f *float64Value) Set(s string) bool { +func (f *float64Value) Set(s string) error { v, err := strconv.ParseFloat(s, 64) *f = float64Value(v) - return err == nil + return err } func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) } +// -- time.Duration Value +type durationValue time.Duration + +func newDurationValue(val time.Duration, p *time.Duration) *durationValue { + *p = val + return (*durationValue)(p) +} + +func (d *durationValue) Set(s string) error { + v, err := time.ParseDuration(s) + *d = durationValue(v) + return err +} + +func (d *durationValue) String() string { return (*time.Duration)(d).String() } + // Value is the interface to the dynamic value stored in a flag. // (The default value is represented as a string.) type Value interface { String() string - Set(string) bool + Set(string) error } // ErrorHandling defines how to handle flag parsing errors. @@ -276,27 +293,25 @@ func Lookup(name string) *Flag { return commandLine.formal[name] } -// Set sets the value of the named flag. It returns true if the set succeeded; false if -// there is no such flag defined. -func (f *FlagSet) Set(name, value string) bool { +// Set sets the value of the named flag. +func (f *FlagSet) Set(name, value string) error { flag, ok := f.formal[name] if !ok { - return false + return fmt.Errorf("no such flag -%v", name) } - ok = flag.Value.Set(value) - if !ok { - return false + err := flag.Value.Set(value) + if err != nil { + return err } if f.actual == nil { f.actual = make(map[string]*Flag) } f.actual[name] = flag - return true + return nil } -// Set sets the value of the named command-line flag. It returns true if the -// set succeeded; false if there is no such flag defined. -func Set(name, value string) bool { +// Set sets the value of the named command-line flag. +func Set(name, value string) error { return commandLine.Set(name, value) } @@ -543,12 +558,38 @@ func (f *FlagSet) Float64(name string, value float64, usage string) *float64 { return p } -// Float64 defines an int flag with specified name, default value, and usage string. +// Float64 defines a float64 flag with specified name, default value, and usage string. // The return value is the address of a float64 variable that stores the value of the flag. func Float64(name string, value float64, usage string) *float64 { return commandLine.Float64(name, value, usage) } +// DurationVar defines a time.Duration flag with specified name, default value, and usage string. +// The argument p points to a time.Duration variable in which to store the value of the flag. +func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) { + f.Var(newDurationValue(value, p), name, usage) +} + +// DurationVar defines a time.Duration flag with specified name, default value, and usage string. +// The argument p points to a time.Duration variable in which to store the value of the flag. +func DurationVar(p *time.Duration, name string, value time.Duration, usage string) { + commandLine.Var(newDurationValue(value, p), name, usage) +} + +// Duration defines a time.Duration flag with specified name, default value, and usage string. +// The return value is the address of a time.Duration variable that stores the value of the flag. +func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration { + p := new(time.Duration) + f.DurationVar(p, name, value, usage) + return p +} + +// Duration defines a time.Duration flag with specified name, default value, and usage string. +// The return value is the address of a time.Duration variable that stores the value of the flag. +func Duration(name string, value time.Duration, usage string) *time.Duration { + return commandLine.Duration(name, value, usage) +} + // Var defines a flag with the specified name and usage string. The type and // value of the flag are represented by the first argument, of type Value, which // typically holds a user-defined implementation of Value. For instance, the @@ -645,8 +686,8 @@ func (f *FlagSet) parseOne() (bool, error) { } if fv, ok := flag.Value.(*boolValue); ok { // special case: doesn't need an arg if has_value { - if !fv.Set(value) { - f.failf("invalid boolean value %q for flag: -%s", value, name) + if err := fv.Set(value); err != nil { + f.failf("invalid boolean value %q for -%s: %v", value, name, err) } } else { fv.Set("true") @@ -661,9 +702,8 @@ func (f *FlagSet) parseOne() (bool, error) { if !has_value { return false, f.failf("flag needs an argument: -%s", name) } - ok = flag.Value.Set(value) - if !ok { - return false, f.failf("invalid value %q for flag: -%s", value, name) + if err := flag.Value.Set(value); err != nil { + return false, f.failf("invalid value %q for flag -%s: %v", value, name, err) } } if f.actual == nil { diff --git a/libgo/go/flag/flag_test.go b/libgo/go/flag/flag_test.go index f13531669c1..698c15f2c58 100644 --- a/libgo/go/flag/flag_test.go +++ b/libgo/go/flag/flag_test.go @@ -10,16 +10,18 @@ import ( "os" "sort" "testing" + "time" ) var ( - test_bool = Bool("test_bool", false, "bool value") - test_int = Int("test_int", 0, "int value") - test_int64 = Int64("test_int64", 0, "int64 value") - test_uint = Uint("test_uint", 0, "uint value") - test_uint64 = Uint64("test_uint64", 0, "uint64 value") - test_string = String("test_string", "0", "string value") - test_float64 = Float64("test_float64", 0, "float64 value") + test_bool = Bool("test_bool", false, "bool value") + test_int = Int("test_int", 0, "int value") + test_int64 = Int64("test_int64", 0, "int64 value") + test_uint = Uint("test_uint", 0, "uint value") + test_uint64 = Uint64("test_uint64", 0, "uint64 value") + test_string = String("test_string", "0", "string value") + test_float64 = Float64("test_float64", 0, "float64 value") + test_duration = Duration("test_duration", 0, "time.Duration value") ) func boolString(s string) string { @@ -41,6 +43,8 @@ func TestEverything(t *testing.T) { ok = true case f.Name == "test_bool" && f.Value.String() == boolString(desired): ok = true + case f.Name == "test_duration" && f.Value.String() == desired+"s": + ok = true } if !ok { t.Error("Visit: bad value", f.Value.String(), "for", f.Name) @@ -48,7 +52,7 @@ func TestEverything(t *testing.T) { } } VisitAll(visitor) - if len(m) != 7 { + if len(m) != 8 { t.Error("VisitAll misses some flags") for k, v := range m { t.Log(k, *v) @@ -70,9 +74,10 @@ func TestEverything(t *testing.T) { Set("test_uint64", "1") Set("test_string", "1") Set("test_float64", "1") + Set("test_duration", "1s") desired = "1" Visit(visitor) - if len(m) != 7 { + if len(m) != 8 { t.Error("Visit fails after set") for k, v := range m { t.Log(k, *v) @@ -109,6 +114,7 @@ func testParse(f *FlagSet, t *testing.T) { uint64Flag := f.Uint64("uint64", 0, "uint64 value") stringFlag := f.String("string", "0", "string value") float64Flag := f.Float64("float64", 0, "float64 value") + durationFlag := f.Duration("duration", 5*time.Second, "time.Duration value") extra := "one-extra-argument" args := []string{ "-bool", @@ -119,6 +125,7 @@ func testParse(f *FlagSet, t *testing.T) { "--uint64", "25", "-string", "hello", "-float64", "2718e28", + "-duration", "2m", extra, } if err := f.Parse(args); err != nil { @@ -151,6 +158,9 @@ func testParse(f *FlagSet, t *testing.T) { if *float64Flag != 2718e28 { t.Error("float64 flag should be 2718e28, is ", *float64Flag) } + if *durationFlag != 2*time.Minute { + t.Error("duration flag should be 2m, is ", *durationFlag) + } if len(f.Args()) != 1 { t.Error("expected one argument, got", len(f.Args())) } else if f.Args()[0] != extra { @@ -174,9 +184,9 @@ func (f *flagVar) String() string { return fmt.Sprint([]string(*f)) } -func (f *flagVar) Set(value string) bool { +func (f *flagVar) Set(value string) error { *f = append(*f, value) - return true + return nil } func TestUserDefined(t *testing.T) { |