Commit 49543695 authored by Russ Cox's avatar Russ Cox

flag: arrange for FlagSet.Usage to be non-nil by default

This allows callers to invoke f.Usage() themselves and get the default
usage handler instead of a panic (from calling a nil function).

Fixes #16955.

Change-Id: Ie337fd9e1f85daf78c5eae7b5c41d5ad8c1f89bf
Reviewed-on: https://go-review.googlesource.com/31576
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: default avatarRob Pike <r@golang.org>
parent f9027d61
...@@ -13,5 +13,6 @@ import "os" ...@@ -13,5 +13,6 @@ import "os"
// exit the program. // exit the program.
func ResetForTesting(usage func()) { func ResetForTesting(usage func()) {
CommandLine = NewFlagSet(os.Args[0], ContinueOnError) CommandLine = NewFlagSet(os.Args[0], ContinueOnError)
CommandLine.Usage = commandLineUsage
Usage = usage Usage = usage
} }
...@@ -502,7 +502,7 @@ func PrintDefaults() { ...@@ -502,7 +502,7 @@ func PrintDefaults() {
} }
// defaultUsage is the default function to print a usage message. // defaultUsage is the default function to print a usage message.
func defaultUsage(f *FlagSet) { func (f *FlagSet) defaultUsage() {
if f.name == "" { if f.name == "" {
fmt.Fprintf(f.out(), "Usage:\n") fmt.Fprintf(f.out(), "Usage:\n")
} else { } else {
...@@ -821,11 +821,7 @@ func (f *FlagSet) failf(format string, a ...interface{}) error { ...@@ -821,11 +821,7 @@ func (f *FlagSet) failf(format string, a ...interface{}) error {
// or the appropriate default usage function otherwise. // or the appropriate default usage function otherwise.
func (f *FlagSet) usage() { func (f *FlagSet) usage() {
if f.Usage == nil { if f.Usage == nil {
if f == CommandLine { f.defaultUsage()
Usage()
} else {
defaultUsage(f)
}
} else { } else {
f.Usage() f.Usage()
} }
...@@ -955,6 +951,18 @@ func Parsed() bool { ...@@ -955,6 +951,18 @@ func Parsed() bool {
// methods of CommandLine. // methods of CommandLine.
var CommandLine = NewFlagSet(os.Args[0], ExitOnError) 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 // NewFlagSet returns a new, empty flag set with the specified name and
// error handling property. // error handling property.
func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet { func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
...@@ -962,6 +970,7 @@ func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet { ...@@ -962,6 +970,7 @@ func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
name: name, name: name,
errorHandling: errorHandling, errorHandling: errorHandling,
} }
f.Usage = f.defaultUsage
return f return f
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment