flags: allow distinct sets of flags.

A FlagSet is an independent set of flags that may be used,
for example, to provide flag processing for subcommands
in a CLI.  The standard, os.Args-derived set of flags is a
global but non-exported FlagSet and the standard functions
are wrappers for methods of that FlagSet.

Allow the programmer to control whether the program
exits if there is a parse error.  For the default set, the behavior
remains to exit on error.

The handling of Usage is odd due to backward compatibility.

R=golang-dev, bradfitz, r, bradfitz
CC=golang-dev
https://golang.org/cl/4517092
diff --git a/src/pkg/flag/export_test.go b/src/pkg/flag/export_test.go
index b5e3243..7b19080 100644
--- a/src/pkg/flag/export_test.go
+++ b/src/pkg/flag/export_test.go
@@ -9,24 +9,14 @@
 // Additional routines compiled into the package only during testing.
 
 // ResetForTesting clears all flag state and sets the usage function as directed.
-// After calling ResetForTesting, parse errors in flag handling will panic rather
-// than exit the program.
+// After calling ResetForTesting, parse errors in flag handling will not
+// exit the program.
 func ResetForTesting(usage func()) {
-	flags = &allFlags{make(map[string]*Flag), make(map[string]*Flag), os.Args[1:]}
+	commandLine = NewFlagSet(os.Args[0], ContinueOnError)
 	Usage = usage
-	panicOnError = true
 }
 
-// ParseForTesting parses the flag state using the provided arguments. It
-// should be called after 1) ResetForTesting and 2) setting up the new flags.
-// The return value reports whether the parse was error-free.
-func ParseForTesting(args []string) (result bool) {
-	defer func() {
-		if recover() != nil {
-			result = false
-		}
-	}()
-	os.Args = args
-	Parse()
-	return true
+// CommandLine returns the default FlagSet.
+func CommandLine() *FlagSet {
+	return commandLine
 }
diff --git a/src/pkg/flag/flag.go b/src/pkg/flag/flag.go
index 062d4a5..ec254fd 100644
--- a/src/pkg/flag/flag.go
+++ b/src/pkg/flag/flag.go
@@ -50,18 +50,12 @@
 	Integer flags accept 1234, 0664, 0x1234 and may be negative.
 	Boolean flags may be 1, 0, t, f, true, false, TRUE, FALSE, True, False.
 
-	It is safe to call flag.Parse multiple times, possibly after changing
-	os.Args.  This makes it possible to implement command lines with
-	subcommands that enable additional flags, as in:
-
-		flag.Bool(...)  // global options
-		flag.Parse()  // parse leading command
-		subcmd := flag.Arg(0)
-		switch subcmd {
-			// add per-subcommand options
-		}
-		os.Args = flag.Args()
-		flag.Parse()
+	The default set of command-line flags is controlled by
+	top-level functions.  The FlagSet type allows one to define
+	independent sets of flags, such as to implement subcommands
+	in a command-line interface. The methods of FlagSet are
+	analogous to the top-level functions for the command-line
+	flag set.
 */
 package flag
 
@@ -190,6 +184,30 @@
 	Set(string) bool
 }
 
+// ErrorHandling defines how to handle flag parsing errors.
+type ErrorHandling int
+
+const (
+	ContinueOnError ErrorHandling = iota
+	ExitOnError
+	PanicOnError
+)
+
+// A FlagSet represents a set of defined flags.
+type FlagSet struct {
+	// Usage is the function called when an error occurs while parsing flags.
+	// The field is a function (not a method) that may be changed to point to
+	// a custom error handler.
+	Usage func()
+
+	name          string
+	actual        map[string]*Flag
+	formal        map[string]*Flag
+	args          []string // arguments after flags
+	exitOnError   bool     // does the program exit if there's an error?
+	errorHandling ErrorHandling
+}
+
 // A Flag represents the state of a flag.
 type Flag struct {
 	Name     string // name as it appears on command line
@@ -198,14 +216,6 @@
 	DefValue string // default value (as text); for usage message
 }
 
-type allFlags struct {
-	actual map[string]*Flag
-	formal map[string]*Flag
-	args   []string // arguments after flags
-}
-
-var flags *allFlags
-
 // sortFlags returns the flags as a slice in lexicographical sorted order.
 func sortFlags(flags map[string]*Flag) []*Flag {
 	list := make(sort.StringArray, len(flags))
@@ -224,43 +234,67 @@
 
 // VisitAll visits the flags in lexicographical order, calling fn for each.
 // It visits all flags, even those not set.
-func VisitAll(fn func(*Flag)) {
-	for _, f := range sortFlags(flags.formal) {
-		fn(f)
+func (f *FlagSet) VisitAll(fn func(*Flag)) {
+	for _, flag := range sortFlags(f.formal) {
+		fn(flag)
 	}
 }
 
+// VisitAll visits the command-line flags in lexicographical order, calling
+// fn for each.  It visits all flags, even those not set.
+func VisitAll(fn func(*Flag)) {
+	commandLine.VisitAll(fn)
+}
+
 // Visit visits the flags in lexicographical order, calling fn for each.
 // It visits only those flags that have been set.
-func Visit(fn func(*Flag)) {
-	for _, f := range sortFlags(flags.actual) {
-		fn(f)
+func (f *FlagSet) Visit(fn func(*Flag)) {
+	for _, flag := range sortFlags(f.actual) {
+		fn(flag)
 	}
 }
 
+// Visit visits the command-line flags in lexicographical order, calling fn
+// for each.  It visits only those flags that have been set.
+func Visit(fn func(*Flag)) {
+	commandLine.Visit(fn)
+}
+
 // Lookup returns the Flag structure of the named flag, returning nil if none exists.
+func (f *FlagSet) Lookup(name string) *Flag {
+	return f.formal[name]
+}
+
+// Lookup returns the Flag structure of the named command-line flag,
+// returning nil if none exists.
 func Lookup(name string) *Flag {
-	return flags.formal[name]
+	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 Set(name, value string) bool {
-	f, ok := flags.formal[name]
+func (f *FlagSet) Set(name, value string) bool {
+	flag, ok := f.formal[name]
 	if !ok {
 		return false
 	}
-	ok = f.Value.Set(value)
+	ok = flag.Value.Set(value)
 	if !ok {
 		return false
 	}
-	flags.actual[name] = f
+	f.actual[name] = flag
 	return true
 }
 
-// PrintDefaults prints to standard error the default values of all defined flags.
-func PrintDefaults() {
-	VisitAll(func(f *Flag) {
+// 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 {
+	return commandLine.Set(name, value)
+}
+
+// PrintDefaults prints to standard error the default values of all defined flags in the set.
+func (f *FlagSet) PrintDefaults() {
+	f.VisitAll(func(f *Flag) {
 		format := "  -%s=%s: %s\n"
 		if _, ok := f.Value.(*stringValue); ok {
 			// put quotes on the value
@@ -270,141 +304,255 @@
 	})
 }
 
-// Usage prints to standard error a default usage message documenting all defined flags.
-// The function is a variable that may be changed to point to a custom function.
-var Usage = func() {
-	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
-	PrintDefaults()
+// PrintDefaults prints to standard error the default values of all defined command-line flags.
+func PrintDefaults() {
+	commandLine.PrintDefaults()
 }
 
-var panicOnError = false
+// defaultUsage is the default function to print a usage message.
+func defaultUsage(f *FlagSet) {
+	fmt.Fprintf(os.Stderr, "Usage of %s:\n", f.name)
+	f.PrintDefaults()
+}
 
-// failf prints to standard error a formatted error and Usage, and then exits the program.
-func failf(format string, a ...interface{}) {
-	fmt.Fprintf(os.Stderr, format, a...)
-	Usage()
-	if panicOnError {
-		panic("flag parse error")
-	}
-	os.Exit(2)
+// Usage prints to standard error a usage message documenting all defined command-line flags.
+// The function is a variable that may be changed to point to a custom function.
+var Usage = func() {
+	defaultUsage(commandLine)
 }
 
 // NFlag returns the number of flags that have been set.
-func NFlag() int { return len(flags.actual) }
+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
+// after flags have been processed.
+func (f *FlagSet) Arg(i int) string {
+	if i < 0 || i >= len(f.args) {
+		return ""
+	}
+	return f.args[i]
+}
 
 // Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
 // after flags have been processed.
 func Arg(i int) string {
-	if i < 0 || i >= len(flags.args) {
-		return ""
-	}
-	return flags.args[i]
+	return commandLine.Arg(i)
 }
 
 // NArg is the number of arguments remaining after flags have been processed.
-func NArg() int { return len(flags.args) }
+func (f *FlagSet) NArg() int { return len(f.args) }
+
+// NArg is the number of arguments remaining after flags have been processed.
+func NArg() int { return len(commandLine.args) }
+
+// Args returns the non-flag arguments.
+func (f *FlagSet) Args() []string { return f.args }
 
 // Args returns the non-flag command-line arguments.
-func Args() []string { return flags.args }
+func Args() []string { return commandLine.args }
+
+// BoolVar defines a bool flag with specified name, default value, and usage string.
+// The argument p points to a bool variable in which to store the value of the flag.
+func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
+	f.Var(newBoolValue(value, p), name, usage)
+}
 
 // BoolVar defines a bool flag with specified name, default value, and usage string.
 // The argument p points to a bool variable in which to store the value of the flag.
 func BoolVar(p *bool, name string, value bool, usage string) {
-	Var(newBoolValue(value, p), name, usage)
+	commandLine.Var(newBoolValue(value, p), name, usage)
+}
+
+// Bool defines a bool flag with specified name, default value, and usage string.
+// The return value is the address of a bool variable that stores the value of the flag.
+func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
+	p := new(bool)
+	f.BoolVar(p, name, value, usage)
+	return p
 }
 
 // Bool defines a bool flag with specified name, default value, and usage string.
 // The return value is the address of a bool variable that stores the value of the flag.
 func Bool(name string, value bool, usage string) *bool {
-	p := new(bool)
-	BoolVar(p, name, value, usage)
-	return p
+	return commandLine.Bool(name, value, usage)
+}
+
+// IntVar defines an int flag with specified name, default value, and usage string.
+// The argument p points to an int variable in which to store the value of the flag.
+func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
+	f.Var(newIntValue(value, p), name, usage)
 }
 
 // IntVar defines an int flag with specified name, default value, and usage string.
 // The argument p points to an int variable in which to store the value of the flag.
 func IntVar(p *int, name string, value int, usage string) {
-	Var(newIntValue(value, p), name, usage)
+	commandLine.Var(newIntValue(value, p), name, usage)
+}
+
+// Int defines an int flag with specified name, default value, and usage string.
+// The return value is the address of an int variable that stores the value of the flag.
+func (f *FlagSet) Int(name string, value int, usage string) *int {
+	p := new(int)
+	f.IntVar(p, name, value, usage)
+	return p
 }
 
 // Int defines an int flag with specified name, default value, and usage string.
 // The return value is the address of an int variable that stores the value of the flag.
 func Int(name string, value int, usage string) *int {
-	p := new(int)
-	IntVar(p, name, value, usage)
-	return p
+	return commandLine.Int(name, value, usage)
+}
+
+// Int64Var defines an int64 flag with specified name, default value, and usage string.
+// The argument p points to an int64 variable in which to store the value of the flag.
+func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {
+	f.Var(newInt64Value(value, p), name, usage)
 }
 
 // Int64Var defines an int64 flag with specified name, default value, and usage string.
 // The argument p points to an int64 variable in which to store the value of the flag.
 func Int64Var(p *int64, name string, value int64, usage string) {
-	Var(newInt64Value(value, p), name, usage)
+	commandLine.Var(newInt64Value(value, p), name, usage)
+}
+
+// Int64 defines an int64 flag with specified name, default value, and usage string.
+// The return value is the address of an int64 variable that stores the value of the flag.
+func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
+	p := new(int64)
+	f.Int64Var(p, name, value, usage)
+	return p
 }
 
 // Int64 defines an int64 flag with specified name, default value, and usage string.
 // The return value is the address of an int64 variable that stores the value of the flag.
 func Int64(name string, value int64, usage string) *int64 {
-	p := new(int64)
-	Int64Var(p, name, value, usage)
-	return p
+	return commandLine.Int64(name, value, usage)
 }
 
 // UintVar defines a uint flag with specified name, default value, and usage string.
 // The argument p points to a uint variable in which to store the value of the flag.
+func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
+	f.Var(newUintValue(value, p), name, usage)
+}
+
+// UintVar defines a uint flag with specified name, default value, and usage string.
+// The argument p points to a uint  variable in which to store the value of the flag.
 func UintVar(p *uint, name string, value uint, usage string) {
-	Var(newUintValue(value, p), name, usage)
+	commandLine.Var(newUintValue(value, p), name, usage)
 }
 
 // Uint defines a uint flag with specified name, default value, and usage string.
-// The return value is the address of a uint variable that stores the value of the flag.
-func Uint(name string, value uint, usage string) *uint {
+// The return value is the address of a uint  variable that stores the value of the flag.
+func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
 	p := new(uint)
-	UintVar(p, name, value, usage)
+	f.UintVar(p, name, value, usage)
 	return p
 }
 
+// Uint defines a uint flag with specified name, default value, and usage string.
+// The return value is the address of a uint  variable that stores the value of the flag.
+func Uint(name string, value uint, usage string) *uint {
+	return commandLine.Uint(name, value, usage)
+}
+
+// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
+// The argument p points to a uint64 variable in which to store the value of the flag.
+func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
+	f.Var(newUint64Value(value, p), name, usage)
+}
+
 // Uint64Var defines a uint64 flag with specified name, default value, and usage string.
 // The argument p points to a uint64 variable in which to store the value of the flag.
 func Uint64Var(p *uint64, name string, value uint64, usage string) {
-	Var(newUint64Value(value, p), name, usage)
+	commandLine.Var(newUint64Value(value, p), name, usage)
+}
+
+// Uint64 defines a uint64 flag with specified name, default value, and usage string.
+// The return value is the address of a uint64 variable that stores the value of the flag.
+func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
+	p := new(uint64)
+	f.Uint64Var(p, name, value, usage)
+	return p
 }
 
 // Uint64 defines a uint64 flag with specified name, default value, and usage string.
 // The return value is the address of a uint64 variable that stores the value of the flag.
 func Uint64(name string, value uint64, usage string) *uint64 {
-	p := new(uint64)
-	Uint64Var(p, name, value, usage)
-	return p
+	return commandLine.Uint64(name, value, usage)
 }
 
 // StringVar defines a string flag with specified name, default value, and usage string.
 // The argument p points to a string variable in which to store the value of the flag.
-func StringVar(p *string, name, value string, usage string) {
-	Var(newStringValue(value, p), name, usage)
+func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
+	f.Var(newStringValue(value, p), name, usage)
+}
+
+// StringVar defines a string flag with specified name, default value, and usage string.
+// The argument p points to a string variable in which to store the value of the flag.
+func StringVar(p *string, name string, value string, usage string) {
+	commandLine.Var(newStringValue(value, p), name, usage)
 }
 
 // String defines a string flag with specified name, default value, and usage string.
 // The return value is the address of a string variable that stores the value of the flag.
-func String(name, value string, usage string) *string {
+func (f *FlagSet) String(name string, value string, usage string) *string {
 	p := new(string)
-	StringVar(p, name, value, usage)
+	f.StringVar(p, name, value, usage)
 	return p
 }
 
+// String defines a string flag with specified name, default value, and usage string.
+// The return value is the address of a string variable that stores the value of the flag.
+func String(name string, value string, usage string) *string {
+	return commandLine.String(name, value, usage)
+}
+
+// Float64Var defines a float64 flag with specified name, default value, and usage string.
+// The argument p points to a float64 variable in which to store the value of the flag.
+func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) {
+	f.Var(newFloat64Value(value, p), name, usage)
+}
+
 // Float64Var defines a float64 flag with specified name, default value, and usage string.
 // The argument p points to a float64 variable in which to store the value of the flag.
 func Float64Var(p *float64, name string, value float64, usage string) {
-	Var(newFloat64Value(value, p), name, usage)
+	commandLine.Var(newFloat64Value(value, p), name, usage)
 }
 
 // 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 {
+func (f *FlagSet) Float64(name string, value float64, usage string) *float64 {
 	p := new(float64)
-	Float64Var(p, name, value, usage)
+	f.Float64Var(p, name, value, usage)
 	return p
 }
 
+// Float64 defines an int 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)
+}
+
+// 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
+// caller could create a flag that turns a comma-separated string into a slice
+// of strings by giving the slice the methods of Value; in particular, Set would
+// decompose the comma-separated string into the slice.
+func (f *FlagSet) Var(value Value, name string, usage string) {
+	// Remember the default value as a string; it won't change.
+	flag := &Flag{name, usage, value, value.String()}
+	_, alreadythere := f.formal[name]
+	if alreadythere {
+		fmt.Fprintf(os.Stderr, "%s flag redefined: %s\n", f.name, name)
+		panic("flag redefinition") // Happens only if flags are declared with identical names
+	}
+	f.formal[name] = flag
+}
+
 // 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
@@ -412,36 +560,42 @@
 // of strings by giving the slice the methods of Value; in particular, Set would
 // decompose the comma-separated string into the slice.
 func Var(value Value, name string, usage string) {
-	// Remember the default value as a string; it won't change.
-	f := &Flag{name, usage, value, value.String()}
-	_, alreadythere := flags.formal[name]
-	if alreadythere {
-		fmt.Fprintln(os.Stderr, "flag redefined:", name)
-		panic("flag redefinition") // Happens only if flags are declared with identical names
-	}
-	flags.formal[name] = f
+	commandLine.Var(value, name, usage)
 }
 
+// failf prints to standard error a formatted error and usage message and
+// returns the error.
+func (f *FlagSet) failf(format string, a ...interface{}) os.Error {
+	err := fmt.Errorf(format, a...)
+	fmt.Println(errc)
+	if f == commandLine {
+		Usage()
+	} else {
+		f.Usage()
+	}
+	return err
+}
 
-func (f *allFlags) parseOne() (ok bool) {
+// parseOne parses one flag. It returns whether a flag was seen.
+func (f *FlagSet) parseOne() (bool, os.Error) {
 	if len(f.args) == 0 {
-		return false
+		return false, nil
 	}
 	s := f.args[0]
 	if len(s) == 0 || s[0] != '-' || len(s) == 1 {
-		return false
+		return false, nil
 	}
 	num_minuses := 1
 	if s[1] == '-' {
 		num_minuses++
 		if len(s) == 2 { // "--" terminates the flags
 			f.args = f.args[1:]
-			return false
+			return false, nil
 		}
 	}
 	name := s[num_minuses:]
 	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
-		failf("bad flag syntax: %s\n", s)
+		return false, f.failf("bad flag syntax: %s", s)
 	}
 
 	// it's a flag. does it have an argument?
@@ -456,15 +610,15 @@
 			break
 		}
 	}
-	m := flags.formal
+	m := f.formal
 	flag, alreadythere := m[name] // BUG
 	if !alreadythere {
-		failf("flag provided but not defined: -%s\n", name)
+		return false, f.failf("flag provided but not defined: -%s", name)
 	}
 	if fv, ok := flag.Value.(*boolValue); ok { // special case: doesn't need an arg
 		if has_value {
 			if !fv.Set(value) {
-				failf("invalid boolean value %q for flag: -%s\n", value, name)
+				f.failf("invalid boolean value %q for flag: -%s", value, name)
 			}
 		} else {
 			fv.Set("true")
@@ -477,25 +631,61 @@
 			value, f.args = f.args[0], f.args[1:]
 		}
 		if !has_value {
-			failf("flag needs an argument: -%s\n", name)
+			return false, f.failf("flag needs an argument: -%s", name)
 		}
 		ok = flag.Value.Set(value)
 		if !ok {
-			failf("invalid value %q for flag: -%s\n", value, name)
+			return false, f.failf("invalid value %q for flag: -%s", value, name)
 		}
 	}
-	flags.actual[name] = flag
-	return true
+	f.actual[name] = flag
+	return true, nil
 }
 
-// Parse parses the command-line flags.  Must be called after all flags are defined
-// and before any are accessed by the program.
-func Parse() {
-	flags.args = os.Args[1:]
-	for flags.parseOne() {
+// Parse parses flag definitions from the argument list, which should not
+// include the command name.  Must be called after all flags in the FlagSet
+// are defined and before flags are accessed by the program.
+func (f *FlagSet) Parse(arguments []string) os.Error {
+	f.args = arguments
+	for {
+		seen, err := f.parseOne()
+		if seen {
+			continue
+		}
+		if err == nil {
+			break
+		}
+		switch f.errorHandling {
+		case ContinueOnError:
+			return err
+		case ExitOnError:
+			os.Exit(2)
+		case PanicOnError:
+			panic(err)
+		}
 	}
+	return nil
 }
 
-func init() {
-	flags = &allFlags{make(map[string]*Flag), make(map[string]*Flag), os.Args[1:]}
+// Parse parses the command-line flags from os.Args[1:].  Must be called
+// after all flags are defined and before flags are accessed by the program.
+func Parse() {
+	// Ignore errors; commandLine is set for ExitOnError.
+	commandLine.Parse(os.Args[1:])
+}
+
+// The default set of command-line flags, parsed from os.Args.
+var commandLine = NewFlagSet(os.Args[0], ExitOnError)
+
+// 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,
+		actual:        make(map[string]*Flag),
+		formal:        make(map[string]*Flag),
+		errorHandling: errorHandling,
+	}
+	f.Usage = func() { defaultUsage(f) }
+	return f
 }
diff --git a/src/pkg/flag/flag_test.go b/src/pkg/flag/flag_test.go
index 1e47d12..fbd7069 100644
--- a/src/pkg/flag/flag_test.go
+++ b/src/pkg/flag/flag_test.go
@@ -89,7 +89,7 @@
 func TestUsage(t *testing.T) {
 	called := false
 	ResetForTesting(func() { called = true })
-	if ParseForTesting([]string{"a.out", "-x"}) {
+	if CommandLine().Parse([]string{"-x"}) == nil {
 		t.Error("parse did not fail for unknown flag")
 	}
 	if !called {
@@ -97,19 +97,17 @@
 	}
 }
 
-func TestParse(t *testing.T) {
-	ResetForTesting(func() { t.Error("bad parse") })
-	boolFlag := Bool("bool", false, "bool value")
-	bool2Flag := Bool("bool2", false, "bool2 value")
-	intFlag := Int("int", 0, "int value")
-	int64Flag := Int64("int64", 0, "int64 value")
-	uintFlag := Uint("uint", 0, "uint value")
-	uint64Flag := Uint64("uint64", 0, "uint64 value")
-	stringFlag := String("string", "0", "string value")
-	float64Flag := Float64("float64", 0, "float64 value")
+func testParse(f *FlagSet, t *testing.T) {
+	boolFlag := f.Bool("bool", false, "bool value")
+	bool2Flag := f.Bool("bool2", false, "bool2 value")
+	intFlag := f.Int("int", 0, "int value")
+	int64Flag := f.Int64("int64", 0, "int64 value")
+	uintFlag := f.Uint("uint", 0, "uint value")
+	uint64Flag := f.Uint64("uint64", 0, "uint64 value")
+	stringFlag := f.String("string", "0", "string value")
+	float64Flag := f.Float64("float64", 0, "float64 value")
 	extra := "one-extra-argument"
 	args := []string{
-		"a.out",
 		"-bool",
 		"-bool2=true",
 		"--int", "22",
@@ -120,8 +118,8 @@
 		"-float64", "2718e28",
 		extra,
 	}
-	if !ParseForTesting(args) {
-		t.Fatal("parse failed")
+	if err := f.Parse(args); err != nil {
+		t.Fatal(err)
 	}
 	if *boolFlag != true {
 		t.Error("bool flag should be true, is ", *boolFlag)
@@ -147,14 +145,23 @@
 	if *float64Flag != 2718e28 {
 		t.Error("float64 flag should be 2718e28, is ", *float64Flag)
 	}
-	if len(Args()) != 1 {
-		t.Error("expected one argument, got", len(Args()))
-	} else if Args()[0] != extra {
-		t.Errorf("expected argument %q got %q", extra, Args()[0])
+	if len(f.Args()) != 1 {
+		t.Error("expected one argument, got", len(f.Args()))
+	} else if f.Args()[0] != extra {
+		t.Errorf("expected argument %q got %q", extra, f.Args()[0])
 	}
 }
 
-// Declare a user-defined flag.
+func TestParse(t *testing.T) {
+	ResetForTesting(func() { t.Error("bad parse") })
+	testParse(CommandLine(), t)
+}
+
+func TestFlagSetParse(t *testing.T) {
+	testParse(NewFlagSet("test", ContinueOnError), t)
+}
+
+// Declare a user-defined flag type.
 type flagVar []string
 
 func (f *flagVar) String() string {
@@ -167,11 +174,11 @@
 }
 
 func TestUserDefined(t *testing.T) {
-	ResetForTesting(func() { t.Fatal("bad parse") })
+	flags := NewFlagSet("test", ContinueOnError)
 	var v flagVar
-	Var(&v, "v", "usage")
-	if !ParseForTesting([]string{"a.out", "-v", "1", "-v", "2", "-v=3"}) {
-		t.Error("parse failed")
+	flags.Var(&v, "v", "usage")
+	if err := flags.Parse([]string{"-v", "1", "-v", "2", "-v=3"}); err != nil {
+		t.Error(err)
 	}
 	if len(v) != 3 {
 		t.Fatal("expected 3 args; got ", len(v))
@@ -182,13 +189,17 @@
 	}
 }
 
+// This tests that one can reset the flags. This still works but not well, and is
+// superseded by FlagSet.
 func TestChangingArgs(t *testing.T) {
 	ResetForTesting(func() { t.Fatal("bad parse") })
 	oldArgs := os.Args
 	defer func() { os.Args = oldArgs }()
 	os.Args = []string{"cmd", "-before", "subcmd", "-after", "args"}
 	before := Bool("before", false, "")
-	Parse()
+	if err := CommandLine().Parse(os.Args[1:]); err != nil {
+		t.Fatal(err)
+	}
 	cmd := Arg(0)
 	os.Args = Args()
 	after := Bool("after", false, "")