diff options
Diffstat (limited to 'libgo/go/flag/flag.go')
-rw-r--r-- | libgo/go/flag/flag.go | 68 |
1 files changed, 47 insertions, 21 deletions
diff --git a/libgo/go/flag/flag.go b/libgo/go/flag/flag.go index 3abc80e9c6..bbbc55a279 100644 --- a/libgo/go/flag/flag.go +++ b/libgo/go/flag/flag.go @@ -68,6 +68,7 @@ import ( "fmt" "io" "os" + "reflect" "sort" "strconv" "time" @@ -93,7 +94,7 @@ func (b *boolValue) Set(s string) error { func (b *boolValue) Get() interface{} { return bool(*b) } -func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) } +func (b *boolValue) String() string { return strconv.FormatBool(bool(*b)) } func (b *boolValue) IsBoolFlag() bool { return true } @@ -120,7 +121,7 @@ func (i *intValue) Set(s string) error { func (i *intValue) Get() interface{} { return int(*i) } -func (i *intValue) String() string { return fmt.Sprintf("%v", *i) } +func (i *intValue) String() string { return strconv.Itoa(int(*i)) } // -- int64 Value type int64Value int64 @@ -138,7 +139,7 @@ func (i *int64Value) Set(s string) error { func (i *int64Value) Get() interface{} { return int64(*i) } -func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) } +func (i *int64Value) String() string { return strconv.FormatInt(int64(*i), 10) } // -- uint Value type uintValue uint @@ -156,7 +157,7 @@ func (i *uintValue) Set(s string) error { func (i *uintValue) Get() interface{} { return uint(*i) } -func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) } +func (i *uintValue) String() string { return strconv.FormatUint(uint64(*i), 10) } // -- uint64 Value type uint64Value uint64 @@ -174,7 +175,7 @@ func (i *uint64Value) Set(s string) error { func (i *uint64Value) Get() interface{} { return uint64(*i) } -func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) } +func (i *uint64Value) String() string { return strconv.FormatUint(uint64(*i), 10) } // -- string Value type stringValue string @@ -191,7 +192,7 @@ func (s *stringValue) Set(val string) error { func (s *stringValue) Get() interface{} { return string(*s) } -func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) } +func (s *stringValue) String() string { return string(*s) } // -- float64 Value type float64Value float64 @@ -209,7 +210,7 @@ func (f *float64Value) Set(s string) error { func (f *float64Value) Get() interface{} { return float64(*f) } -func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) } +func (f *float64Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 64) } // -- time.Duration Value type durationValue time.Duration @@ -237,6 +238,8 @@ func (d *durationValue) String() string { return (*time.Duration)(d).String() } // rather than using the next command-line argument. // // Set is called once, in command line order, for each flag present. +// The flag package may call the String method with a zero-valued receiver, +// such as a nil pointer. type Value interface { String() string Set(string) error @@ -261,7 +264,7 @@ const ( PanicOnError // Call panic with a descriptive error. ) -// A FlagSet represents a set of defined flags. The zero value of a FlagSet +// A FlagSet represents a set of defined flags. The zero value of a FlagSet // has no name and has ContinueOnError error handling. type FlagSet struct { // Usage is the function called when an error occurs while parsing flags. @@ -324,7 +327,7 @@ func (f *FlagSet) VisitAll(fn func(*Flag)) { } // VisitAll visits the command-line flags in lexicographical order, calling -// fn for each. It visits all flags, even those not set. +// fn for each. It visits all flags, even those not set. func VisitAll(fn func(*Flag)) { CommandLine.VisitAll(fn) } @@ -338,7 +341,7 @@ func (f *FlagSet) Visit(fn func(*Flag)) { } // Visit visits the command-line flags in lexicographical order, calling fn -// for each. It visits only those flags that have been set. +// for each. It visits only those flags that have been set. func Visit(fn func(*Flag)) { CommandLine.Visit(fn) } @@ -378,7 +381,21 @@ func Set(name, value string) error { // isZeroValue guesses whether the string represents the zero // value for a flag. It is not accurate but in practice works OK. -func isZeroValue(value string) bool { +func isZeroValue(flag *Flag, value string) bool { + // Build a zero value of the flag's Value type, and see if the + // result of calling its String method equals the value passed in. + // This works unless the Value type is itself an interface type. + typ := reflect.TypeOf(flag.Value) + var z reflect.Value + if typ.Kind() == reflect.Ptr { + z = reflect.New(typ.Elem()) + } else { + z = reflect.Zero(typ) + } + if value == z.Interface().(Value).String() { + return true + } + switch value { case "false": return true @@ -449,7 +466,7 @@ func (f *FlagSet) PrintDefaults() { s += "\n \t" } s += usage - if !isZeroValue(flag.DefValue) { + if !isZeroValue(flag, flag.DefValue) { if _, ok := flag.Value.(*stringValue); ok { // put quotes on the value s += fmt.Sprintf(" (default %q)", flag.DefValue) @@ -485,7 +502,7 @@ func PrintDefaults() { } // defaultUsage is the default function to print a usage message. -func defaultUsage(f *FlagSet) { +func (f *FlagSet) defaultUsage() { if f.name == "" { fmt.Fprintf(f.out(), "Usage:\n") } else { @@ -514,7 +531,7 @@ func (f *FlagSet) NFlag() int { return len(f.actual) } // NFlag returns the number of command-line flags that have been set. func NFlag() int { return len(CommandLine.actual) } -// Arg returns the i'th argument. Arg(0) is the first remaining argument +// Arg returns the i'th argument. Arg(0) is the first remaining argument // after flags have been processed. Arg returns an empty string if the // requested element does not exist. func (f *FlagSet) Arg(i int) string { @@ -524,7 +541,7 @@ func (f *FlagSet) Arg(i int) string { return f.args[i] } -// Arg returns the i'th command-line argument. Arg(0) is the first remaining argument +// Arg returns the i'th command-line argument. Arg(0) is the first remaining argument // after flags have been processed. Arg returns an empty string if the // requested element does not exist. func Arg(i int) string { @@ -804,11 +821,7 @@ func (f *FlagSet) failf(format string, a ...interface{}) error { // or the appropriate default usage function otherwise. func (f *FlagSet) usage() { if f.Usage == nil { - if f == CommandLine { - Usage() - } else { - defaultUsage(f) - } + f.defaultUsage() } else { f.Usage() } @@ -890,7 +903,7 @@ func (f *FlagSet) parseOne() (bool, error) { } // Parse parses flag definitions from the argument list, which should not -// include the command name. Must be called after all flags in the FlagSet +// include the command name. Must be called after all flags in the FlagSet // are defined and before flags are accessed by the program. // The return value will be ErrHelp if -help or -h were set but not defined. func (f *FlagSet) Parse(arguments []string) error { @@ -938,6 +951,18 @@ func Parsed() bool { // methods of CommandLine. var CommandLine = NewFlagSet(os.Args[0], ExitOnError) +func init() { + // Override generic FlagSet default Usage with call to global Usage. + // Note: This is not CommandLine.Usage = Usage, + // because we want any eventual call to use any updated value of Usage, + // not the value it has when this line is run. + CommandLine.Usage = commandLineUsage +} + +func commandLineUsage() { + Usage() +} + // NewFlagSet returns a new, empty flag set with the specified name and // error handling property. func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet { @@ -945,6 +970,7 @@ func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet { name: name, errorHandling: errorHandling, } + f.Usage = f.defaultUsage return f } |