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/*
6Package pflag is a drop-in replacement for Go's flag package, implementing
7POSIX/GNU-style --flags.
8
9pflag is compatible with the GNU extensions to the POSIX recommendations
10for command-line options. See
11http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
12
13Usage:
14
15pflag is a drop-in replacement of Go's native flag package. If you import
16pflag under the name "flag" then all code should continue to function
17with no changes.
18
19	import flag "github.com/spf13/pflag"
20
21There is one exception to this: if you directly instantiate the Flag struct
22there is one more field "Shorthand" that you will need to set.
23Most code never instantiates this struct directly, and instead uses
24functions such as String(), BoolVar(), and Var(), and is therefore
25unaffected.
26
27Define flags using flag.String(), Bool(), Int(), etc.
28
29This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
30	var ip = flag.Int("flagname", 1234, "help message for flagname")
31If you like, you can bind the flag to a variable using the Var() functions.
32	var flagvar int
33	func init() {
34		flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
35	}
36Or you can create custom flags that satisfy the Value interface (with
37pointer receivers) and couple them to flag parsing by
38	flag.Var(&flagVal, "name", "help message for flagname")
39For such flags, the default value is just the initial value of the variable.
40
41After all flags are defined, call
42	flag.Parse()
43to parse the command line into the defined flags.
44
45Flags may then be used directly. If you're using the flags themselves,
46they are all pointers; if you bind to variables, they're values.
47	fmt.Println("ip has value ", *ip)
48	fmt.Println("flagvar has value ", flagvar)
49
50After parsing, the arguments after the flag are available as the
51slice flag.Args() or individually as flag.Arg(i).
52The arguments are indexed from 0 through flag.NArg()-1.
53
54The pflag package also defines some new functions that are not in flag,
55that give one-letter shorthands for flags. You can use these by appending
56'P' to the name of any function that defines a flag.
57	var ip = flag.IntP("flagname", "f", 1234, "help message")
58	var flagvar bool
59	func init() {
60		flag.BoolVarP("boolname", "b", true, "help message")
61	}
62	flag.VarP(&flagVar, "varname", "v", 1234, "help message")
63Shorthand letters can be used with single dashes on the command line.
64Boolean shorthand flags can be combined with other shorthand flags.
65
66Command line flag syntax:
67	--flag    // boolean flags only
68	--flag=x
69
70Unlike the flag package, a single dash before an option means something
71different than a double dash. Single dashes signify a series of shorthand
72letters for flags. All but the last shorthand letter must be boolean flags.
73	// boolean flags
74	-f
75	-abc
76	// non-boolean flags
77	-n 1234
78	-Ifile
79	// mixed
80	-abcs "hello"
81	-abcn1234
82
83Flag parsing stops after the terminator "--". Unlike the flag package,
84flags can be interspersed with arguments anywhere on the command line
85before this terminator.
86
87Integer flags accept 1234, 0664, 0x1234 and may be negative.
88Boolean flags (in their long form) accept 1, 0, t, f, true, false,
89TRUE, FALSE, True, False.
90Duration flags accept any input valid for time.ParseDuration.
91
92The default set of command-line flags is controlled by
93top-level functions.  The FlagSet type allows one to define
94independent sets of flags, such as to implement subcommands
95in a command-line interface. The methods of FlagSet are
96analogous to the top-level functions for the command-line
97flag set.
98*/
99package pflag
100
101import (
102	"bytes"
103	"errors"
104	goflag "flag"
105	"fmt"
106	"io"
107	"os"
108	"sort"
109	"strings"
110)
111
112// ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
113var ErrHelp = errors.New("pflag: help requested")
114
115// ErrorHandling defines how to handle flag parsing errors.
116type ErrorHandling int
117
118const (
119	// ContinueOnError will return an err from Parse() if an error is found
120	ContinueOnError ErrorHandling = iota
121	// ExitOnError will call os.Exit(2) if an error is found when parsing
122	ExitOnError
123	// PanicOnError will panic() if an error is found when parsing flags
124	PanicOnError
125)
126
127// ParseErrorsWhitelist defines the parsing errors that can be ignored
128type ParseErrorsWhitelist struct {
129	// UnknownFlags will ignore unknown flags errors and continue parsing rest of the flags
130	UnknownFlags bool
131}
132
133// NormalizedName is a flag name that has been normalized according to rules
134// for the FlagSet (e.g. making '-' and '_' equivalent).
135type NormalizedName string
136
137// A FlagSet represents a set of defined flags.
138type FlagSet struct {
139	// Usage is the function called when an error occurs while parsing flags.
140	// The field is a function (not a method) that may be changed to point to
141	// a custom error handler.
142	Usage func()
143
144	// SortFlags is used to indicate, if user wants to have sorted flags in
145	// help/usage messages.
146	SortFlags bool
147
148	// ParseErrorsWhitelist is used to configure a whitelist of errors
149	ParseErrorsWhitelist ParseErrorsWhitelist
150
151	name              string
152	parsed            bool
153	actual            map[NormalizedName]*Flag
154	orderedActual     []*Flag
155	sortedActual      []*Flag
156	formal            map[NormalizedName]*Flag
157	orderedFormal     []*Flag
158	sortedFormal      []*Flag
159	shorthands        map[byte]*Flag
160	args              []string // arguments after flags
161	argsLenAtDash     int      // len(args) when a '--' was located when parsing, or -1 if no --
162	errorHandling     ErrorHandling
163	output            io.Writer // nil means stderr; use out() accessor
164	interspersed      bool      // allow interspersed option/non-option args
165	normalizeNameFunc func(f *FlagSet, name string) NormalizedName
166
167	addedGoFlagSets []*goflag.FlagSet
168}
169
170// A Flag represents the state of a flag.
171type Flag struct {
172	Name                string              // name as it appears on command line
173	Shorthand           string              // one-letter abbreviated flag
174	Usage               string              // help message
175	Value               Value               // value as set
176	DefValue            string              // default value (as text); for usage message
177	Changed             bool                // If the user set the value (or if left to default)
178	NoOptDefVal         string              // default value (as text); if the flag is on the command line without any options
179	Deprecated          string              // If this flag is deprecated, this string is the new or now thing to use
180	Hidden              bool                // used by cobra.Command to allow flags to be hidden from help/usage text
181	ShorthandDeprecated string              // If the shorthand of this flag is deprecated, this string is the new or now thing to use
182	Annotations         map[string][]string // used by cobra.Command bash autocomple code
183}
184
185// Value is the interface to the dynamic value stored in a flag.
186// (The default value is represented as a string.)
187type Value interface {
188	String() string
189	Set(string) error
190	Type() string
191}
192
193// sortFlags returns the flags as a slice in lexicographical sorted order.
194func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
195	list := make(sort.StringSlice, len(flags))
196	i := 0
197	for k := range flags {
198		list[i] = string(k)
199		i++
200	}
201	list.Sort()
202	result := make([]*Flag, len(list))
203	for i, name := range list {
204		result[i] = flags[NormalizedName(name)]
205	}
206	return result
207}
208
209// SetNormalizeFunc allows you to add a function which can translate flag names.
210// Flags added to the FlagSet will be translated and then when anything tries to
211// look up the flag that will also be translated. So it would be possible to create
212// a flag named "getURL" and have it translated to "geturl".  A user could then pass
213// "--getUrl" which may also be translated to "geturl" and everything will work.
214func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
215	f.normalizeNameFunc = n
216	f.sortedFormal = f.sortedFormal[:0]
217	for fname, flag := range f.formal {
218		nname := f.normalizeFlagName(flag.Name)
219		if fname == nname {
220			continue
221		}
222		flag.Name = string(nname)
223		delete(f.formal, fname)
224		f.formal[nname] = flag
225		if _, set := f.actual[fname]; set {
226			delete(f.actual, fname)
227			f.actual[nname] = flag
228		}
229	}
230}
231
232// GetNormalizeFunc returns the previously set NormalizeFunc of a function which
233// does no translation, if not set previously.
234func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName {
235	if f.normalizeNameFunc != nil {
236		return f.normalizeNameFunc
237	}
238	return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) }
239}
240
241func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
242	n := f.GetNormalizeFunc()
243	return n(f, name)
244}
245
246func (f *FlagSet) out() io.Writer {
247	if f.output == nil {
248		return os.Stderr
249	}
250	return f.output
251}
252
253// SetOutput sets the destination for usage and error messages.
254// If output is nil, os.Stderr is used.
255func (f *FlagSet) SetOutput(output io.Writer) {
256	f.output = output
257}
258
259// VisitAll visits the flags in lexicographical order or
260// in primordial order if f.SortFlags is false, calling fn for each.
261// It visits all flags, even those not set.
262func (f *FlagSet) VisitAll(fn func(*Flag)) {
263	if len(f.formal) == 0 {
264		return
265	}
266
267	var flags []*Flag
268	if f.SortFlags {
269		if len(f.formal) != len(f.sortedFormal) {
270			f.sortedFormal = sortFlags(f.formal)
271		}
272		flags = f.sortedFormal
273	} else {
274		flags = f.orderedFormal
275	}
276
277	for _, flag := range flags {
278		fn(flag)
279	}
280}
281
282// HasFlags returns a bool to indicate if the FlagSet has any flags defined.
283func (f *FlagSet) HasFlags() bool {
284	return len(f.formal) > 0
285}
286
287// HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
288// that are not hidden.
289func (f *FlagSet) HasAvailableFlags() bool {
290	for _, flag := range f.formal {
291		if !flag.Hidden {
292			return true
293		}
294	}
295	return false
296}
297
298// VisitAll visits the command-line flags in lexicographical order or
299// in primordial order if f.SortFlags is false, calling fn for each.
300// It visits all flags, even those not set.
301func VisitAll(fn func(*Flag)) {
302	CommandLine.VisitAll(fn)
303}
304
305// Visit visits the flags in lexicographical order or
306// in primordial order if f.SortFlags is false, calling fn for each.
307// It visits only those flags that have been set.
308func (f *FlagSet) Visit(fn func(*Flag)) {
309	if len(f.actual) == 0 {
310		return
311	}
312
313	var flags []*Flag
314	if f.SortFlags {
315		if len(f.actual) != len(f.sortedActual) {
316			f.sortedActual = sortFlags(f.actual)
317		}
318		flags = f.sortedActual
319	} else {
320		flags = f.orderedActual
321	}
322
323	for _, flag := range flags {
324		fn(flag)
325	}
326}
327
328// Visit visits the command-line flags in lexicographical order or
329// in primordial order if f.SortFlags is false, calling fn for each.
330// It visits only those flags that have been set.
331func Visit(fn func(*Flag)) {
332	CommandLine.Visit(fn)
333}
334
335// Lookup returns the Flag structure of the named flag, returning nil if none exists.
336func (f *FlagSet) Lookup(name string) *Flag {
337	return f.lookup(f.normalizeFlagName(name))
338}
339
340// ShorthandLookup returns the Flag structure of the short handed flag,
341// returning nil if none exists.
342// It panics, if len(name) > 1.
343func (f *FlagSet) ShorthandLookup(name string) *Flag {
344	if name == "" {
345		return nil
346	}
347	if len(name) > 1 {
348		msg := fmt.Sprintf("can not look up shorthand which is more than one ASCII character: %q", name)
349		fmt.Fprintf(f.out(), msg)
350		panic(msg)
351	}
352	c := name[0]
353	return f.shorthands[c]
354}
355
356// lookup returns the Flag structure of the named flag, returning nil if none exists.
357func (f *FlagSet) lookup(name NormalizedName) *Flag {
358	return f.formal[name]
359}
360
361// func to return a given type for a given flag name
362func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) {
363	flag := f.Lookup(name)
364	if flag == nil {
365		err := fmt.Errorf("flag accessed but not defined: %s", name)
366		return nil, err
367	}
368
369	if flag.Value.Type() != ftype {
370		err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type())
371		return nil, err
372	}
373
374	sval := flag.Value.String()
375	result, err := convFunc(sval)
376	if err != nil {
377		return nil, err
378	}
379	return result, nil
380}
381
382// ArgsLenAtDash will return the length of f.Args at the moment when a -- was
383// found during arg parsing. This allows your program to know which args were
384// before the -- and which came after.
385func (f *FlagSet) ArgsLenAtDash() int {
386	return f.argsLenAtDash
387}
388
389// MarkDeprecated indicated that a flag is deprecated in your program. It will
390// continue to function but will not show up in help or usage messages. Using
391// this flag will also print the given usageMessage.
392func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
393	flag := f.Lookup(name)
394	if flag == nil {
395		return fmt.Errorf("flag %q does not exist", name)
396	}
397	if usageMessage == "" {
398		return fmt.Errorf("deprecated message for flag %q must be set", name)
399	}
400	flag.Deprecated = usageMessage
401	flag.Hidden = true
402	return nil
403}
404
405// MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your
406// program. It will continue to function but will not show up in help or usage
407// messages. Using this flag will also print the given usageMessage.
408func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error {
409	flag := f.Lookup(name)
410	if flag == nil {
411		return fmt.Errorf("flag %q does not exist", name)
412	}
413	if usageMessage == "" {
414		return fmt.Errorf("deprecated message for flag %q must be set", name)
415	}
416	flag.ShorthandDeprecated = usageMessage
417	return nil
418}
419
420// MarkHidden sets a flag to 'hidden' in your program. It will continue to
421// function but will not show up in help or usage messages.
422func (f *FlagSet) MarkHidden(name string) error {
423	flag := f.Lookup(name)
424	if flag == nil {
425		return fmt.Errorf("flag %q does not exist", name)
426	}
427	flag.Hidden = true
428	return nil
429}
430
431// Lookup returns the Flag structure of the named command-line flag,
432// returning nil if none exists.
433func Lookup(name string) *Flag {
434	return CommandLine.Lookup(name)
435}
436
437// ShorthandLookup returns the Flag structure of the short handed flag,
438// returning nil if none exists.
439func ShorthandLookup(name string) *Flag {
440	return CommandLine.ShorthandLookup(name)
441}
442
443// Set sets the value of the named flag.
444func (f *FlagSet) Set(name, value string) error {
445	normalName := f.normalizeFlagName(name)
446	flag, ok := f.formal[normalName]
447	if !ok {
448		return fmt.Errorf("no such flag -%v", name)
449	}
450
451	err := flag.Value.Set(value)
452	if err != nil {
453		var flagName string
454		if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
455			flagName = fmt.Sprintf("-%s, --%s", flag.Shorthand, flag.Name)
456		} else {
457			flagName = fmt.Sprintf("--%s", flag.Name)
458		}
459		return fmt.Errorf("invalid argument %q for %q flag: %v", value, flagName, err)
460	}
461
462	if !flag.Changed {
463		if f.actual == nil {
464			f.actual = make(map[NormalizedName]*Flag)
465		}
466		f.actual[normalName] = flag
467		f.orderedActual = append(f.orderedActual, flag)
468
469		flag.Changed = true
470	}
471
472	if flag.Deprecated != "" {
473		fmt.Fprintf(f.out(), "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
474	}
475	return nil
476}
477
478// SetAnnotation allows one to set arbitrary annotations on a flag in the FlagSet.
479// This is sometimes used by spf13/cobra programs which want to generate additional
480// bash completion information.
481func (f *FlagSet) SetAnnotation(name, key string, values []string) error {
482	normalName := f.normalizeFlagName(name)
483	flag, ok := f.formal[normalName]
484	if !ok {
485		return fmt.Errorf("no such flag -%v", name)
486	}
487	if flag.Annotations == nil {
488		flag.Annotations = map[string][]string{}
489	}
490	flag.Annotations[key] = values
491	return nil
492}
493
494// Changed returns true if the flag was explicitly set during Parse() and false
495// otherwise
496func (f *FlagSet) Changed(name string) bool {
497	flag := f.Lookup(name)
498	// If a flag doesn't exist, it wasn't changed....
499	if flag == nil {
500		return false
501	}
502	return flag.Changed
503}
504
505// Set sets the value of the named command-line flag.
506func Set(name, value string) error {
507	return CommandLine.Set(name, value)
508}
509
510// PrintDefaults prints, to standard error unless configured
511// otherwise, the default values of all defined flags in the set.
512func (f *FlagSet) PrintDefaults() {
513	usages := f.FlagUsages()
514	fmt.Fprint(f.out(), usages)
515}
516
517// defaultIsZeroValue returns true if the default value for this flag represents
518// a zero value.
519func (f *Flag) defaultIsZeroValue() bool {
520	switch f.Value.(type) {
521	case boolFlag:
522		return f.DefValue == "false"
523	case *durationValue:
524		// Beginning in Go 1.7, duration zero values are "0s"
525		return f.DefValue == "0" || f.DefValue == "0s"
526	case *intValue, *int8Value, *int32Value, *int64Value, *uintValue, *uint8Value, *uint16Value, *uint32Value, *uint64Value, *countValue, *float32Value, *float64Value:
527		return f.DefValue == "0"
528	case *stringValue:
529		return f.DefValue == ""
530	case *ipValue, *ipMaskValue, *ipNetValue:
531		return f.DefValue == "<nil>"
532	case *intSliceValue, *stringSliceValue, *stringArrayValue:
533		return f.DefValue == "[]"
534	default:
535		switch f.Value.String() {
536		case "false":
537			return true
538		case "<nil>":
539			return true
540		case "":
541			return true
542		case "0":
543			return true
544		}
545		return false
546	}
547}
548
549// UnquoteUsage extracts a back-quoted name from the usage
550// string for a flag and returns it and the un-quoted usage.
551// Given "a `name` to show" it returns ("name", "a name to show").
552// If there are no back quotes, the name is an educated guess of the
553// type of the flag's value, or the empty string if the flag is boolean.
554func UnquoteUsage(flag *Flag) (name string, usage string) {
555	// Look for a back-quoted name, but avoid the strings package.
556	usage = flag.Usage
557	for i := 0; i < len(usage); i++ {
558		if usage[i] == '`' {
559			for j := i + 1; j < len(usage); j++ {
560				if usage[j] == '`' {
561					name = usage[i+1 : j]
562					usage = usage[:i] + name + usage[j+1:]
563					return name, usage
564				}
565			}
566			break // Only one back quote; use type name.
567		}
568	}
569
570	name = flag.Value.Type()
571	switch name {
572	case "bool":
573		name = ""
574	case "float64":
575		name = "float"
576	case "int64":
577		name = "int"
578	case "uint64":
579		name = "uint"
580	case "stringSlice":
581		name = "strings"
582	case "intSlice":
583		name = "ints"
584	case "uintSlice":
585		name = "uints"
586	case "boolSlice":
587		name = "bools"
588	}
589
590	return
591}
592
593// Splits the string `s` on whitespace into an initial substring up to
594// `i` runes in length and the remainder. Will go `slop` over `i` if
595// that encompasses the entire string (which allows the caller to
596// avoid short orphan words on the final line).
597func wrapN(i, slop int, s string) (string, string) {
598	if i+slop > len(s) {
599		return s, ""
600	}
601
602	w := strings.LastIndexAny(s[:i], " \t\n")
603	if w <= 0 {
604		return s, ""
605	}
606	nlPos := strings.LastIndex(s[:i], "\n")
607	if nlPos > 0 && nlPos < w {
608		return s[:nlPos], s[nlPos+1:]
609	}
610	return s[:w], s[w+1:]
611}
612
613// Wraps the string `s` to a maximum width `w` with leading indent
614// `i`. The first line is not indented (this is assumed to be done by
615// caller). Pass `w` == 0 to do no wrapping
616func wrap(i, w int, s string) string {
617	if w == 0 {
618		return strings.Replace(s, "\n", "\n"+strings.Repeat(" ", i), -1)
619	}
620
621	// space between indent i and end of line width w into which
622	// we should wrap the text.
623	wrap := w - i
624
625	var r, l string
626
627	// Not enough space for sensible wrapping. Wrap as a block on
628	// the next line instead.
629	if wrap < 24 {
630		i = 16
631		wrap = w - i
632		r += "\n" + strings.Repeat(" ", i)
633	}
634	// If still not enough space then don't even try to wrap.
635	if wrap < 24 {
636		return strings.Replace(s, "\n", r, -1)
637	}
638
639	// Try to avoid short orphan words on the final line, by
640	// allowing wrapN to go a bit over if that would fit in the
641	// remainder of the line.
642	slop := 5
643	wrap = wrap - slop
644
645	// Handle first line, which is indented by the caller (or the
646	// special case above)
647	l, s = wrapN(wrap, slop, s)
648	r = r + strings.Replace(l, "\n", "\n"+strings.Repeat(" ", i), -1)
649
650	// Now wrap the rest
651	for s != "" {
652		var t string
653
654		t, s = wrapN(wrap, slop, s)
655		r = r + "\n" + strings.Repeat(" ", i) + strings.Replace(t, "\n", "\n"+strings.Repeat(" ", i), -1)
656	}
657
658	return r
659
660}
661
662// FlagUsagesWrapped returns a string containing the usage information
663// for all flags in the FlagSet. Wrapped to `cols` columns (0 for no
664// wrapping)
665func (f *FlagSet) FlagUsagesWrapped(cols int) string {
666	buf := new(bytes.Buffer)
667
668	lines := make([]string, 0, len(f.formal))
669
670	maxlen := 0
671	f.VisitAll(func(flag *Flag) {
672		if flag.Hidden {
673			return
674		}
675
676		line := ""
677		if flag.Shorthand != "" && flag.ShorthandDeprecated == "" {
678			line = fmt.Sprintf("  -%s, --%s", flag.Shorthand, flag.Name)
679		} else {
680			line = fmt.Sprintf("      --%s", flag.Name)
681		}
682
683		varname, usage := UnquoteUsage(flag)
684		if varname != "" {
685			line += " " + varname
686		}
687		if flag.NoOptDefVal != "" {
688			switch flag.Value.Type() {
689			case "string":
690				line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
691			case "bool":
692				if flag.NoOptDefVal != "true" {
693					line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
694				}
695			case "count":
696				if flag.NoOptDefVal != "+1" {
697					line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
698				}
699			default:
700				line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
701			}
702		}
703
704		// This special character will be replaced with spacing once the
705		// correct alignment is calculated
706		line += "\x00"
707		if len(line) > maxlen {
708			maxlen = len(line)
709		}
710
711		line += usage
712		if !flag.defaultIsZeroValue() {
713			if flag.Value.Type() == "string" {
714				line += fmt.Sprintf(" (default %q)", flag.DefValue)
715			} else {
716				line += fmt.Sprintf(" (default %s)", flag.DefValue)
717			}
718		}
719		if len(flag.Deprecated) != 0 {
720			line += fmt.Sprintf(" (DEPRECATED: %s)", flag.Deprecated)
721		}
722
723		lines = append(lines, line)
724	})
725
726	for _, line := range lines {
727		sidx := strings.Index(line, "\x00")
728		spacing := strings.Repeat(" ", maxlen-sidx)
729		// maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx
730		fmt.Fprintln(buf, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
731	}
732
733	return buf.String()
734}
735
736// FlagUsages returns a string containing the usage information for all flags in
737// the FlagSet
738func (f *FlagSet) FlagUsages() string {
739	return f.FlagUsagesWrapped(0)
740}
741
742// PrintDefaults prints to standard error the default values of all defined command-line flags.
743func PrintDefaults() {
744	CommandLine.PrintDefaults()
745}
746
747// defaultUsage is the default function to print a usage message.
748func defaultUsage(f *FlagSet) {
749	fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
750	f.PrintDefaults()
751}
752
753// NOTE: Usage is not just defaultUsage(CommandLine)
754// because it serves (via godoc flag Usage) as the example
755// for how to write your own usage function.
756
757// Usage prints to standard error a usage message documenting all defined command-line flags.
758// The function is a variable that may be changed to point to a custom function.
759// By default it prints a simple header and calls PrintDefaults; for details about the
760// format of the output and how to control it, see the documentation for PrintDefaults.
761var Usage = func() {
762	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
763	PrintDefaults()
764}
765
766// NFlag returns the number of flags that have been set.
767func (f *FlagSet) NFlag() int { return len(f.actual) }
768
769// NFlag returns the number of command-line flags that have been set.
770func NFlag() int { return len(CommandLine.actual) }
771
772// Arg returns the i'th argument.  Arg(0) is the first remaining argument
773// after flags have been processed.
774func (f *FlagSet) Arg(i int) string {
775	if i < 0 || i >= len(f.args) {
776		return ""
777	}
778	return f.args[i]
779}
780
781// Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
782// after flags have been processed.
783func Arg(i int) string {
784	return CommandLine.Arg(i)
785}
786
787// NArg is the number of arguments remaining after flags have been processed.
788func (f *FlagSet) NArg() int { return len(f.args) }
789
790// NArg is the number of arguments remaining after flags have been processed.
791func NArg() int { return len(CommandLine.args) }
792
793// Args returns the non-flag arguments.
794func (f *FlagSet) Args() []string { return f.args }
795
796// Args returns the non-flag command-line arguments.
797func Args() []string { return CommandLine.args }
798
799// Var defines a flag with the specified name and usage string. The type and
800// value of the flag are represented by the first argument, of type Value, which
801// typically holds a user-defined implementation of Value. For instance, the
802// caller could create a flag that turns a comma-separated string into a slice
803// of strings by giving the slice the methods of Value; in particular, Set would
804// decompose the comma-separated string into the slice.
805func (f *FlagSet) Var(value Value, name string, usage string) {
806	f.VarP(value, name, "", usage)
807}
808
809// VarPF is like VarP, but returns the flag created
810func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {
811	// Remember the default value as a string; it won't change.
812	flag := &Flag{
813		Name:      name,
814		Shorthand: shorthand,
815		Usage:     usage,
816		Value:     value,
817		DefValue:  value.String(),
818	}
819	f.AddFlag(flag)
820	return flag
821}
822
823// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
824func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
825	f.VarPF(value, name, shorthand, usage)
826}
827
828// AddFlag will add the flag to the FlagSet
829func (f *FlagSet) AddFlag(flag *Flag) {
830	normalizedFlagName := f.normalizeFlagName(flag.Name)
831
832	_, alreadyThere := f.formal[normalizedFlagName]
833	if alreadyThere {
834		msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
835		fmt.Fprintln(f.out(), msg)
836		panic(msg) // Happens only if flags are declared with identical names
837	}
838	if f.formal == nil {
839		f.formal = make(map[NormalizedName]*Flag)
840	}
841
842	flag.Name = string(normalizedFlagName)
843	f.formal[normalizedFlagName] = flag
844	f.orderedFormal = append(f.orderedFormal, flag)
845
846	if flag.Shorthand == "" {
847		return
848	}
849	if len(flag.Shorthand) > 1 {
850		msg := fmt.Sprintf("%q shorthand is more than one ASCII character", flag.Shorthand)
851		fmt.Fprintf(f.out(), msg)
852		panic(msg)
853	}
854	if f.shorthands == nil {
855		f.shorthands = make(map[byte]*Flag)
856	}
857	c := flag.Shorthand[0]
858	used, alreadyThere := f.shorthands[c]
859	if alreadyThere {
860		msg := fmt.Sprintf("unable to redefine %q shorthand in %q flagset: it's already used for %q flag", c, f.name, used.Name)
861		fmt.Fprintf(f.out(), msg)
862		panic(msg)
863	}
864	f.shorthands[c] = flag
865}
866
867// AddFlagSet adds one FlagSet to another. If a flag is already present in f
868// the flag from newSet will be ignored.
869func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
870	if newSet == nil {
871		return
872	}
873	newSet.VisitAll(func(flag *Flag) {
874		if f.Lookup(flag.Name) == nil {
875			f.AddFlag(flag)
876		}
877	})
878}
879
880// Var defines a flag with the specified name and usage string. The type and
881// value of the flag are represented by the first argument, of type Value, which
882// typically holds a user-defined implementation of Value. For instance, the
883// caller could create a flag that turns a comma-separated string into a slice
884// of strings by giving the slice the methods of Value; in particular, Set would
885// decompose the comma-separated string into the slice.
886func Var(value Value, name string, usage string) {
887	CommandLine.VarP(value, name, "", usage)
888}
889
890// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
891func VarP(value Value, name, shorthand, usage string) {
892	CommandLine.VarP(value, name, shorthand, usage)
893}
894
895// failf prints to standard error a formatted error and usage message and
896// returns the error.
897func (f *FlagSet) failf(format string, a ...interface{}) error {
898	err := fmt.Errorf(format, a...)
899	if f.errorHandling != ContinueOnError {
900		fmt.Fprintln(f.out(), err)
901		f.usage()
902	}
903	return err
904}
905
906// usage calls the Usage method for the flag set, or the usage function if
907// the flag set is CommandLine.
908func (f *FlagSet) usage() {
909	if f == CommandLine {
910		Usage()
911	} else if f.Usage == nil {
912		defaultUsage(f)
913	} else {
914		f.Usage()
915	}
916}
917
918//--unknown (args will be empty)
919//--unknown --next-flag ... (args will be --next-flag ...)
920//--unknown arg ... (args will be arg ...)
921func stripUnknownFlagValue(args []string) []string {
922	if len(args) == 0 {
923		//--unknown
924		return args
925	}
926
927	first := args[0]
928	if len(first) > 0 && first[0] == '-' {
929		//--unknown --next-flag ...
930		return args
931	}
932
933	//--unknown arg ... (args will be arg ...)
934	if len(args) > 1 {
935		return args[1:]
936	}
937	return nil
938}
939
940func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
941	a = args
942	name := s[2:]
943	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
944		err = f.failf("bad flag syntax: %s", s)
945		return
946	}
947
948	split := strings.SplitN(name, "=", 2)
949	name = split[0]
950	flag, exists := f.formal[f.normalizeFlagName(name)]
951
952	if !exists {
953		switch {
954		case name == "help":
955			f.usage()
956			return a, ErrHelp
957		case f.ParseErrorsWhitelist.UnknownFlags:
958			// --unknown=unknownval arg ...
959			// we do not want to lose arg in this case
960			if len(split) >= 2 {
961				return a, nil
962			}
963
964			return stripUnknownFlagValue(a), nil
965		default:
966			err = f.failf("unknown flag: --%s", name)
967			return
968		}
969	}
970
971	var value string
972	if len(split) == 2 {
973		// '--flag=arg'
974		value = split[1]
975	} else if flag.NoOptDefVal != "" {
976		// '--flag' (arg was optional)
977		value = flag.NoOptDefVal
978	} else if len(a) > 0 {
979		// '--flag arg'
980		value = a[0]
981		a = a[1:]
982	} else {
983		// '--flag' (arg was required)
984		err = f.failf("flag needs an argument: %s", s)
985		return
986	}
987
988	err = fn(flag, value)
989	if err != nil {
990		f.failf(err.Error())
991	}
992	return
993}
994
995func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) {
996	outArgs = args
997
998	if strings.HasPrefix(shorthands, "test.") {
999		return
1000	}
1001
1002	outShorts = shorthands[1:]
1003	c := shorthands[0]
1004
1005	flag, exists := f.shorthands[c]
1006	if !exists {
1007		switch {
1008		case c == 'h':
1009			f.usage()
1010			err = ErrHelp
1011			return
1012		case f.ParseErrorsWhitelist.UnknownFlags:
1013			// '-f=arg arg ...'
1014			// we do not want to lose arg in this case
1015			if len(shorthands) > 2 && shorthands[1] == '=' {
1016				outShorts = ""
1017				return
1018			}
1019
1020			outArgs = stripUnknownFlagValue(outArgs)
1021			return
1022		default:
1023			err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
1024			return
1025		}
1026	}
1027
1028	var value string
1029	if len(shorthands) > 2 && shorthands[1] == '=' {
1030		// '-f=arg'
1031		value = shorthands[2:]
1032		outShorts = ""
1033	} else if flag.NoOptDefVal != "" {
1034		// '-f' (arg was optional)
1035		value = flag.NoOptDefVal
1036	} else if len(shorthands) > 1 {
1037		// '-farg'
1038		value = shorthands[1:]
1039		outShorts = ""
1040	} else if len(args) > 0 {
1041		// '-f arg'
1042		value = args[0]
1043		outArgs = args[1:]
1044	} else {
1045		// '-f' (arg was required)
1046		err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
1047		return
1048	}
1049
1050	if flag.ShorthandDeprecated != "" {
1051		fmt.Fprintf(f.out(), "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
1052	}
1053
1054	err = fn(flag, value)
1055	if err != nil {
1056		f.failf(err.Error())
1057	}
1058	return
1059}
1060
1061func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) {
1062	a = args
1063	shorthands := s[1:]
1064
1065	// "shorthands" can be a series of shorthand letters of flags (e.g. "-vvv").
1066	for len(shorthands) > 0 {
1067		shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
1068		if err != nil {
1069			return
1070		}
1071	}
1072
1073	return
1074}
1075
1076func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
1077	for len(args) > 0 {
1078		s := args[0]
1079		args = args[1:]
1080		if len(s) == 0 || s[0] != '-' || len(s) == 1 {
1081			if !f.interspersed {
1082				f.args = append(f.args, s)
1083				f.args = append(f.args, args...)
1084				return nil
1085			}
1086			f.args = append(f.args, s)
1087			continue
1088		}
1089
1090		if s[1] == '-' {
1091			if len(s) == 2 { // "--" terminates the flags
1092				f.argsLenAtDash = len(f.args)
1093				f.args = append(f.args, args...)
1094				break
1095			}
1096			args, err = f.parseLongArg(s, args, fn)
1097		} else {
1098			args, err = f.parseShortArg(s, args, fn)
1099		}
1100		if err != nil {
1101			return
1102		}
1103	}
1104	return
1105}
1106
1107// Parse parses flag definitions from the argument list, which should not
1108// include the command name.  Must be called after all flags in the FlagSet
1109// are defined and before flags are accessed by the program.
1110// The return value will be ErrHelp if -help was set but not defined.
1111func (f *FlagSet) Parse(arguments []string) error {
1112	if f.addedGoFlagSets != nil {
1113		for _, goFlagSet := range f.addedGoFlagSets {
1114			goFlagSet.Parse(nil)
1115		}
1116	}
1117	f.parsed = true
1118
1119	if len(arguments) < 0 {
1120		return nil
1121	}
1122
1123	f.args = make([]string, 0, len(arguments))
1124
1125	set := func(flag *Flag, value string) error {
1126		return f.Set(flag.Name, value)
1127	}
1128
1129	err := f.parseArgs(arguments, set)
1130	if err != nil {
1131		switch f.errorHandling {
1132		case ContinueOnError:
1133			return err
1134		case ExitOnError:
1135			fmt.Println(err)
1136			os.Exit(2)
1137		case PanicOnError:
1138			panic(err)
1139		}
1140	}
1141	return nil
1142}
1143
1144type parseFunc func(flag *Flag, value string) error
1145
1146// ParseAll parses flag definitions from the argument list, which should not
1147// include the command name. The arguments for fn are flag and value. Must be
1148// called after all flags in the FlagSet are defined and before flags are
1149// accessed by the program. The return value will be ErrHelp if -help was set
1150// but not defined.
1151func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error {
1152	f.parsed = true
1153	f.args = make([]string, 0, len(arguments))
1154
1155	err := f.parseArgs(arguments, fn)
1156	if err != nil {
1157		switch f.errorHandling {
1158		case ContinueOnError:
1159			return err
1160		case ExitOnError:
1161			os.Exit(2)
1162		case PanicOnError:
1163			panic(err)
1164		}
1165	}
1166	return nil
1167}
1168
1169// Parsed reports whether f.Parse has been called.
1170func (f *FlagSet) Parsed() bool {
1171	return f.parsed
1172}
1173
1174// Parse parses the command-line flags from os.Args[1:].  Must be called
1175// after all flags are defined and before flags are accessed by the program.
1176func Parse() {
1177	// Ignore errors; CommandLine is set for ExitOnError.
1178	CommandLine.Parse(os.Args[1:])
1179}
1180
1181// ParseAll parses the command-line flags from os.Args[1:] and called fn for each.
1182// The arguments for fn are flag and value. Must be called after all flags are
1183// defined and before flags are accessed by the program.
1184func ParseAll(fn func(flag *Flag, value string) error) {
1185	// Ignore errors; CommandLine is set for ExitOnError.
1186	CommandLine.ParseAll(os.Args[1:], fn)
1187}
1188
1189// SetInterspersed sets whether to support interspersed option/non-option arguments.
1190func SetInterspersed(interspersed bool) {
1191	CommandLine.SetInterspersed(interspersed)
1192}
1193
1194// Parsed returns true if the command-line flags have been parsed.
1195func Parsed() bool {
1196	return CommandLine.Parsed()
1197}
1198
1199// CommandLine is the default set of command-line flags, parsed from os.Args.
1200var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
1201
1202// NewFlagSet returns a new, empty flag set with the specified name,
1203// error handling property and SortFlags set to true.
1204func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
1205	f := &FlagSet{
1206		name:          name,
1207		errorHandling: errorHandling,
1208		argsLenAtDash: -1,
1209		interspersed:  true,
1210		SortFlags:     true,
1211	}
1212	return f
1213}
1214
1215// SetInterspersed sets whether to support interspersed option/non-option arguments.
1216func (f *FlagSet) SetInterspersed(interspersed bool) {
1217	f.interspersed = interspersed
1218}
1219
1220// Init sets the name and error handling property for a flag set.
1221// By default, the zero FlagSet uses an empty name and the
1222// ContinueOnError error handling policy.
1223func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
1224	f.name = name
1225	f.errorHandling = errorHandling
1226	f.argsLenAtDash = -1
1227}
1228