summaryrefslogtreecommitdiff
path: root/libgo/go/flag/flag.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/flag/flag.go')
-rw-r--r--libgo/go/flag/flag.go151
1 files changed, 125 insertions, 26 deletions
diff --git a/libgo/go/flag/flag.go b/libgo/go/flag/flag.go
index 60aef5d806c..3abc80e9c67 100644
--- a/libgo/go/flag/flag.go
+++ b/libgo/go/flag/flag.go
@@ -31,7 +31,7 @@
fmt.Println("ip has value ", *ip)
fmt.Println("flagvar has value ", flagvar)
- After parsing, the arguments after the flag are available as the
+ After parsing, the arguments following the flags are available as the
slice flag.Args() or individually as flag.Arg(i).
The arguments are indexed from 0 through flag.NArg()-1.
@@ -235,6 +235,8 @@ func (d *durationValue) String() string { return (*time.Duration)(d).String() }
// If a Value has an IsBoolFlag() bool method returning true,
// the command-line parser makes -name equivalent to -name=true
// rather than using the next command-line argument.
+//
+// Set is called once, in command line order, for each flag present.
type Value interface {
String() string
Set(string) error
@@ -249,13 +251,14 @@ type Getter interface {
Get() interface{}
}
-// ErrorHandling defines how to handle flag parsing errors.
+// ErrorHandling defines how FlagSet.Parse behaves if the parse fails.
type ErrorHandling int
+// These constants cause FlagSet.Parse to behave as described if the parse fails.
const (
- ContinueOnError ErrorHandling = iota
- ExitOnError
- PanicOnError
+ ContinueOnError ErrorHandling = iota // Return a descriptive error.
+ ExitOnError // Call os.Exit(2).
+ PanicOnError // Call panic with a descriptive error.
)
// A FlagSet represents a set of defined flags. The zero value of a FlagSet
@@ -373,20 +376,110 @@ func Set(name, value string) error {
return CommandLine.Set(name, value)
}
-// PrintDefaults prints, to standard error unless configured
-// otherwise, the default values of all defined flags in the set.
+// 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 {
+ switch value {
+ case "false":
+ return true
+ case "":
+ return true
+ case "0":
+ return true
+ }
+ return false
+}
+
+// UnquoteUsage extracts a back-quoted name from the usage
+// string for a flag and returns it and the un-quoted usage.
+// Given "a `name` to show" it returns ("name", "a name to show").
+// If there are no back quotes, the name is an educated guess of the
+// type of the flag's value, or the empty string if the flag is boolean.
+func UnquoteUsage(flag *Flag) (name string, usage string) {
+ // Look for a back-quoted name, but avoid the strings package.
+ usage = flag.Usage
+ for i := 0; i < len(usage); i++ {
+ if usage[i] == '`' {
+ for j := i + 1; j < len(usage); j++ {
+ if usage[j] == '`' {
+ name = usage[i+1 : j]
+ usage = usage[:i] + name + usage[j+1:]
+ return name, usage
+ }
+ }
+ break // Only one back quote; use type name.
+ }
+ }
+ // No explicit name, so use type if we can find one.
+ name = "value"
+ switch flag.Value.(type) {
+ case boolFlag:
+ name = ""
+ case *durationValue:
+ name = "duration"
+ case *float64Value:
+ name = "float"
+ case *intValue, *int64Value:
+ name = "int"
+ case *stringValue:
+ name = "string"
+ case *uintValue, *uint64Value:
+ name = "uint"
+ }
+ return
+}
+
+// PrintDefaults prints to standard error the default values of all
+// defined command-line flags in the set. See the documentation for
+// the global function PrintDefaults for more information.
func (f *FlagSet) PrintDefaults() {
f.VisitAll(func(flag *Flag) {
- format := " -%s=%s: %s\n"
- if _, ok := flag.Value.(*stringValue); ok {
- // put quotes on the value
- format = " -%s=%q: %s\n"
+ s := fmt.Sprintf(" -%s", flag.Name) // Two spaces before -; see next two comments.
+ name, usage := UnquoteUsage(flag)
+ if len(name) > 0 {
+ s += " " + name
+ }
+ // Boolean flags of one ASCII letter are so common we
+ // treat them specially, putting their usage on the same line.
+ if len(s) <= 4 { // space, space, '-', 'x'.
+ s += "\t"
+ } else {
+ // Four spaces before the tab triggers good alignment
+ // for both 4- and 8-space tab stops.
+ s += "\n \t"
}
- fmt.Fprintf(f.out(), format, flag.Name, flag.DefValue, flag.Usage)
+ s += usage
+ if !isZeroValue(flag.DefValue) {
+ if _, ok := flag.Value.(*stringValue); ok {
+ // put quotes on the value
+ s += fmt.Sprintf(" (default %q)", flag.DefValue)
+ } else {
+ s += fmt.Sprintf(" (default %v)", flag.DefValue)
+ }
+ }
+ fmt.Fprint(f.out(), s, "\n")
})
}
-// PrintDefaults prints to standard error the default values of all defined command-line flags.
+// PrintDefaults prints, to standard error unless configured otherwise,
+// a usage message showing the default settings of all defined
+// command-line flags.
+// For an integer valued flag x, the default output has the form
+// -x int
+// usage-message-for-x (default 7)
+// The usage message will appear on a separate line for anything but
+// a bool flag with a one-byte name. For bool flags, the type is
+// omitted and if the flag name is one byte the usage message appears
+// on the same line. The parenthetical default is omitted if the
+// default is the zero value for the type. The listed type, here int,
+// can be changed by placing a back-quoted name in the flag's usage
+// string; the first such item in the message is taken to be a parameter
+// name to show in the message and the back quotes are stripped from
+// the message when displayed. For instance, given
+// flag.String("I", "", "search `directory` for include files")
+// the output will be
+// -I directory
+// search directory for include files.
func PrintDefaults() {
CommandLine.PrintDefaults()
}
@@ -408,6 +501,8 @@ func defaultUsage(f *FlagSet) {
// Usage prints to standard error a usage message documenting all defined command-line flags.
// It is called when an error occurs while parsing flags.
// The function is a variable that may be changed to point to a custom function.
+// By default it prints a simple header and calls PrintDefaults; for details about the
+// format of the output and how to control it, see the documentation for PrintDefaults.
var Usage = func() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
PrintDefaults()
@@ -420,7 +515,8 @@ func (f *FlagSet) NFlag() int { return len(f.actual) }
func NFlag() int { return len(CommandLine.actual) }
// Arg returns the i'th argument. Arg(0) is the first remaining argument
-// after flags have been processed.
+// after flags have been processed. Arg returns an empty string if the
+// requested element does not exist.
func (f *FlagSet) Arg(i int) string {
if i < 0 || i >= len(f.args) {
return ""
@@ -429,7 +525,8 @@ func (f *FlagSet) Arg(i int) string {
}
// Arg returns the i'th command-line argument. Arg(0) is the first remaining argument
-// after flags have been processed.
+// after flags have been processed. Arg returns an empty string if the
+// requested element does not exist.
func Arg(i int) string {
return CommandLine.Arg(i)
}
@@ -726,27 +823,27 @@ func (f *FlagSet) parseOne() (bool, error) {
if len(s) == 0 || s[0] != '-' || len(s) == 1 {
return false, nil
}
- num_minuses := 1
+ numMinuses := 1
if s[1] == '-' {
- num_minuses++
+ numMinuses++
if len(s) == 2 { // "--" terminates the flags
f.args = f.args[1:]
return false, nil
}
}
- name := s[num_minuses:]
+ name := s[numMinuses:]
if len(name) == 0 || name[0] == '-' || name[0] == '=' {
return false, f.failf("bad flag syntax: %s", s)
}
// it's a flag. does it have an argument?
f.args = f.args[1:]
- has_value := false
+ hasValue := false
value := ""
for i := 1; i < len(name); i++ { // equals cannot be first
if name[i] == '=' {
value = name[i+1:]
- has_value = true
+ hasValue = true
name = name[0:i]
break
}
@@ -762,21 +859,23 @@ func (f *FlagSet) parseOne() (bool, error) {
}
if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
- if has_value {
+ if hasValue {
if err := fv.Set(value); err != nil {
return false, f.failf("invalid boolean value %q for -%s: %v", value, name, err)
}
} else {
- fv.Set("true")
+ if err := fv.Set("true"); err != nil {
+ return false, f.failf("invalid boolean flag %s: %v", name, err)
+ }
}
} else {
// It must have a value, which might be the next argument.
- if !has_value && len(f.args) > 0 {
+ if !hasValue && len(f.args) > 0 {
// value is the next arg
- has_value = true
+ hasValue = true
value, f.args = f.args[0], f.args[1:]
}
- if !has_value {
+ if !hasValue {
return false, f.failf("flag needs an argument: -%s", name)
}
if err := flag.Value.Set(value); err != nil {
@@ -829,7 +928,7 @@ func Parse() {
CommandLine.Parse(os.Args[1:])
}
-// Parsed returns true if the command-line flags have been parsed.
+// Parsed reports whether the command-line flags have been parsed.
func Parsed() bool {
return CommandLine.Parsed()
}