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