Skip to content

Commit

Permalink
flag: arrange for FlagSet.Usage to be non-nil by default
Browse files Browse the repository at this point in the history
This allows callers to invoke f.Usage() themselves and get the default
usage handler instead of a panic (from calling a nil function).

Fixes golang#16955.

Change-Id: Ie337fd9e1f85daf78c5eae7b5c41d5ad8c1f89bf
Reviewed-on: https://go-review.googlesource.com/31576
Run-TryBot: Russ Cox <[email protected]>
Reviewed-by: Rob Pike <[email protected]>
  • Loading branch information
rsc committed Oct 26, 2016
1 parent f9027d6 commit 4954369
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/flag/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ import "os"
// exit the program.
func ResetForTesting(usage func()) {
CommandLine = NewFlagSet(os.Args[0], ContinueOnError)
CommandLine.Usage = commandLineUsage
Usage = usage
}
21 changes: 15 additions & 6 deletions src/flag/flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -502,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 {
Expand Down Expand Up @@ -821,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()
}
Expand Down Expand Up @@ -955,13 +951,26 @@ 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 {
f := &FlagSet{
name: name,
errorHandling: errorHandling,
}
f.Usage = f.defaultUsage
return f
}

Expand Down

0 comments on commit 4954369

Please sign in to comment.