Run Format

Source file src/pkg/flag/flag.go

     1	// Copyright 2009 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	/*
     6		Package flag implements command-line flag parsing.
     7	
     8		Usage:
     9	
    10		Define flags using flag.String(), Bool(), Int(), etc.
    11	
    12		This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
    13			import "flag"
    14			var ip = flag.Int("flagname", 1234, "help message for flagname")
    15		If you like, you can bind the flag to a variable using the Var() functions.
    16			var flagvar int
    17			func init() {
    18				flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
    19			}
    20		Or you can create custom flags that satisfy the Value interface (with
    21		pointer receivers) and couple them to flag parsing by
    22			flag.Var(&flagVal, "name", "help message for flagname")
    23		For such flags, the default value is just the initial value of the variable.
    24	
    25		After all flags are defined, call
    26			flag.Parse()
    27		to parse the command line into the defined flags.
    28	
    29		Flags may then be used directly. If you're using the flags themselves,
    30		they are all pointers; if you bind to variables, they're values.
    31			fmt.Println("ip has value ", *ip)
    32			fmt.Println("flagvar has value ", flagvar)
    33	
    34		After parsing, the arguments after the flag are available as the
    35		slice flag.Args() or individually as flag.Arg(i).
    36		The arguments are indexed from 0 through flag.NArg()-1.
    37	
    38		Command line flag syntax:
    39			-flag
    40			-flag=x
    41			-flag x  // non-boolean flags only
    42		One or two minus signs may be used; they are equivalent.
    43		The last form is not permitted for boolean flags because the
    44		meaning of the command
    45			cmd -x *
    46		will change if there is a file called 0, false, etc.  You must
    47		use the -flag=false form to turn off a boolean flag.
    48	
    49		Flag parsing stops just before the first non-flag argument
    50		("-" is a non-flag argument) or after the terminator "--".
    51	
    52		Integer flags accept 1234, 0664, 0x1234 and may be negative.
    53		Boolean flags may be 1, 0, t, f, true, false, TRUE, FALSE, True, False.
    54		Duration flags accept any input valid for time.ParseDuration.
    55	
    56		The default set of command-line flags is controlled by
    57		top-level functions.  The FlagSet type allows one to define
    58		independent sets of flags, such as to implement subcommands
    59		in a command-line interface. The methods of FlagSet are
    60		analogous to the top-level functions for the command-line
    61		flag set.
    62	*/
    63	package flag
    64	
    65	import (
    66		"errors"
    67		"fmt"
    68		"io"
    69		"os"
    70		"sort"
    71		"strconv"
    72		"time"
    73	)
    74	
    75	// ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
    76	var ErrHelp = errors.New("flag: help requested")
    77	
    78	// -- bool Value
    79	type boolValue bool
    80	
    81	func newBoolValue(val bool, p *bool) *boolValue {
    82		*p = val
    83		return (*boolValue)(p)
    84	}
    85	
    86	func (b *boolValue) Set(s string) error {
    87		v, err := strconv.ParseBool(s)
    88		*b = boolValue(v)
    89		return err
    90	}
    91	
    92	func (b *boolValue) String() string { return fmt.Sprintf("%v", *b) }
    93	
    94	func (b *boolValue) IsBoolFlag() bool { return true }
    95	
    96	// optional interface to indicate boolean flags that can be
    97	// supplied without "=value" text
    98	type boolFlag interface {
    99		Value
   100		IsBoolFlag() bool
   101	}
   102	
   103	// -- int Value
   104	type intValue int
   105	
   106	func newIntValue(val int, p *int) *intValue {
   107		*p = val
   108		return (*intValue)(p)
   109	}
   110	
   111	func (i *intValue) Set(s string) error {
   112		v, err := strconv.ParseInt(s, 0, 64)
   113		*i = intValue(v)
   114		return err
   115	}
   116	
   117	func (i *intValue) String() string { return fmt.Sprintf("%v", *i) }
   118	
   119	// -- int64 Value
   120	type int64Value int64
   121	
   122	func newInt64Value(val int64, p *int64) *int64Value {
   123		*p = val
   124		return (*int64Value)(p)
   125	}
   126	
   127	func (i *int64Value) Set(s string) error {
   128		v, err := strconv.ParseInt(s, 0, 64)
   129		*i = int64Value(v)
   130		return err
   131	}
   132	
   133	func (i *int64Value) String() string { return fmt.Sprintf("%v", *i) }
   134	
   135	// -- uint Value
   136	type uintValue uint
   137	
   138	func newUintValue(val uint, p *uint) *uintValue {
   139		*p = val
   140		return (*uintValue)(p)
   141	}
   142	
   143	func (i *uintValue) Set(s string) error {
   144		v, err := strconv.ParseUint(s, 0, 64)
   145		*i = uintValue(v)
   146		return err
   147	}
   148	
   149	func (i *uintValue) String() string { return fmt.Sprintf("%v", *i) }
   150	
   151	// -- uint64 Value
   152	type uint64Value uint64
   153	
   154	func newUint64Value(val uint64, p *uint64) *uint64Value {
   155		*p = val
   156		return (*uint64Value)(p)
   157	}
   158	
   159	func (i *uint64Value) Set(s string) error {
   160		v, err := strconv.ParseUint(s, 0, 64)
   161		*i = uint64Value(v)
   162		return err
   163	}
   164	
   165	func (i *uint64Value) String() string { return fmt.Sprintf("%v", *i) }
   166	
   167	// -- string Value
   168	type stringValue string
   169	
   170	func newStringValue(val string, p *string) *stringValue {
   171		*p = val
   172		return (*stringValue)(p)
   173	}
   174	
   175	func (s *stringValue) Set(val string) error {
   176		*s = stringValue(val)
   177		return nil
   178	}
   179	
   180	func (s *stringValue) String() string { return fmt.Sprintf("%s", *s) }
   181	
   182	// -- float64 Value
   183	type float64Value float64
   184	
   185	func newFloat64Value(val float64, p *float64) *float64Value {
   186		*p = val
   187		return (*float64Value)(p)
   188	}
   189	
   190	func (f *float64Value) Set(s string) error {
   191		v, err := strconv.ParseFloat(s, 64)
   192		*f = float64Value(v)
   193		return err
   194	}
   195	
   196	func (f *float64Value) String() string { return fmt.Sprintf("%v", *f) }
   197	
   198	// -- time.Duration Value
   199	type durationValue time.Duration
   200	
   201	func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
   202		*p = val
   203		return (*durationValue)(p)
   204	}
   205	
   206	func (d *durationValue) Set(s string) error {
   207		v, err := time.ParseDuration(s)
   208		*d = durationValue(v)
   209		return err
   210	}
   211	
   212	func (d *durationValue) String() string { return (*time.Duration)(d).String() }
   213	
   214	// Value is the interface to the dynamic value stored in a flag.
   215	// (The default value is represented as a string.)
   216	//
   217	// If a Value has an IsBoolFlag() bool method returning true,
   218	// the command-line parser makes -name equivalent to -name=true
   219	// rather than using the next command-line argument.
   220	type Value interface {
   221		String() string
   222		Set(string) error
   223	}
   224	
   225	// ErrorHandling defines how to handle flag parsing errors.
   226	type ErrorHandling int
   227	
   228	const (
   229		ContinueOnError ErrorHandling = iota
   230		ExitOnError
   231		PanicOnError
   232	)
   233	
   234	// A FlagSet represents a set of defined flags.
   235	type FlagSet struct {
   236		// Usage is the function called when an error occurs while parsing flags.
   237		// The field is a function (not a method) that may be changed to point to
   238		// a custom error handler.
   239		Usage func()
   240	
   241		name          string
   242		parsed        bool
   243		actual        map[string]*Flag
   244		formal        map[string]*Flag
   245		args          []string // arguments after flags
   246		exitOnError   bool     // does the program exit if there's an error?
   247		errorHandling ErrorHandling
   248		output        io.Writer // nil means stderr; use out() accessor
   249	}
   250	
   251	// A Flag represents the state of a flag.
   252	type Flag struct {
   253		Name     string // name as it appears on command line
   254		Usage    string // help message
   255		Value    Value  // value as set
   256		DefValue string // default value (as text); for usage message
   257	}
   258	
   259	// sortFlags returns the flags as a slice in lexicographical sorted order.
   260	func sortFlags(flags map[string]*Flag) []*Flag {
   261		list := make(sort.StringSlice, len(flags))
   262		i := 0
   263		for _, f := range flags {
   264			list[i] = f.Name
   265			i++
   266		}
   267		list.Sort()
   268		result := make([]*Flag, len(list))
   269		for i, name := range list {
   270			result[i] = flags[name]
   271		}
   272		return result
   273	}
   274	
   275	func (f *FlagSet) out() io.Writer {
   276		if f.output == nil {
   277			return os.Stderr
   278		}
   279		return f.output
   280	}
   281	
   282	// SetOutput sets the destination for usage and error messages.
   283	// If output is nil, os.Stderr is used.
   284	func (f *FlagSet) SetOutput(output io.Writer) {
   285		f.output = output
   286	}
   287	
   288	// VisitAll visits the flags in lexicographical order, calling fn for each.
   289	// It visits all flags, even those not set.
   290	func (f *FlagSet) VisitAll(fn func(*Flag)) {
   291		for _, flag := range sortFlags(f.formal) {
   292			fn(flag)
   293		}
   294	}
   295	
   296	// VisitAll visits the command-line flags in lexicographical order, calling
   297	// fn for each.  It visits all flags, even those not set.
   298	func VisitAll(fn func(*Flag)) {
   299		commandLine.VisitAll(fn)
   300	}
   301	
   302	// Visit visits the flags in lexicographical order, calling fn for each.
   303	// It visits only those flags that have been set.
   304	func (f *FlagSet) Visit(fn func(*Flag)) {
   305		for _, flag := range sortFlags(f.actual) {
   306			fn(flag)
   307		}
   308	}
   309	
   310	// Visit visits the command-line flags in lexicographical order, calling fn
   311	// for each.  It visits only those flags that have been set.
   312	func Visit(fn func(*Flag)) {
   313		commandLine.Visit(fn)
   314	}
   315	
   316	// Lookup returns the Flag structure of the named flag, returning nil if none exists.
   317	func (f *FlagSet) Lookup(name string) *Flag {
   318		return f.formal[name]
   319	}
   320	
   321	// Lookup returns the Flag structure of the named command-line flag,
   322	// returning nil if none exists.
   323	func Lookup(name string) *Flag {
   324		return commandLine.formal[name]
   325	}
   326	
   327	// Set sets the value of the named flag.
   328	func (f *FlagSet) Set(name, value string) error {
   329		flag, ok := f.formal[name]
   330		if !ok {
   331			return fmt.Errorf("no such flag -%v", name)
   332		}
   333		err := flag.Value.Set(value)
   334		if err != nil {
   335			return err
   336		}
   337		if f.actual == nil {
   338			f.actual = make(map[string]*Flag)
   339		}
   340		f.actual[name] = flag
   341		return nil
   342	}
   343	
   344	// Set sets the value of the named command-line flag.
   345	func Set(name, value string) error {
   346		return commandLine.Set(name, value)
   347	}
   348	
   349	// PrintDefaults prints, to standard error unless configured
   350	// otherwise, the default values of all defined flags in the set.
   351	func (f *FlagSet) PrintDefaults() {
   352		f.VisitAll(func(flag *Flag) {
   353			format := "  -%s=%s: %s\n"
   354			if _, ok := flag.Value.(*stringValue); ok {
   355				// put quotes on the value
   356				format = "  -%s=%q: %s\n"
   357			}
   358			fmt.Fprintf(f.out(), format, flag.Name, flag.DefValue, flag.Usage)
   359		})
   360	}
   361	
   362	// PrintDefaults prints to standard error the default values of all defined command-line flags.
   363	func PrintDefaults() {
   364		commandLine.PrintDefaults()
   365	}
   366	
   367	// defaultUsage is the default function to print a usage message.
   368	func defaultUsage(f *FlagSet) {
   369		fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
   370		f.PrintDefaults()
   371	}
   372	
   373	// NOTE: Usage is not just defaultUsage(commandLine)
   374	// because it serves (via godoc flag Usage) as the example
   375	// for how to write your own usage function.
   376	
   377	// Usage prints to standard error a usage message documenting all defined command-line flags.
   378	// The function is a variable that may be changed to point to a custom function.
   379	var Usage = func() {
   380		fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
   381		PrintDefaults()
   382	}
   383	
   384	// NFlag returns the number of flags that have been set.
   385	func (f *FlagSet) NFlag() int { return len(f.actual) }
   386	
   387	// NFlag returns the number of command-line flags that have been set.
   388	func NFlag() int { return len(commandLine.actual) }
   389	
   390	// Arg returns the i'th argument.  Arg(0) is the first remaining argument
   391	// after flags have been processed.
   392	func (f *FlagSet) Arg(i int) string {
   393		if i < 0 || i >= len(f.args) {
   394			return ""
   395		}
   396		return f.args[i]
   397	}
   398	
   399	// Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
   400	// after flags have been processed.
   401	func Arg(i int) string {
   402		return commandLine.Arg(i)
   403	}
   404	
   405	// NArg is the number of arguments remaining after flags have been processed.
   406	func (f *FlagSet) NArg() int { return len(f.args) }
   407	
   408	// NArg is the number of arguments remaining after flags have been processed.
   409	func NArg() int { return len(commandLine.args) }
   410	
   411	// Args returns the non-flag arguments.
   412	func (f *FlagSet) Args() []string { return f.args }
   413	
   414	// Args returns the non-flag command-line arguments.
   415	func Args() []string { return commandLine.args }
   416	
   417	// BoolVar defines a bool flag with specified name, default value, and usage string.
   418	// The argument p points to a bool variable in which to store the value of the flag.
   419	func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
   420		f.Var(newBoolValue(value, p), name, usage)
   421	}
   422	
   423	// BoolVar defines a bool flag with specified name, default value, and usage string.
   424	// The argument p points to a bool variable in which to store the value of the flag.
   425	func BoolVar(p *bool, name string, value bool, usage string) {
   426		commandLine.Var(newBoolValue(value, p), name, usage)
   427	}
   428	
   429	// Bool defines a bool flag with specified name, default value, and usage string.
   430	// The return value is the address of a bool variable that stores the value of the flag.
   431	func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
   432		p := new(bool)
   433		f.BoolVar(p, name, value, usage)
   434		return p
   435	}
   436	
   437	// Bool defines a bool flag with specified name, default value, and usage string.
   438	// The return value is the address of a bool variable that stores the value of the flag.
   439	func Bool(name string, value bool, usage string) *bool {
   440		return commandLine.Bool(name, value, usage)
   441	}
   442	
   443	// IntVar defines an int flag with specified name, default value, and usage string.
   444	// The argument p points to an int variable in which to store the value of the flag.
   445	func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
   446		f.Var(newIntValue(value, p), name, usage)
   447	}
   448	
   449	// IntVar defines an int flag with specified name, default value, and usage string.
   450	// The argument p points to an int variable in which to store the value of the flag.
   451	func IntVar(p *int, name string, value int, usage string) {
   452		commandLine.Var(newIntValue(value, p), name, usage)
   453	}
   454	
   455	// Int defines an int flag with specified name, default value, and usage string.
   456	// The return value is the address of an int variable that stores the value of the flag.
   457	func (f *FlagSet) Int(name string, value int, usage string) *int {
   458		p := new(int)
   459		f.IntVar(p, name, value, usage)
   460		return p
   461	}
   462	
   463	// Int defines an int flag with specified name, default value, and usage string.
   464	// The return value is the address of an int variable that stores the value of the flag.
   465	func Int(name string, value int, usage string) *int {
   466		return commandLine.Int(name, value, usage)
   467	}
   468	
   469	// Int64Var defines an int64 flag with specified name, default value, and usage string.
   470	// The argument p points to an int64 variable in which to store the value of the flag.
   471	func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {
   472		f.Var(newInt64Value(value, p), name, usage)
   473	}
   474	
   475	// Int64Var defines an int64 flag with specified name, default value, and usage string.
   476	// The argument p points to an int64 variable in which to store the value of the flag.
   477	func Int64Var(p *int64, name string, value int64, usage string) {
   478		commandLine.Var(newInt64Value(value, p), name, usage)
   479	}
   480	
   481	// Int64 defines an int64 flag with specified name, default value, and usage string.
   482	// The return value is the address of an int64 variable that stores the value of the flag.
   483	func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
   484		p := new(int64)
   485		f.Int64Var(p, name, value, usage)
   486		return p
   487	}
   488	
   489	// Int64 defines an int64 flag with specified name, default value, and usage string.
   490	// The return value is the address of an int64 variable that stores the value of the flag.
   491	func Int64(name string, value int64, usage string) *int64 {
   492		return commandLine.Int64(name, value, usage)
   493	}
   494	
   495	// UintVar defines a uint flag with specified name, default value, and usage string.
   496	// The argument p points to a uint variable in which to store the value of the flag.
   497	func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
   498		f.Var(newUintValue(value, p), name, usage)
   499	}
   500	
   501	// UintVar defines a uint flag with specified name, default value, and usage string.
   502	// The argument p points to a uint  variable in which to store the value of the flag.
   503	func UintVar(p *uint, name string, value uint, usage string) {
   504		commandLine.Var(newUintValue(value, p), name, usage)
   505	}
   506	
   507	// Uint defines a uint flag with specified name, default value, and usage string.
   508	// The return value is the address of a uint  variable that stores the value of the flag.
   509	func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
   510		p := new(uint)
   511		f.UintVar(p, name, value, usage)
   512		return p
   513	}
   514	
   515	// Uint defines a uint flag with specified name, default value, and usage string.
   516	// The return value is the address of a uint  variable that stores the value of the flag.
   517	func Uint(name string, value uint, usage string) *uint {
   518		return commandLine.Uint(name, value, usage)
   519	}
   520	
   521	// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
   522	// The argument p points to a uint64 variable in which to store the value of the flag.
   523	func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
   524		f.Var(newUint64Value(value, p), name, usage)
   525	}
   526	
   527	// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
   528	// The argument p points to a uint64 variable in which to store the value of the flag.
   529	func Uint64Var(p *uint64, name string, value uint64, usage string) {
   530		commandLine.Var(newUint64Value(value, p), name, usage)
   531	}
   532	
   533	// Uint64 defines a uint64 flag with specified name, default value, and usage string.
   534	// The return value is the address of a uint64 variable that stores the value of the flag.
   535	func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
   536		p := new(uint64)
   537		f.Uint64Var(p, name, value, usage)
   538		return p
   539	}
   540	
   541	// Uint64 defines a uint64 flag with specified name, default value, and usage string.
   542	// The return value is the address of a uint64 variable that stores the value of the flag.
   543	func Uint64(name string, value uint64, usage string) *uint64 {
   544		return commandLine.Uint64(name, value, usage)
   545	}
   546	
   547	// StringVar defines a string flag with specified name, default value, and usage string.
   548	// The argument p points to a string variable in which to store the value of the flag.
   549	func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
   550		f.Var(newStringValue(value, p), name, usage)
   551	}
   552	
   553	// StringVar defines a string flag with specified name, default value, and usage string.
   554	// The argument p points to a string variable in which to store the value of the flag.
   555	func StringVar(p *string, name string, value string, usage string) {
   556		commandLine.Var(newStringValue(value, p), name, usage)
   557	}
   558	
   559	// String defines a string flag with specified name, default value, and usage string.
   560	// The return value is the address of a string variable that stores the value of the flag.
   561	func (f *FlagSet) String(name string, value string, usage string) *string {
   562		p := new(string)
   563		f.StringVar(p, name, value, usage)
   564		return p
   565	}
   566	
   567	// String defines a string flag with specified name, default value, and usage string.
   568	// The return value is the address of a string variable that stores the value of the flag.
   569	func String(name string, value string, usage string) *string {
   570		return commandLine.String(name, value, usage)
   571	}
   572	
   573	// Float64Var defines a float64 flag with specified name, default value, and usage string.
   574	// The argument p points to a float64 variable in which to store the value of the flag.
   575	func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) {
   576		f.Var(newFloat64Value(value, p), name, usage)
   577	}
   578	
   579	// Float64Var defines a float64 flag with specified name, default value, and usage string.
   580	// The argument p points to a float64 variable in which to store the value of the flag.
   581	func Float64Var(p *float64, name string, value float64, usage string) {
   582		commandLine.Var(newFloat64Value(value, p), name, usage)
   583	}
   584	
   585	// Float64 defines a float64 flag with specified name, default value, and usage string.
   586	// The return value is the address of a float64 variable that stores the value of the flag.
   587	func (f *FlagSet) Float64(name string, value float64, usage string) *float64 {
   588		p := new(float64)
   589		f.Float64Var(p, name, value, usage)
   590		return p
   591	}
   592	
   593	// Float64 defines a float64 flag with specified name, default value, and usage string.
   594	// The return value is the address of a float64 variable that stores the value of the flag.
   595	func Float64(name string, value float64, usage string) *float64 {
   596		return commandLine.Float64(name, value, usage)
   597	}
   598	
   599	// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
   600	// The argument p points to a time.Duration variable in which to store the value of the flag.
   601	func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
   602		f.Var(newDurationValue(value, p), name, usage)
   603	}
   604	
   605	// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
   606	// The argument p points to a time.Duration variable in which to store the value of the flag.
   607	func DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
   608		commandLine.Var(newDurationValue(value, p), name, usage)
   609	}
   610	
   611	// Duration defines a time.Duration flag with specified name, default value, and usage string.
   612	// The return value is the address of a time.Duration variable that stores the value of the flag.
   613	func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration {
   614		p := new(time.Duration)
   615		f.DurationVar(p, name, value, usage)
   616		return p
   617	}
   618	
   619	// Duration defines a time.Duration flag with specified name, default value, and usage string.
   620	// The return value is the address of a time.Duration variable that stores the value of the flag.
   621	func Duration(name string, value time.Duration, usage string) *time.Duration {
   622		return commandLine.Duration(name, value, usage)
   623	}
   624	
   625	// Var defines a flag with the specified name and usage string. The type and
   626	// value of the flag are represented by the first argument, of type Value, which
   627	// typically holds a user-defined implementation of Value. For instance, the
   628	// caller could create a flag that turns a comma-separated string into a slice
   629	// of strings by giving the slice the methods of Value; in particular, Set would
   630	// decompose the comma-separated string into the slice.
   631	func (f *FlagSet) Var(value Value, name string, usage string) {
   632		// Remember the default value as a string; it won't change.
   633		flag := &Flag{name, usage, value, value.String()}
   634		_, alreadythere := f.formal[name]
   635		if alreadythere {
   636			msg := fmt.Sprintf("%s flag redefined: %s", f.name, name)
   637			fmt.Fprintln(f.out(), msg)
   638			panic(msg) // Happens only if flags are declared with identical names
   639		}
   640		if f.formal == nil {
   641			f.formal = make(map[string]*Flag)
   642		}
   643		f.formal[name] = flag
   644	}
   645	
   646	// Var defines a flag with the specified name and usage string. The type and
   647	// value of the flag are represented by the first argument, of type Value, which
   648	// typically holds a user-defined implementation of Value. For instance, the
   649	// caller could create a flag that turns a comma-separated string into a slice
   650	// of strings by giving the slice the methods of Value; in particular, Set would
   651	// decompose the comma-separated string into the slice.
   652	func Var(value Value, name string, usage string) {
   653		commandLine.Var(value, name, usage)
   654	}
   655	
   656	// failf prints to standard error a formatted error and usage message and
   657	// returns the error.
   658	func (f *FlagSet) failf(format string, a ...interface{}) error {
   659		err := fmt.Errorf(format, a...)
   660		fmt.Fprintln(f.out(), err)
   661		f.usage()
   662		return err
   663	}
   664	
   665	// usage calls the Usage method for the flag set, or the usage function if
   666	// the flag set is commandLine.
   667	func (f *FlagSet) usage() {
   668		if f == commandLine {
   669			Usage()
   670		} else if f.Usage == nil {
   671			defaultUsage(f)
   672		} else {
   673			f.Usage()
   674		}
   675	}
   676	
   677	// parseOne parses one flag. It returns whether a flag was seen.
   678	func (f *FlagSet) parseOne() (bool, error) {
   679		if len(f.args) == 0 {
   680			return false, nil
   681		}
   682		s := f.args[0]
   683		if len(s) == 0 || s[0] != '-' || len(s) == 1 {
   684			return false, nil
   685		}
   686		num_minuses := 1
   687		if s[1] == '-' {
   688			num_minuses++
   689			if len(s) == 2 { // "--" terminates the flags
   690				f.args = f.args[1:]
   691				return false, nil
   692			}
   693		}
   694		name := s[num_minuses:]
   695		if len(name) == 0 || name[0] == '-' || name[0] == '=' {
   696			return false, f.failf("bad flag syntax: %s", s)
   697		}
   698	
   699		// it's a flag. does it have an argument?
   700		f.args = f.args[1:]
   701		has_value := false
   702		value := ""
   703		for i := 1; i < len(name); i++ { // equals cannot be first
   704			if name[i] == '=' {
   705				value = name[i+1:]
   706				has_value = true
   707				name = name[0:i]
   708				break
   709			}
   710		}
   711		m := f.formal
   712		flag, alreadythere := m[name] // BUG
   713		if !alreadythere {
   714			if name == "help" || name == "h" { // special case for nice help message.
   715				f.usage()
   716				return false, ErrHelp
   717			}
   718			return false, f.failf("flag provided but not defined: -%s", name)
   719		}
   720		if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
   721			if has_value {
   722				if err := fv.Set(value); err != nil {
   723					return false, f.failf("invalid boolean value %q for  -%s: %v", value, name, err)
   724				}
   725			} else {
   726				fv.Set("true")
   727			}
   728		} else {
   729			// It must have a value, which might be the next argument.
   730			if !has_value && len(f.args) > 0 {
   731				// value is the next arg
   732				has_value = true
   733				value, f.args = f.args[0], f.args[1:]
   734			}
   735			if !has_value {
   736				return false, f.failf("flag needs an argument: -%s", name)
   737			}
   738			if err := flag.Value.Set(value); err != nil {
   739				return false, f.failf("invalid value %q for flag -%s: %v", value, name, err)
   740			}
   741		}
   742		if f.actual == nil {
   743			f.actual = make(map[string]*Flag)
   744		}
   745		f.actual[name] = flag
   746		return true, nil
   747	}
   748	
   749	// Parse parses flag definitions from the argument list, which should not
   750	// include the command name.  Must be called after all flags in the FlagSet
   751	// are defined and before flags are accessed by the program.
   752	// The return value will be ErrHelp if -help was set but not defined.
   753	func (f *FlagSet) Parse(arguments []string) error {
   754		f.parsed = true
   755		f.args = arguments
   756		for {
   757			seen, err := f.parseOne()
   758			if seen {
   759				continue
   760			}
   761			if err == nil {
   762				break
   763			}
   764			switch f.errorHandling {
   765			case ContinueOnError:
   766				return err
   767			case ExitOnError:
   768				os.Exit(2)
   769			case PanicOnError:
   770				panic(err)
   771			}
   772		}
   773		return nil
   774	}
   775	
   776	// Parsed reports whether f.Parse has been called.
   777	func (f *FlagSet) Parsed() bool {
   778		return f.parsed
   779	}
   780	
   781	// Parse parses the command-line flags from os.Args[1:].  Must be called
   782	// after all flags are defined and before flags are accessed by the program.
   783	func Parse() {
   784		// Ignore errors; commandLine is set for ExitOnError.
   785		commandLine.Parse(os.Args[1:])
   786	}
   787	
   788	// Parsed returns true if the command-line flags have been parsed.
   789	func Parsed() bool {
   790		return commandLine.Parsed()
   791	}
   792	
   793	// The default set of command-line flags, parsed from os.Args.
   794	var commandLine = NewFlagSet(os.Args[0], ExitOnError)
   795	
   796	// NewFlagSet returns a new, empty flag set with the specified name and
   797	// error handling property.
   798	func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
   799		f := &FlagSet{
   800			name:          name,
   801			errorHandling: errorHandling,
   802		}
   803		return f
   804	}
   805	
   806	// Init sets the name and error handling property for a flag set.
   807	// By default, the zero FlagSet uses an empty name and the
   808	// ContinueOnError error handling policy.
   809	func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
   810		f.name = name
   811		f.errorHandling = errorHandling
   812	}

View as plain text