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// VisitAll visits the command-line flags in lexicographical order, calling
246// fn for each.  It visits all flags, even those not set.
247func VisitAll(fn func(*Flag)) {
248	CommandLine.VisitAll(fn)
249}
250
251// Visit visits the flags in lexicographical order, calling fn for each.
252// It visits only those flags that have been set.
253func (f *FlagSet) Visit(fn func(*Flag)) {
254	for _, flag := range sortFlags(f.actual) {
255		fn(flag)
256	}
257}
258
259// Visit visits the command-line flags in lexicographical order, calling fn
260// for each.  It visits only those flags that have been set.
261func Visit(fn func(*Flag)) {
262	CommandLine.Visit(fn)
263}
264
265// Lookup returns the Flag structure of the named flag, returning nil if none exists.
266func (f *FlagSet) Lookup(name string) *Flag {
267	return f.lookup(f.normalizeFlagName(name))
268}
269
270// lookup returns the Flag structure of the named flag, returning nil if none exists.
271func (f *FlagSet) lookup(name NormalizedName) *Flag {
272	return f.formal[name]
273}
274
275// func to return a given type for a given flag name
276func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) {
277	flag := f.Lookup(name)
278	if flag == nil {
279		err := fmt.Errorf("flag accessed but not defined: %s", name)
280		return nil, err
281	}
282
283	if flag.Value.Type() != ftype {
284		err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type())
285		return nil, err
286	}
287
288	sval := flag.Value.String()
289	result, err := convFunc(sval)
290	if err != nil {
291		return nil, err
292	}
293	return result, nil
294}
295
296// ArgsLenAtDash will return the length of f.Args at the moment when a -- was
297// found during arg parsing. This allows your program to know which args were
298// before the -- and which came after.
299func (f *FlagSet) ArgsLenAtDash() int {
300	return f.argsLenAtDash
301}
302
303// MarkDeprecated indicated that a flag is deprecated in your program. It will
304// continue to function but will not show up in help or usage messages. Using
305// this flag will also print the given usageMessage.
306func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
307	flag := f.Lookup(name)
308	if flag == nil {
309		return fmt.Errorf("flag %q does not exist", name)
310	}
311	if len(usageMessage) == 0 {
312		return fmt.Errorf("deprecated message for flag %q must be set", name)
313	}
314	flag.Deprecated = usageMessage
315	return nil
316}
317
318// MarkShorthandDeprecated will mark the shorthand of a flag deprecated in your
319// program. It will continue to function but will not show up in help or usage
320// messages. Using this flag will also print the given usageMessage.
321func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error {
322	flag := f.Lookup(name)
323	if flag == nil {
324		return fmt.Errorf("flag %q does not exist", name)
325	}
326	if len(usageMessage) == 0 {
327		return fmt.Errorf("deprecated message for flag %q must be set", name)
328	}
329	flag.ShorthandDeprecated = usageMessage
330	return nil
331}
332
333// MarkHidden sets a flag to 'hidden' in your program. It will continue to
334// function but will not show up in help or usage messages.
335func (f *FlagSet) MarkHidden(name string) error {
336	flag := f.Lookup(name)
337	if flag == nil {
338		return fmt.Errorf("flag %q does not exist", name)
339	}
340	flag.Hidden = true
341	return nil
342}
343
344// Lookup returns the Flag structure of the named command-line flag,
345// returning nil if none exists.
346func Lookup(name string) *Flag {
347	return CommandLine.Lookup(name)
348}
349
350// Set sets the value of the named flag.
351func (f *FlagSet) Set(name, value string) error {
352	normalName := f.normalizeFlagName(name)
353	flag, ok := f.formal[normalName]
354	if !ok {
355		return fmt.Errorf("no such flag -%v", name)
356	}
357	err := flag.Value.Set(value)
358	if err != nil {
359		return err
360	}
361	if f.actual == nil {
362		f.actual = make(map[NormalizedName]*Flag)
363	}
364	f.actual[normalName] = flag
365	flag.Changed = true
366	if len(flag.Deprecated) > 0 {
367		fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
368	}
369	return nil
370}
371
372// SetAnnotation allows one to set arbitrary annotations on a flag in the FlagSet.
373// This is sometimes used by spf13/cobra programs which want to generate additional
374// bash completion information.
375func (f *FlagSet) SetAnnotation(name, key string, values []string) error {
376	normalName := f.normalizeFlagName(name)
377	flag, ok := f.formal[normalName]
378	if !ok {
379		return fmt.Errorf("no such flag -%v", name)
380	}
381	if flag.Annotations == nil {
382		flag.Annotations = map[string][]string{}
383	}
384	flag.Annotations[key] = values
385	return nil
386}
387
388// Changed returns true if the flag was explicitly set during Parse() and false
389// otherwise
390func (f *FlagSet) Changed(name string) bool {
391	flag := f.Lookup(name)
392	// If a flag doesn't exist, it wasn't changed....
393	if flag == nil {
394		return false
395	}
396	return flag.Changed
397}
398
399// Set sets the value of the named command-line flag.
400func Set(name, value string) error {
401	return CommandLine.Set(name, value)
402}
403
404// PrintDefaults prints, to standard error unless configured
405// otherwise, the default values of all defined flags in the set.
406func (f *FlagSet) PrintDefaults() {
407	usages := f.FlagUsages()
408	fmt.Fprintf(f.out(), "%s", usages)
409}
410
411// FlagUsages Returns a string containing the usage information for all flags in
412// the FlagSet
413func (f *FlagSet) FlagUsages() string {
414	x := new(bytes.Buffer)
415
416	f.VisitAll(func(flag *Flag) {
417		if len(flag.Deprecated) > 0 || flag.Hidden {
418			return
419		}
420		format := ""
421		if len(flag.Shorthand) > 0 && len(flag.ShorthandDeprecated) == 0 {
422			format = "  -%s, --%s"
423		} else {
424			format = "   %s   --%s"
425		}
426		if len(flag.NoOptDefVal) > 0 {
427			format = format + "["
428		}
429		if flag.Value.Type() == "string" {
430			// put quotes on the value
431			format = format + "=%q"
432		} else {
433			format = format + "=%s"
434		}
435		if len(flag.NoOptDefVal) > 0 {
436			format = format + "]"
437		}
438		format = format + ": %s\n"
439		shorthand := flag.Shorthand
440		if len(flag.ShorthandDeprecated) > 0 {
441			shorthand = ""
442		}
443		fmt.Fprintf(x, format, shorthand, flag.Name, flag.DefValue, flag.Usage)
444	})
445
446	return x.String()
447}
448
449// PrintDefaults prints to standard error the default values of all defined command-line flags.
450func PrintDefaults() {
451	CommandLine.PrintDefaults()
452}
453
454// defaultUsage is the default function to print a usage message.
455func defaultUsage(f *FlagSet) {
456	fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
457	f.PrintDefaults()
458}
459
460// NOTE: Usage is not just defaultUsage(CommandLine)
461// because it serves (via godoc flag Usage) as the example
462// for how to write your own usage function.
463
464// Usage prints to standard error a usage message documenting all defined command-line flags.
465// The function is a variable that may be changed to point to a custom function.
466var Usage = func() {
467	fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
468	PrintDefaults()
469}
470
471// NFlag returns the number of flags that have been set.
472func (f *FlagSet) NFlag() int { return len(f.actual) }
473
474// NFlag returns the number of command-line flags that have been set.
475func NFlag() int { return len(CommandLine.actual) }
476
477// Arg returns the i'th argument.  Arg(0) is the first remaining argument
478// after flags have been processed.
479func (f *FlagSet) Arg(i int) string {
480	if i < 0 || i >= len(f.args) {
481		return ""
482	}
483	return f.args[i]
484}
485
486// Arg returns the i'th command-line argument.  Arg(0) is the first remaining argument
487// after flags have been processed.
488func Arg(i int) string {
489	return CommandLine.Arg(i)
490}
491
492// NArg is the number of arguments remaining after flags have been processed.
493func (f *FlagSet) NArg() int { return len(f.args) }
494
495// NArg is the number of arguments remaining after flags have been processed.
496func NArg() int { return len(CommandLine.args) }
497
498// Args returns the non-flag arguments.
499func (f *FlagSet) Args() []string { return f.args }
500
501// Args returns the non-flag command-line arguments.
502func Args() []string { return CommandLine.args }
503
504// Var defines a flag with the specified name and usage string. The type and
505// value of the flag are represented by the first argument, of type Value, which
506// typically holds a user-defined implementation of Value. For instance, the
507// caller could create a flag that turns a comma-separated string into a slice
508// of strings by giving the slice the methods of Value; in particular, Set would
509// decompose the comma-separated string into the slice.
510func (f *FlagSet) Var(value Value, name string, usage string) {
511	f.VarP(value, name, "", usage)
512}
513
514// VarPF is like VarP, but returns the flag created
515func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {
516	// Remember the default value as a string; it won't change.
517	flag := &Flag{
518		Name:      name,
519		Shorthand: shorthand,
520		Usage:     usage,
521		Value:     value,
522		DefValue:  value.String(),
523	}
524	f.AddFlag(flag)
525	return flag
526}
527
528// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
529func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
530	_ = f.VarPF(value, name, shorthand, usage)
531}
532
533// AddFlag will add the flag to the FlagSet
534func (f *FlagSet) AddFlag(flag *Flag) {
535	// Call normalizeFlagName function only once
536	normalizedFlagName := f.normalizeFlagName(flag.Name)
537
538	_, alreadythere := f.formal[normalizedFlagName]
539	if alreadythere {
540		msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
541		fmt.Fprintln(f.out(), msg)
542		panic(msg) // Happens only if flags are declared with identical names
543	}
544	if f.formal == nil {
545		f.formal = make(map[NormalizedName]*Flag)
546	}
547
548	flag.Name = string(normalizedFlagName)
549	f.formal[normalizedFlagName] = flag
550
551	if len(flag.Shorthand) == 0 {
552		return
553	}
554	if len(flag.Shorthand) > 1 {
555		fmt.Fprintf(f.out(), "%s shorthand more than ASCII character: %s\n", f.name, flag.Shorthand)
556		panic("shorthand is more than one character")
557	}
558	if f.shorthands == nil {
559		f.shorthands = make(map[byte]*Flag)
560	}
561	c := flag.Shorthand[0]
562	old, alreadythere := f.shorthands[c]
563	if alreadythere {
564		fmt.Fprintf(f.out(), "%s shorthand reused: %q for %s already used for %s\n", f.name, c, flag.Name, old.Name)
565		panic("shorthand redefinition")
566	}
567	f.shorthands[c] = flag
568}
569
570// AddFlagSet adds one FlagSet to another. If a flag is already present in f
571// the flag from newSet will be ignored
572func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
573	if newSet == nil {
574		return
575	}
576	newSet.VisitAll(func(flag *Flag) {
577		if f.Lookup(flag.Name) == nil {
578			f.AddFlag(flag)
579		}
580	})
581}
582
583// Var defines a flag with the specified name and usage string. The type and
584// value of the flag are represented by the first argument, of type Value, which
585// typically holds a user-defined implementation of Value. For instance, the
586// caller could create a flag that turns a comma-separated string into a slice
587// of strings by giving the slice the methods of Value; in particular, Set would
588// decompose the comma-separated string into the slice.
589func Var(value Value, name string, usage string) {
590	CommandLine.VarP(value, name, "", usage)
591}
592
593// VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
594func VarP(value Value, name, shorthand, usage string) {
595	CommandLine.VarP(value, name, shorthand, usage)
596}
597
598// failf prints to standard error a formatted error and usage message and
599// returns the error.
600func (f *FlagSet) failf(format string, a ...interface{}) error {
601	err := fmt.Errorf(format, a...)
602	fmt.Fprintln(f.out(), err)
603	f.usage()
604	return err
605}
606
607// usage calls the Usage method for the flag set, or the usage function if
608// the flag set is CommandLine.
609func (f *FlagSet) usage() {
610	if f == CommandLine {
611		Usage()
612	} else if f.Usage == nil {
613		defaultUsage(f)
614	} else {
615		f.Usage()
616	}
617}
618
619func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) error {
620	if err := flag.Value.Set(value); err != nil {
621		return f.failf("invalid argument %q for %s: %v", value, origArg, err)
622	}
623	// mark as visited for Visit()
624	if f.actual == nil {
625		f.actual = make(map[NormalizedName]*Flag)
626	}
627	f.actual[f.normalizeFlagName(flag.Name)] = flag
628	flag.Changed = true
629	if len(flag.Deprecated) > 0 {
630		fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
631	}
632	if len(flag.ShorthandDeprecated) > 0 && containsShorthand(origArg, flag.Shorthand) {
633		fmt.Fprintf(os.Stderr, "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
634	}
635	return nil
636}
637
638func containsShorthand(arg, shorthand string) bool {
639	// filter out flags --<flag_name>
640	if strings.HasPrefix(arg, "-") {
641		return false
642	}
643	arg = strings.SplitN(arg, "=", 2)[0]
644	return strings.Contains(arg, shorthand)
645}
646
647func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error) {
648	a = args
649	name := s[2:]
650	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
651		err = f.failf("bad flag syntax: %s", s)
652		return
653	}
654	split := strings.SplitN(name, "=", 2)
655	name = split[0]
656	flag, alreadythere := f.formal[f.normalizeFlagName(name)]
657	if !alreadythere {
658		if name == "help" { // special case for nice help message.
659			f.usage()
660			return a, ErrHelp
661		}
662		err = f.failf("unknown flag: --%s", name)
663		return
664	}
665	var value string
666	if len(split) == 2 {
667		// '--flag=arg'
668		value = split[1]
669	} else if len(flag.NoOptDefVal) > 0 {
670		// '--flag' (arg was optional)
671		value = flag.NoOptDefVal
672	} else if len(a) > 0 {
673		// '--flag arg'
674		value = a[0]
675		a = a[1:]
676	} else {
677		// '--flag' (arg was required)
678		err = f.failf("flag needs an argument: %s", s)
679		return
680	}
681	err = f.setFlag(flag, value, s)
682	return
683}
684
685func (f *FlagSet) parseSingleShortArg(shorthands string, args []string) (outShorts string, outArgs []string, err error) {
686	outArgs = args
687	outShorts = shorthands[1:]
688	c := shorthands[0]
689
690	flag, alreadythere := f.shorthands[c]
691	if !alreadythere {
692		if c == 'h' { // special case for nice help message.
693			f.usage()
694			err = ErrHelp
695			return
696		}
697		//TODO continue on error
698		err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
699		return
700	}
701	var value string
702	if len(shorthands) > 2 && shorthands[1] == '=' {
703		value = shorthands[2:]
704		outShorts = ""
705	} else if len(flag.NoOptDefVal) > 0 {
706		value = flag.NoOptDefVal
707	} else if len(shorthands) > 1 {
708		value = shorthands[1:]
709		outShorts = ""
710	} else if len(args) > 0 {
711		value = args[0]
712		outArgs = args[1:]
713	} else {
714		err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
715		return
716	}
717	err = f.setFlag(flag, value, shorthands)
718	return
719}
720
721func (f *FlagSet) parseShortArg(s string, args []string) (a []string, err error) {
722	a = args
723	shorthands := s[1:]
724
725	for len(shorthands) > 0 {
726		shorthands, a, err = f.parseSingleShortArg(shorthands, args)
727		if err != nil {
728			return
729		}
730	}
731
732	return
733}
734
735func (f *FlagSet) parseArgs(args []string) (err error) {
736	for len(args) > 0 {
737		s := args[0]
738		args = args[1:]
739		if len(s) == 0 || s[0] != '-' || len(s) == 1 {
740			if !f.interspersed {
741				f.args = append(f.args, s)
742				f.args = append(f.args, args...)
743				return nil
744			}
745			f.args = append(f.args, s)
746			continue
747		}
748
749		if s[1] == '-' {
750			if len(s) == 2 { // "--" terminates the flags
751				f.argsLenAtDash = len(f.args)
752				f.args = append(f.args, args...)
753				break
754			}
755			args, err = f.parseLongArg(s, args)
756		} else {
757			args, err = f.parseShortArg(s, args)
758		}
759		if err != nil {
760			return
761		}
762	}
763	return
764}
765
766// Parse parses flag definitions from the argument list, which should not
767// include the command name.  Must be called after all flags in the FlagSet
768// are defined and before flags are accessed by the program.
769// The return value will be ErrHelp if -help was set but not defined.
770func (f *FlagSet) Parse(arguments []string) error {
771	f.parsed = true
772	f.args = make([]string, 0, len(arguments))
773	err := f.parseArgs(arguments)
774	if err != nil {
775		switch f.errorHandling {
776		case ContinueOnError:
777			return err
778		case ExitOnError:
779			os.Exit(2)
780		case PanicOnError:
781			panic(err)
782		}
783	}
784	return nil
785}
786
787// Parsed reports whether f.Parse has been called.
788func (f *FlagSet) Parsed() bool {
789	return f.parsed
790}
791
792// Parse parses the command-line flags from os.Args[1:].  Must be called
793// after all flags are defined and before flags are accessed by the program.
794func Parse() {
795	// Ignore errors; CommandLine is set for ExitOnError.
796	CommandLine.Parse(os.Args[1:])
797}
798
799// SetInterspersed sets whether to support interspersed option/non-option arguments.
800func SetInterspersed(interspersed bool) {
801	CommandLine.SetInterspersed(interspersed)
802}
803
804// Parsed returns true if the command-line flags have been parsed.
805func Parsed() bool {
806	return CommandLine.Parsed()
807}
808
809// The default set of command-line flags, parsed from os.Args.
810var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
811
812// NewFlagSet returns a new, empty flag set with the specified name and
813// error handling property.
814func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
815	f := &FlagSet{
816		name:          name,
817		errorHandling: errorHandling,
818		argsLenAtDash: -1,
819		interspersed:  true,
820	}
821	return f
822}
823
824// SetInterspersed sets whether to support interspersed option/non-option arguments.
825func (f *FlagSet) SetInterspersed(interspersed bool) {
826	f.interspersed = interspersed
827}
828
829// Init sets the name and error handling property for a flag set.
830// By default, the zero FlagSet uses an empty name and the
831// ContinueOnError error handling policy.
832func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
833	f.name = name
834	f.errorHandling = errorHandling
835	f.argsLenAtDash = -1
836}
837