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