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/ogier/pflag"
20
21	There 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	name              string
138	parsed            bool
139	actual            map[NormalizedName]*Flag
140	formal            map[NormalizedName]*Flag
141	shorthands        map[byte]*Flag
142	args              []string // arguments after flags
143	argsLenAtDash     int      // len(args) when a '--' was located when parsing, or -1 if no --
144	exitOnError       bool     // does the program exit if there's an error?
145	errorHandling     ErrorHandling
146	output            io.Writer // nil means stderr; use out() accessor
147	interspersed      bool      // allow interspersed option/non-option args
148	normalizeNameFunc func(f *FlagSet, name string) NormalizedName
149}
150
151// A Flag represents the state of a flag.
152type Flag struct {
153	Name                string              // name as it appears on command line
154	Shorthand           string              // one-letter abbreviated flag
155	Usage               string              // help message
156	Value               Value               // value as set
157	DefValue            string              // default value (as text); for usage message
158	Changed             bool                // If the user set the value (or if left to default)
159	NoOptDefVal         string              //default value (as text); if the flag is on the command line without any options
160	Deprecated          string              // If this flag is deprecated, this string is the new or now thing to use
161	Hidden              bool                // used by cobra.Command to allow flags to be hidden from help/usage text
162	ShorthandDeprecated string              // If the shorthand of this flag is deprecated, this string is the new or now thing to use
163	Annotations         map[string][]string // used by cobra.Command bash autocomple code
164}
165
166// Value is the interface to the dynamic value stored in a flag.
167// (The default value is represented as a string.)
168type Value interface {
169	String() string
170	Set(string) error
171	Type() string
172}
173
174// sortFlags returns the flags as a slice in lexicographical sorted order.
175func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
176	list := make(sort.StringSlice, len(flags))
177	i := 0
178	for k := range flags {
179		list[i] = string(k)
180		i++
181	}
182	list.Sort()
183	result := make([]*Flag, len(list))
184	for i, name := range list {
185		result[i] = flags[NormalizedName(name)]
186	}
187	return result
188}
189
190// SetNormalizeFunc allows you to add a function which can translate flag names.
191// Flags added to the FlagSet will be translated and then when anything tries to
192// look up the flag that will also be translated. So it would be possible to create
193// a flag named "getURL" and have it translated to "geturl".  A user could then pass
194// "--getUrl" which may also be translated to "geturl" and everything will work.
195func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
196	f.normalizeNameFunc = n
197	for k, v := range f.formal {
198		delete(f.formal, k)
199		nname := f.normalizeFlagName(string(k))
200		f.formal[nname] = v
201		v.Name = string(nname)
202	}
203}
204
205// GetNormalizeFunc returns the previously set NormalizeFunc of a function which
206// does no translation, if not set previously.
207func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName {
208	if f.normalizeNameFunc != nil {
209		return f.normalizeNameFunc
210	}
211	return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) }
212}
213
214func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
215	n := f.GetNormalizeFunc()
216	return n(f, name)
217}
218
219func (f *FlagSet) out() io.Writer {
220	if f.output == nil {
221		return os.Stderr
222	}
223	return f.output
224}
225
226// SetOutput sets the destination for usage and error messages.
227// If output is nil, os.Stderr is used.
228func (f *FlagSet) SetOutput(output io.Writer) {
229	f.output = output
230}
231
232// VisitAll visits the flags in lexicographical order, calling fn for each.
233// It visits all flags, even those not set.
234func (f *FlagSet) VisitAll(fn func(*Flag)) {
235	for _, flag := range sortFlags(f.formal) {
236		fn(flag)
237	}
238}
239
240// HasFlags returns a bool to indicate if the FlagSet has any flags definied.
241func (f *FlagSet) HasFlags() bool {
242	return len(f.formal) > 0
243}
244
245// HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
246// definied that are not hidden or deprecated.
247func (f *FlagSet) HasAvailableFlags() bool {
248	for _, flag := range f.formal {
249		if !flag.Hidden && len(flag.Deprecated) == 0 {
250			return true
251		}
252	}
253	return false
254}
255
256// VisitAll visits the command-line flags in lexicographical order, calling
257// fn for each.  It visits all flags, even those not set.
258func VisitAll(fn func(*Flag)) {
259	CommandLine.VisitAll(fn)
260}
261
262// Visit visits the flags in lexicographical order, calling fn for each.
263// It visits only those flags that have been set.
264func (f *FlagSet) Visit(fn func(*Flag)) {
265	for _, flag := range sortFlags(f.actual) {
266		fn(flag)
267	}
268}
269
270// Visit visits the command-line flags in lexicographical order, calling fn
271// for each.  It visits only those flags that have been set.
272func Visit(fn func(*Flag)) {
273	CommandLine.Visit(fn)
274}
275
276// Lookup returns the Flag structure of the named flag, returning nil if none exists.
277func (f *FlagSet) Lookup(name string) *Flag {
278	return f.lookup(f.normalizeFlagName(name))
279}
280
281// lookup returns the Flag structure of the named flag, returning nil if none exists.
282func (f *FlagSet) lookup(name NormalizedName) *Flag {
283	return f.formal[name]
284}
285
286// func to return a given type for a given flag name
287func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) {
288	flag := f.Lookup(name)
289	if flag == nil {
290		err := fmt.Errorf("flag accessed but not defined: %s", name)
291		return nil, err
292	}
293
294	if flag.Value.Type() != ftype {
295		err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type())
296		return nil, err
297	}
298
299	sval := flag.Value.String()
300	result, err := convFunc(sval)
301	if err != nil {
302		return nil, err
303	}
304	return result, nil
305}
306
307// ArgsLenAtDash will return the length of f.Args at the moment when a -- was
308// found during arg parsing. This allows your program to know which args were
309// before the -- and which came after.
310func (f *FlagSet) ArgsLenAtDash() int {
311	return f.argsLenAtDash
312}
313
314// MarkDeprecated indicated that a flag is deprecated in your program. It will
315// continue to function but will not show up in help or usage messages. Using
316// this flag will also print the given usageMessage.
317func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
318	flag := f.Lookup(name)
319	if flag == nil {
320		return fmt.Errorf("flag %q does not exist", name)
321	}
322	if len(usageMessage) == 0 {
323		return fmt.Errorf("deprecated message for flag %q must be set", name)
324	}
325	flag.Deprecated = usageMessage
326	return nil
327}
328
329// MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your
330// program. It will continue to function but will not show up in help or usage
331// messages. Using this flag will also print the given usageMessage.
332func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error {
333	flag := f.Lookup(name)
334	if flag == nil {
335		return fmt.Errorf("flag %q does not exist", name)
336	}
337	if len(usageMessage) == 0 {
338		return fmt.Errorf("deprecated message for flag %q must be set", name)
339	}
340	flag.ShorthandDeprecated = usageMessage
341	return nil
342}
343
344// MarkHidden sets a flag to 'hidden' in your program. It will continue to
345// function but will not show up in help or usage messages.
346func (f *FlagSet) MarkHidden(name string) error {
347	flag := f.Lookup(name)
348	if flag == nil {
349		return fmt.Errorf("flag %q does not exist", name)
350	}
351	flag.Hidden = true
352	return nil
353}
354
355// Lookup returns the Flag structure of the named command-line flag,
356// returning nil if none exists.
357func Lookup(name string) *Flag {
358	return CommandLine.Lookup(name)
359}
360
361// Set sets the value of the named flag.
362func (f *FlagSet) Set(name, value string) error {
363	normalName := f.normalizeFlagName(name)
364	flag, ok := f.formal[normalName]
365	if !ok {
366		return fmt.Errorf("no such flag -%v", name)
367	}
368	err := flag.Value.Set(value)
369	if err != nil {
370		return err
371	}
372	if f.actual == nil {
373		f.actual = make(map[NormalizedName]*Flag)
374	}
375	f.actual[normalName] = flag
376	flag.Changed = true
377	if len(flag.Deprecated) > 0 {
378		fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
379	}
380	return nil
381}
382
383// SetAnnotation allows one to set arbitrary annotations on a flag in the FlagSet.
384// This is sometimes used by spf13/cobra programs which want to generate additional
385// bash completion information.
386func (f *FlagSet) SetAnnotation(name, key string, values []string) error {
387	normalName := f.normalizeFlagName(name)
388	flag, ok := f.formal[normalName]
389	if !ok {
390		return fmt.Errorf("no such flag -%v", name)
391	}
392	if flag.Annotations == nil {
393		flag.Annotations = map[string][]string{}
394	}
395	flag.Annotations[key] = values
396	return nil
397}
398
399// Changed returns true if the flag was explicitly set during Parse() and false
400// otherwise
401func (f *FlagSet) Changed(name string) bool {
402	flag := f.Lookup(name)
403	// If a flag doesn't exist, it wasn't changed....
404	if flag == nil {
405		return false
406	}
407	return flag.Changed
408}
409
410// Set sets the value of the named command-line flag.
411func Set(name, value string) error {
412	return CommandLine.Set(name, value)
413}
414
415// PrintDefaults prints, to standard error unless configured
416// otherwise, the default values of all defined flags in the set.
417func (f *FlagSet) PrintDefaults() {
418	usages := f.FlagUsages()
419	fmt.Fprintf(f.out(), "%s", usages)
420}
421
422// isZeroValue guesses whether the string represents the zero
423// value for a flag. It is not accurate but in practice works OK.
424func isZeroValue(value string) bool {
425	switch value {
426	case "false":
427		return true
428	case "<nil>":
429		return true
430	case "":
431		return true
432	case "0":
433		return true
434	}
435	return false
436}
437
438// UnquoteUsage extracts a back-quoted name from the usage
439// string for a flag and returns it and the un-quoted usage.
440// Given "a `name` to show" it returns ("name", "a name to show").
441// If there are no back quotes, the name is an educated guess of the
442// type of the flag's value, or the empty string if the flag is boolean.
443func UnquoteUsage(flag *Flag) (name string, usage string) {
444	// Look for a back-quoted name, but avoid the strings package.
445	usage = flag.Usage
446	for i := 0; i < len(usage); i++ {
447		if usage[i] == '`' {
448			for j := i + 1; j < len(usage); j++ {
449				if usage[j] == '`' {
450					name = usage[i+1 : j]
451					usage = usage[:i] + name + usage[j+1:]
452					return name, usage
453				}
454			}
455			break // Only one back quote; use type name.
456		}
457	}
458	// No explicit name, so use type if we can find one.
459	name = "value"
460	switch flag.Value.(type) {
461	case boolFlag:
462		name = ""
463	case *durationValue:
464		name = "duration"
465	case *float64Value:
466		name = "float"
467	case *intValue, *int64Value:
468		name = "int"
469	case *stringValue:
470		name = "string"
471	case *uintValue, *uint64Value:
472		name = "uint"
473	}
474	return
475}
476
477// FlagUsages Returns a string containing the usage information for all flags in
478// the FlagSet
479func (f *FlagSet) FlagUsages() string {
480	x := new(bytes.Buffer)
481
482	lines := make([]string, 0, len(f.formal))
483
484	maxlen := 0
485	f.VisitAll(func(flag *Flag) {
486		if len(flag.Deprecated) > 0 || flag.Hidden {
487			return
488		}
489
490		line := ""
491		if len(flag.Shorthand) > 0 && len(flag.ShorthandDeprecated) == 0 {
492			line = fmt.Sprintf("  -%s, --%s", flag.Shorthand, flag.Name)
493		} else {
494			line = fmt.Sprintf("      --%s", flag.Name)
495		}
496
497		varname, usage := UnquoteUsage(flag)
498		if len(varname) > 0 {
499			line += " " + varname
500		}
501		if len(flag.NoOptDefVal) > 0 {
502			switch flag.Value.Type() {
503			case "string":
504				line += fmt.Sprintf("[=%q]", flag.NoOptDefVal)
505			case "bool":
506				if flag.NoOptDefVal != "true" {
507					line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
508				}
509			default:
510				line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
511			}
512		}
513
514		// This special character will be replaced with spacing once the
515		// correct alignment is calculated
516		line += "\x00"
517		if len(line) > maxlen {
518			maxlen = len(line)
519		}
520
521		line += usage
522		if !isZeroValue(flag.DefValue) {
523			if flag.Value.Type() == "string" {
524				line += fmt.Sprintf(" (default %q)", flag.DefValue)
525			} else {
526				line += fmt.Sprintf(" (default %s)", flag.DefValue)
527			}
528		}
529
530		lines = append(lines, line)
531	})
532
533	for _, line := range lines {
534		sidx := strings.Index(line, "\x00")
535		spacing := strings.Repeat(" ", maxlen-sidx)
536		fmt.Fprintln(x, line[:sidx], spacing, line[sidx+1:])
537	}
538
539	return x.String()
540}
541
542// PrintDefaults prints to standard error the default values of all defined command-line flags.
543func PrintDefaults() {
544	CommandLine.PrintDefaults()
545}
546
547// defaultUsage is the default function to print a usage message.
548func defaultUsage(f *FlagSet) {
549	fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
550	f.PrintDefaults()
551}
552
553// NOTE: Usage is not just defaultUsage(CommandLine)
554// because it serves (via godoc flag Usage) as the example
555// for how to write your own usage function.
556
557// Usage prints to standard error a usage message documenting all defined command-line flags.
558// The function is a variable that may be changed to point to a custom function.
559// By default it prints a simple header and calls PrintDefaults; for details about the
560// format of the output and how to control it, see the documentation for PrintDefaults.
561var Usage = func() {
562	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
563	PrintDefaults()
564}
565
566// NFlag returns the number of flags that have been set.
567func (f *FlagSet) NFlag() int { return len(f.actual) }
568
569// NFlag returns the number of command-line flags that have been set.
570func NFlag() int { return len(CommandLine.actual) }
571
572// Arg returns the i'th argument.  Arg(0) is the first remaining argument
573// after flags have been processed.
574func (f *FlagSet) Arg(i int) string {
575	if i < 0 || i >= len(f.args) {
576		return ""
577	}
578	return f.args[i]
579}
580
581// Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
582// after flags have been processed.
583func Arg(i int) string {
584	return CommandLine.Arg(i)
585}
586
587// NArg is the number of arguments remaining after flags have been processed.
588func (f *FlagSet) NArg() int { return len(f.args) }
589
590// NArg is the number of arguments remaining after flags have been processed.
591func NArg() int { return len(CommandLine.args) }
592
593// Args returns the non-flag arguments.
594func (f *FlagSet) Args() []string { return f.args }
595
596// Args returns the non-flag command-line arguments.
597func Args() []string { return CommandLine.args }
598
599// Var defines a flag with the specified name and usage string. The type and
600// value of the flag are represented by the first argument, of type Value, which
601// typically holds a user-defined implementation of Value. For instance, the
602// caller could create a flag that turns a comma-separated string into a slice
603// of strings by giving the slice the methods of Value; in particular, Set would
604// decompose the comma-separated string into the slice.
605func (f *FlagSet) Var(value Value, name string, usage string) {
606	f.VarP(value, name, "", usage)
607}
608
609// VarPF is like VarP, but returns the flag created
610func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {
611	// Remember the default value as a string; it won't change.
612	flag := &Flag{
613		Name:      name,
614		Shorthand: shorthand,
615		Usage:     usage,
616		Value:     value,
617		DefValue:  value.String(),
618	}
619	f.AddFlag(flag)
620	return flag
621}
622
623// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
624func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
625	_ = f.VarPF(value, name, shorthand, usage)
626}
627
628// AddFlag will add the flag to the FlagSet
629func (f *FlagSet) AddFlag(flag *Flag) {
630	// Call normalizeFlagName function only once
631	normalizedFlagName := f.normalizeFlagName(flag.Name)
632
633	_, alreadythere := f.formal[normalizedFlagName]
634	if alreadythere {
635		msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
636		fmt.Fprintln(f.out(), msg)
637		panic(msg) // Happens only if flags are declared with identical names
638	}
639	if f.formal == nil {
640		f.formal = make(map[NormalizedName]*Flag)
641	}
642
643	flag.Name = string(normalizedFlagName)
644	f.formal[normalizedFlagName] = flag
645
646	if len(flag.Shorthand) == 0 {
647		return
648	}
649	if len(flag.Shorthand) > 1 {
650		fmt.Fprintf(f.out(), "%s shorthand more than ASCII character: %s\n", f.name, flag.Shorthand)
651		panic("shorthand is more than one character")
652	}
653	if f.shorthands == nil {
654		f.shorthands = make(map[byte]*Flag)
655	}
656	c := flag.Shorthand[0]
657	old, alreadythere := f.shorthands[c]
658	if alreadythere {
659		fmt.Fprintf(f.out(), "%s shorthand reused: %q for %s already used for %s\n", f.name, c, flag.Name, old.Name)
660		panic("shorthand redefinition")
661	}
662	f.shorthands[c] = flag
663}
664
665// AddFlagSet adds one FlagSet to another. If a flag is already present in f
666// the flag from newSet will be ignored
667func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
668	if newSet == nil {
669		return
670	}
671	newSet.VisitAll(func(flag *Flag) {
672		if f.Lookup(flag.Name) == nil {
673			f.AddFlag(flag)
674		}
675	})
676}
677
678// Var defines a flag with the specified name and usage string. The type and
679// value of the flag are represented by the first argument, of type Value, which
680// typically holds a user-defined implementation of Value. For instance, the
681// caller could create a flag that turns a comma-separated string into a slice
682// of strings by giving the slice the methods of Value; in particular, Set would
683// decompose the comma-separated string into the slice.
684func Var(value Value, name string, usage string) {
685	CommandLine.VarP(value, name, "", usage)
686}
687
688// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
689func VarP(value Value, name, shorthand, usage string) {
690	CommandLine.VarP(value, name, shorthand, usage)
691}
692
693// failf prints to standard error a formatted error and usage message and
694// returns the error.
695func (f *FlagSet) failf(format string, a ...interface{}) error {
696	err := fmt.Errorf(format, a...)
697	fmt.Fprintln(f.out(), err)
698	f.usage()
699	return err
700}
701
702// usage calls the Usage method for the flag set, or the usage function if
703// the flag set is CommandLine.
704func (f *FlagSet) usage() {
705	if f == CommandLine {
706		Usage()
707	} else if f.Usage == nil {
708		defaultUsage(f)
709	} else {
710		f.Usage()
711	}
712}
713
714func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) error {
715	if err := flag.Value.Set(value); err != nil {
716		return f.failf("invalid argument %q for %s: %v", value, origArg, err)
717	}
718	// mark as visited for Visit()
719	if f.actual == nil {
720		f.actual = make(map[NormalizedName]*Flag)
721	}
722	f.actual[f.normalizeFlagName(flag.Name)] = flag
723	flag.Changed = true
724	if len(flag.Deprecated) > 0 {
725		fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
726	}
727	if len(flag.ShorthandDeprecated) > 0 && containsShorthand(origArg, flag.Shorthand) {
728		fmt.Fprintf(os.Stderr, "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
729	}
730	return nil
731}
732
733func containsShorthand(arg, shorthand string) bool {
734	// filter out flags --<flag_name>
735	if strings.HasPrefix(arg, "-") {
736		return false
737	}
738	arg = strings.SplitN(arg, "=", 2)[0]
739	return strings.Contains(arg, shorthand)
740}
741
742func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error) {
743	a = args
744	name := s[2:]
745	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
746		err = f.failf("bad flag syntax: %s", s)
747		return
748	}
749	split := strings.SplitN(name, "=", 2)
750	name = split[0]
751	flag, alreadythere := f.formal[f.normalizeFlagName(name)]
752	if !alreadythere {
753		if name == "help" { // special case for nice help message.
754			f.usage()
755			return a, ErrHelp
756		}
757		err = f.failf("unknown flag: --%s", name)
758		return
759	}
760	var value string
761	if len(split) == 2 {
762		// '--flag=arg'
763		value = split[1]
764	} else if len(flag.NoOptDefVal) > 0 {
765		// '--flag' (arg was optional)
766		value = flag.NoOptDefVal
767	} else if len(a) > 0 {
768		// '--flag arg'
769		value = a[0]
770		a = a[1:]
771	} else {
772		// '--flag' (arg was required)
773		err = f.failf("flag needs an argument: %s", s)
774		return
775	}
776	err = f.setFlag(flag, value, s)
777	return
778}
779
780func (f *FlagSet) parseSingleShortArg(shorthands string, args []string) (outShorts string, outArgs []string, err error) {
781	if strings.HasPrefix(shorthands, "test.") {
782		return
783	}
784	outArgs = args
785	outShorts = shorthands[1:]
786	c := shorthands[0]
787
788	flag, alreadythere := f.shorthands[c]
789	if !alreadythere {
790		if c == 'h' { // special case for nice help message.
791			f.usage()
792			err = ErrHelp
793			return
794		}
795		//TODO continue on error
796		err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
797		return
798	}
799	var value string
800	if len(shorthands) > 2 && shorthands[1] == '=' {
801		value = shorthands[2:]
802		outShorts = ""
803	} else if len(flag.NoOptDefVal) > 0 {
804		value = flag.NoOptDefVal
805	} else if len(shorthands) > 1 {
806		value = shorthands[1:]
807		outShorts = ""
808	} else if len(args) > 0 {
809		value = args[0]
810		outArgs = args[1:]
811	} else {
812		err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
813		return
814	}
815	err = f.setFlag(flag, value, shorthands)
816	return
817}
818
819func (f *FlagSet) parseShortArg(s string, args []string) (a []string, err error) {
820	a = args
821	shorthands := s[1:]
822
823	for len(shorthands) > 0 {
824		shorthands, a, err = f.parseSingleShortArg(shorthands, args)
825		if err != nil {
826			return
827		}
828	}
829
830	return
831}
832
833func (f *FlagSet) parseArgs(args []string) (err error) {
834	for len(args) > 0 {
835		s := args[0]
836		args = args[1:]
837		if len(s) == 0 || s[0] != '-' || len(s) == 1 {
838			if !f.interspersed {
839				f.args = append(f.args, s)
840				f.args = append(f.args, args...)
841				return nil
842			}
843			f.args = append(f.args, s)
844			continue
845		}
846
847		if s[1] == '-' {
848			if len(s) == 2 { // "--" terminates the flags
849				f.argsLenAtDash = len(f.args)
850				f.args = append(f.args, args...)
851				break
852			}
853			args, err = f.parseLongArg(s, args)
854		} else {
855			args, err = f.parseShortArg(s, args)
856		}
857		if err != nil {
858			return
859		}
860	}
861	return
862}
863
864// Parse parses flag definitions from the argument list, which should not
865// include the command name.  Must be called after all flags in the FlagSet
866// are defined and before flags are accessed by the program.
867// The return value will be ErrHelp if -help was set but not defined.
868func (f *FlagSet) Parse(arguments []string) error {
869	f.parsed = true
870	f.args = make([]string, 0, len(arguments))
871	err := f.parseArgs(arguments)
872	if err != nil {
873		switch f.errorHandling {
874		case ContinueOnError:
875			return err
876		case ExitOnError:
877			os.Exit(2)
878		case PanicOnError:
879			panic(err)
880		}
881	}
882	return nil
883}
884
885// Parsed reports whether f.Parse has been called.
886func (f *FlagSet) Parsed() bool {
887	return f.parsed
888}
889
890// Parse parses the command-line flags from os.Args[1:].  Must be called
891// after all flags are defined and before flags are accessed by the program.
892func Parse() {
893	// Ignore errors; CommandLine is set for ExitOnError.
894	CommandLine.Parse(os.Args[1:])
895}
896
897// SetInterspersed sets whether to support interspersed option/non-option arguments.
898func SetInterspersed(interspersed bool) {
899	CommandLine.SetInterspersed(interspersed)
900}
901
902// Parsed returns true if the command-line flags have been parsed.
903func Parsed() bool {
904	return CommandLine.Parsed()
905}
906
907// CommandLine is the default set of command-line flags, parsed from os.Args.
908var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
909
910// NewFlagSet returns a new, empty flag set with the specified name and
911// error handling property.
912func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
913	f := &FlagSet{
914		name:          name,
915		errorHandling: errorHandling,
916		argsLenAtDash: -1,
917		interspersed:  true,
918	}
919	return f
920}
921
922// SetInterspersed sets whether to support interspersed option/non-option arguments.
923func (f *FlagSet) SetInterspersed(interspersed bool) {
924	f.interspersed = interspersed
925}
926
927// Init sets the name and error handling property for a flag set.
928// By default, the zero FlagSet uses an empty name and the
929// ContinueOnError error handling policy.
930func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
931	f.name = name
932	f.errorHandling = errorHandling
933	f.argsLenAtDash = -1
934}
935