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.
6 Package pflag is a drop-in replacement for Go's flag package, implementing
7 POSIX/GNU-style --flags.
9 pflag is compatible with the GNU extensions to the POSIX recommendations
10 for command-line options. See
11 http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
15 pflag is a drop-in replacement of Go's native flag package. If you import
16 pflag under the name "flag" then all code should continue to function
19 import flag "github.com/ogier/pflag"
21 There is one exception to this: if you directly instantiate the Flag struct
22 there is one more field "Shorthand" that you will need to set.
23 Most code never instantiates this struct directly, and instead uses
24 functions such as String(), BoolVar(), and Var(), and is therefore
27 Define flags using flag.String(), Bool(), Int(), etc.
29 This declares an integer flag, -flagname, stored in the pointer ip, with type *int.
30 var ip = flag.Int("flagname", 1234, "help message for flagname")
31 If you like, you can bind the flag to a variable using the Var() functions.
34 flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
36 Or you can create custom flags that satisfy the Value interface (with
37 pointer receivers) and couple them to flag parsing by
38 flag.Var(&flagVal, "name", "help message for flagname")
39 For such flags, the default value is just the initial value of the variable.
41 After all flags are defined, call
43 to parse the command line into the defined flags.
45 Flags may then be used directly. If you're using the flags themselves,
46 they 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)
50 After parsing, the arguments after the flag are available as the
51 slice flag.Args() or individually as flag.Arg(i).
52 The arguments are indexed from 0 through flag.NArg()-1.
54 The pflag package also defines some new functions that are not in flag,
55 that 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")
60 flag.BoolVarP("boolname", "b", true, "help message")
62 flag.VarP(&flagVar, "varname", "v", 1234, "help message")
63 Shorthand letters can be used with single dashes on the command line.
64 Boolean shorthand flags can be combined with other shorthand flags.
66 Command line flag syntax:
67 --flag // boolean flags only
70 Unlike the flag package, a single dash before an option means something
71 different than a double dash. Single dashes signify a series of shorthand
72 letters for flags. All but the last shorthand letter must be boolean flags.
83 Flag parsing stops after the terminator "--". Unlike the flag package,
84 flags can be interspersed with arguments anywhere on the command line
85 before this terminator.
87 Integer flags accept 1234, 0664, 0x1234 and may be negative.
88 Boolean flags (in their long form) accept 1, 0, t, f, true, false,
89 TRUE, FALSE, True, False.
90 Duration flags accept any input valid for time.ParseDuration.
92 The default set of command-line flags is controlled by
93 top-level functions. The FlagSet type allows one to define
94 independent sets of flags, such as to implement subcommands
95 in a command-line interface. The methods of FlagSet are
96 analogous to the top-level functions for the command-line
111 // ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
112 var ErrHelp = errors.New("pflag: help requested")
114 // ErrorHandling defines how to handle flag parsing errors.
115 type ErrorHandling int
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
122 // PanicOnError will panic() if an error is found when parsing flags
126 // NormalizedName is a flag name that has been normalized according to rules
127 // for the FlagSet (e.g. making '-' and '_' equivalent).
128 type NormalizedName string
130 // A FlagSet represents a set of defined flags.
131 type 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.
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
151 // A Flag represents the state of a flag.
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
166 // Value is the interface to the dynamic value stored in a flag.
167 // (The default value is represented as a string.)
168 type Value interface {
174 // sortFlags returns the flags as a slice in lexicographical sorted order.
175 func sortFlags(flags map[NormalizedName]*Flag) []*Flag {
176 list := make(sort.StringSlice, len(flags))
178 for k := range flags {
183 result := make([]*Flag, len(list))
184 for i, name := range list {
185 result[i] = flags[NormalizedName(name)]
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.
195 func (f *FlagSet) SetNormalizeFunc(n func(f *FlagSet, name string) NormalizedName) {
196 f.normalizeNameFunc = n
197 for k, v := range f.formal {
199 nname := f.normalizeFlagName(string(k))
201 v.Name = string(nname)
205 // GetNormalizeFunc returns the previously set NormalizeFunc of a function which
206 // does no translation, if not set previously.
207 func (f *FlagSet) GetNormalizeFunc() func(f *FlagSet, name string) NormalizedName {
208 if f.normalizeNameFunc != nil {
209 return f.normalizeNameFunc
211 return func(f *FlagSet, name string) NormalizedName { return NormalizedName(name) }
214 func (f *FlagSet) normalizeFlagName(name string) NormalizedName {
215 n := f.GetNormalizeFunc()
219 func (f *FlagSet) out() io.Writer {
226 // SetOutput sets the destination for usage and error messages.
227 // If output is nil, os.Stderr is used.
228 func (f *FlagSet) SetOutput(output io.Writer) {
232 // VisitAll visits the flags in lexicographical order, calling fn for each.
233 // It visits all flags, even those not set.
234 func (f *FlagSet) VisitAll(fn func(*Flag)) {
235 for _, flag := range sortFlags(f.formal) {
240 // HasFlags returns a bool to indicate if the FlagSet has any flags definied.
241 func (f *FlagSet) HasFlags() bool {
242 return len(f.formal) > 0
245 // HasAvailableFlags returns a bool to indicate if the FlagSet has any flags
246 // definied that are not hidden or deprecated.
247 func (f *FlagSet) HasAvailableFlags() bool {
248 for _, flag := range f.formal {
249 if !flag.Hidden && len(flag.Deprecated) == 0 {
256 // VisitAll visits the command-line flags in lexicographical order, calling
257 // fn for each. It visits all flags, even those not set.
258 func VisitAll(fn func(*Flag)) {
259 CommandLine.VisitAll(fn)
262 // Visit visits the flags in lexicographical order, calling fn for each.
263 // It visits only those flags that have been set.
264 func (f *FlagSet) Visit(fn func(*Flag)) {
265 for _, flag := range sortFlags(f.actual) {
270 // Visit visits the command-line flags in lexicographical order, calling fn
271 // for each. It visits only those flags that have been set.
272 func Visit(fn func(*Flag)) {
273 CommandLine.Visit(fn)
276 // Lookup returns the Flag structure of the named flag, returning nil if none exists.
277 func (f *FlagSet) Lookup(name string) *Flag {
278 return f.lookup(f.normalizeFlagName(name))
281 // lookup returns the Flag structure of the named flag, returning nil if none exists.
282 func (f *FlagSet) lookup(name NormalizedName) *Flag {
283 return f.formal[name]
286 // func to return a given type for a given flag name
287 func (f *FlagSet) getFlagType(name string, ftype string, convFunc func(sval string) (interface{}, error)) (interface{}, error) {
288 flag := f.Lookup(name)
290 err := fmt.Errorf("flag accessed but not defined: %s", name)
294 if flag.Value.Type() != ftype {
295 err := fmt.Errorf("trying to get %s value of flag of type %s", ftype, flag.Value.Type())
299 sval := flag.Value.String()
300 result, err := convFunc(sval)
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.
310 func (f *FlagSet) ArgsLenAtDash() int {
311 return f.argsLenAtDash
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.
317 func (f *FlagSet) MarkDeprecated(name string, usageMessage string) error {
318 flag := f.Lookup(name)
320 return fmt.Errorf("flag %q does not exist", name)
322 if len(usageMessage) == 0 {
323 return fmt.Errorf("deprecated message for flag %q must be set", name)
325 flag.Deprecated = usageMessage
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.
332 func (f *FlagSet) MarkShorthandDeprecated(name string, usageMessage string) error {
333 flag := f.Lookup(name)
335 return fmt.Errorf("flag %q does not exist", name)
337 if len(usageMessage) == 0 {
338 return fmt.Errorf("deprecated message for flag %q must be set", name)
340 flag.ShorthandDeprecated = usageMessage
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.
346 func (f *FlagSet) MarkHidden(name string) error {
347 flag := f.Lookup(name)
349 return fmt.Errorf("flag %q does not exist", name)
355 // Lookup returns the Flag structure of the named command-line flag,
356 // returning nil if none exists.
357 func Lookup(name string) *Flag {
358 return CommandLine.Lookup(name)
361 // Set sets the value of the named flag.
362 func (f *FlagSet) Set(name, value string) error {
363 normalName := f.normalizeFlagName(name)
364 flag, ok := f.formal[normalName]
366 return fmt.Errorf("no such flag -%v", name)
368 err := flag.Value.Set(value)
373 f.actual = make(map[NormalizedName]*Flag)
375 f.actual[normalName] = flag
377 if len(flag.Deprecated) > 0 {
378 fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
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.
386 func (f *FlagSet) SetAnnotation(name, key string, values []string) error {
387 normalName := f.normalizeFlagName(name)
388 flag, ok := f.formal[normalName]
390 return fmt.Errorf("no such flag -%v", name)
392 if flag.Annotations == nil {
393 flag.Annotations = map[string][]string{}
395 flag.Annotations[key] = values
399 // Changed returns true if the flag was explicitly set during Parse() and false
401 func (f *FlagSet) Changed(name string) bool {
402 flag := f.Lookup(name)
403 // If a flag doesn't exist, it wasn't changed....
410 // Set sets the value of the named command-line flag.
411 func Set(name, value string) error {
412 return CommandLine.Set(name, value)
415 // PrintDefaults prints, to standard error unless configured
416 // otherwise, the default values of all defined flags in the set.
417 func (f *FlagSet) PrintDefaults() {
418 usages := f.FlagUsages()
419 fmt.Fprint(f.out(), usages)
422 // defaultIsZeroValue returns true if the default value for this flag represents
424 func (f *Flag) defaultIsZeroValue() bool {
425 switch f.Value.(type) {
427 return f.DefValue == "false"
429 // Beginning in Go 1.7, duration zero values are "0s"
430 return f.DefValue == "0" || f.DefValue == "0s"
431 case *intValue, *int8Value, *int32Value, *int64Value, *uintValue, *uint8Value, *uint16Value, *uint32Value, *uint64Value, *countValue, *float32Value, *float64Value:
432 return f.DefValue == "0"
434 return f.DefValue == ""
435 case *ipValue, *ipMaskValue, *ipNetValue:
436 return f.DefValue == "<nil>"
437 case *intSliceValue, *stringSliceValue, *stringArrayValue:
438 return f.DefValue == "[]"
440 switch f.Value.String() {
454 // UnquoteUsage extracts a back-quoted name from the usage
455 // string for a flag and returns it and the un-quoted usage.
456 // Given "a `name` to show" it returns ("name", "a name to show").
457 // If there are no back quotes, the name is an educated guess of the
458 // type of the flag's value, or the empty string if the flag is boolean.
459 func UnquoteUsage(flag *Flag) (name string, usage string) {
460 // Look for a back-quoted name, but avoid the strings package.
462 for i := 0; i < len(usage); i++ {
464 for j := i + 1; j < len(usage); j++ {
466 name = usage[i+1 : j]
467 usage = usage[:i] + name + usage[j+1:]
471 break // Only one back quote; use type name.
475 name = flag.Value.Type()
490 // Splits the string `s` on whitespace into an initial substring up to
491 // `i` runes in length and the remainder. Will go `slop` over `i` if
492 // that encompasses the entire string (which allows the caller to
493 // avoid short orphan words on the final line).
494 func wrapN(i, slop int, s string) (string, string) {
499 w := strings.LastIndexAny(s[:i], " \t")
504 return s[:w], s[w+1:]
507 // Wraps the string `s` to a maximum width `w` with leading indent
508 // `i`. The first line is not indented (this is assumed to be done by
509 // caller). Pass `w` == 0 to do no wrapping
510 func wrap(i, w int, s string) string {
515 // space between indent i and end of line width w into which
516 // we should wrap the text.
521 // Not enough space for sensible wrapping. Wrap as a block on
522 // the next line instead.
526 r += "\n" + strings.Repeat(" ", i)
528 // If still not enough space then don't even try to wrap.
533 // Try to avoid short orphan words on the final line, by
534 // allowing wrapN to go a bit over if that would fit in the
535 // remainder of the line.
539 // Handle first line, which is indented by the caller (or the
540 // special case above)
541 l, s = wrapN(wrap, slop, s)
548 t, s = wrapN(wrap, slop, s)
549 r = r + "\n" + strings.Repeat(" ", i) + t
556 // FlagUsagesWrapped returns a string containing the usage information
557 // for all flags in the FlagSet. Wrapped to `cols` columns (0 for no
559 func (f *FlagSet) FlagUsagesWrapped(cols int) string {
560 x := new(bytes.Buffer)
562 lines := make([]string, 0, len(f.formal))
565 f.VisitAll(func(flag *Flag) {
566 if len(flag.Deprecated) > 0 || flag.Hidden {
571 if len(flag.Shorthand) > 0 && len(flag.ShorthandDeprecated) == 0 {
572 line = fmt.Sprintf(" -%s, --%s", flag.Shorthand, flag.Name)
574 line = fmt.Sprintf(" --%s", flag.Name)
577 varname, usage := UnquoteUsage(flag)
578 if len(varname) > 0 {
579 line += " " + varname
581 if len(flag.NoOptDefVal) > 0 {
582 switch flag.Value.Type() {
584 line += fmt.Sprintf("[=\"%s\"]", flag.NoOptDefVal)
586 if flag.NoOptDefVal != "true" {
587 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
590 line += fmt.Sprintf("[=%s]", flag.NoOptDefVal)
594 // This special character will be replaced with spacing once the
595 // correct alignment is calculated
597 if len(line) > maxlen {
602 if !flag.defaultIsZeroValue() {
603 if flag.Value.Type() == "string" {
604 line += fmt.Sprintf(" (default \"%s\")", flag.DefValue)
606 line += fmt.Sprintf(" (default %s)", flag.DefValue)
610 lines = append(lines, line)
613 for _, line := range lines {
614 sidx := strings.Index(line, "\x00")
615 spacing := strings.Repeat(" ", maxlen-sidx)
616 // maxlen + 2 comes from + 1 for the \x00 and + 1 for the (deliberate) off-by-one in maxlen-sidx
617 fmt.Fprintln(x, line[:sidx], spacing, wrap(maxlen+2, cols, line[sidx+1:]))
623 // FlagUsages returns a string containing the usage information for all flags in
625 func (f *FlagSet) FlagUsages() string {
626 return f.FlagUsagesWrapped(0)
629 // PrintDefaults prints to standard error the default values of all defined command-line flags.
630 func PrintDefaults() {
631 CommandLine.PrintDefaults()
634 // defaultUsage is the default function to print a usage message.
635 func defaultUsage(f *FlagSet) {
636 fmt.Fprintf(f.out(), "Usage of %s:\n", f.name)
640 // NOTE: Usage is not just defaultUsage(CommandLine)
641 // because it serves (via godoc flag Usage) as the example
642 // for how to write your own usage function.
644 // Usage prints to standard error a usage message documenting all defined command-line flags.
645 // The function is a variable that may be changed to point to a custom function.
646 // By default it prints a simple header and calls PrintDefaults; for details about the
647 // format of the output and how to control it, see the documentation for PrintDefaults.
649 fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
653 // NFlag returns the number of flags that have been set.
654 func (f *FlagSet) NFlag() int { return len(f.actual) }
656 // NFlag returns the number of command-line flags that have been set.
657 func NFlag() int { return len(CommandLine.actual) }
659 // Arg returns the i'th argument. Arg(0) is the first remaining argument
660 // after flags have been processed.
661 func (f *FlagSet) Arg(i int) string {
662 if i < 0 || i >= len(f.args) {
668 // Arg returns the i'th command-line argument. Arg(0) is the first remaining argument
669 // after flags have been processed.
670 func Arg(i int) string {
671 return CommandLine.Arg(i)
674 // NArg is the number of arguments remaining after flags have been processed.
675 func (f *FlagSet) NArg() int { return len(f.args) }
677 // NArg is the number of arguments remaining after flags have been processed.
678 func NArg() int { return len(CommandLine.args) }
680 // Args returns the non-flag arguments.
681 func (f *FlagSet) Args() []string { return f.args }
683 // Args returns the non-flag command-line arguments.
684 func Args() []string { return CommandLine.args }
686 // Var defines a flag with the specified name and usage string. The type and
687 // value of the flag are represented by the first argument, of type Value, which
688 // typically holds a user-defined implementation of Value. For instance, the
689 // caller could create a flag that turns a comma-separated string into a slice
690 // of strings by giving the slice the methods of Value; in particular, Set would
691 // decompose the comma-separated string into the slice.
692 func (f *FlagSet) Var(value Value, name string, usage string) {
693 f.VarP(value, name, "", usage)
696 // VarPF is like VarP, but returns the flag created
697 func (f *FlagSet) VarPF(value Value, name, shorthand, usage string) *Flag {
698 // Remember the default value as a string; it won't change.
701 Shorthand: shorthand,
704 DefValue: value.String(),
710 // VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
711 func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
712 f.VarPF(value, name, shorthand, usage)
715 // AddFlag will add the flag to the FlagSet
716 func (f *FlagSet) AddFlag(flag *Flag) {
717 // Call normalizeFlagName function only once
718 normalizedFlagName := f.normalizeFlagName(flag.Name)
720 _, alreadythere := f.formal[normalizedFlagName]
722 msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
723 fmt.Fprintln(f.out(), msg)
724 panic(msg) // Happens only if flags are declared with identical names
727 f.formal = make(map[NormalizedName]*Flag)
730 flag.Name = string(normalizedFlagName)
731 f.formal[normalizedFlagName] = flag
733 if len(flag.Shorthand) == 0 {
736 if len(flag.Shorthand) > 1 {
737 fmt.Fprintf(f.out(), "%s shorthand more than ASCII character: %s\n", f.name, flag.Shorthand)
738 panic("shorthand is more than one character")
740 if f.shorthands == nil {
741 f.shorthands = make(map[byte]*Flag)
743 c := flag.Shorthand[0]
744 old, alreadythere := f.shorthands[c]
746 fmt.Fprintf(f.out(), "%s shorthand reused: %q for %s already used for %s\n", f.name, c, flag.Name, old.Name)
747 panic("shorthand redefinition")
749 f.shorthands[c] = flag
752 // AddFlagSet adds one FlagSet to another. If a flag is already present in f
753 // the flag from newSet will be ignored
754 func (f *FlagSet) AddFlagSet(newSet *FlagSet) {
758 newSet.VisitAll(func(flag *Flag) {
759 if f.Lookup(flag.Name) == nil {
765 // Var defines a flag with the specified name and usage string. The type and
766 // value of the flag are represented by the first argument, of type Value, which
767 // typically holds a user-defined implementation of Value. For instance, the
768 // caller could create a flag that turns a comma-separated string into a slice
769 // of strings by giving the slice the methods of Value; in particular, Set would
770 // decompose the comma-separated string into the slice.
771 func Var(value Value, name string, usage string) {
772 CommandLine.VarP(value, name, "", usage)
775 // VarP is like Var, but accepts a shorthand letter that can be used after a single dash.
776 func VarP(value Value, name, shorthand, usage string) {
777 CommandLine.VarP(value, name, shorthand, usage)
780 // failf prints to standard error a formatted error and usage message and
781 // returns the error.
782 func (f *FlagSet) failf(format string, a ...interface{}) error {
783 err := fmt.Errorf(format, a...)
784 fmt.Fprintln(f.out(), err)
789 // usage calls the Usage method for the flag set, or the usage function if
790 // the flag set is CommandLine.
791 func (f *FlagSet) usage() {
792 if f == CommandLine {
794 } else if f.Usage == nil {
801 func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) error {
802 if err := flag.Value.Set(value); err != nil {
803 return f.failf("invalid argument %q for %s: %v", value, origArg, err)
805 // mark as visited for Visit()
807 f.actual = make(map[NormalizedName]*Flag)
809 f.actual[f.normalizeFlagName(flag.Name)] = flag
811 if len(flag.Deprecated) > 0 {
812 fmt.Fprintf(os.Stderr, "Flag --%s has been deprecated, %s\n", flag.Name, flag.Deprecated)
814 if len(flag.ShorthandDeprecated) > 0 && containsShorthand(origArg, flag.Shorthand) {
815 fmt.Fprintf(os.Stderr, "Flag shorthand -%s has been deprecated, %s\n", flag.Shorthand, flag.ShorthandDeprecated)
820 func containsShorthand(arg, shorthand string) bool {
821 // filter out flags --<flag_name>
822 if strings.HasPrefix(arg, "-") {
825 arg = strings.SplitN(arg, "=", 2)[0]
826 return strings.Contains(arg, shorthand)
829 func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) {
832 if len(name) == 0 || name[0] == '-' || name[0] == '=' {
833 err = f.failf("bad flag syntax: %s", s)
836 split := strings.SplitN(name, "=", 2)
838 flag, alreadythere := f.formal[f.normalizeFlagName(name)]
840 if name == "help" { // special case for nice help message.
844 err = f.failf("unknown flag: --%s", name)
851 } else if len(flag.NoOptDefVal) > 0 {
852 // '--flag' (arg was optional)
853 value = flag.NoOptDefVal
854 } else if len(a) > 0 {
859 // '--flag' (arg was required)
860 err = f.failf("flag needs an argument: %s", s)
863 err = fn(flag, value, s)
867 func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) {
868 if strings.HasPrefix(shorthands, "test.") {
872 outShorts = shorthands[1:]
875 flag, alreadythere := f.shorthands[c]
877 if c == 'h' { // special case for nice help message.
882 //TODO continue on error
883 err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
887 if len(shorthands) > 2 && shorthands[1] == '=' {
888 value = shorthands[2:]
890 } else if len(flag.NoOptDefVal) > 0 {
891 value = flag.NoOptDefVal
892 } else if len(shorthands) > 1 {
893 value = shorthands[1:]
895 } else if len(args) > 0 {
899 err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
902 err = fn(flag, value, shorthands)
906 func (f *FlagSet) parseShortArg(s string, args []string, fn parseFunc) (a []string, err error) {
910 for len(shorthands) > 0 {
911 shorthands, a, err = f.parseSingleShortArg(shorthands, args, fn)
920 func (f *FlagSet) parseArgs(args []string, fn parseFunc) (err error) {
924 if len(s) == 0 || s[0] != '-' || len(s) == 1 {
926 f.args = append(f.args, s)
927 f.args = append(f.args, args...)
930 f.args = append(f.args, s)
935 if len(s) == 2 { // "--" terminates the flags
936 f.argsLenAtDash = len(f.args)
937 f.args = append(f.args, args...)
940 args, err = f.parseLongArg(s, args, fn)
942 args, err = f.parseShortArg(s, args, fn)
951 // Parse parses flag definitions from the argument list, which should not
952 // include the command name. Must be called after all flags in the FlagSet
953 // are defined and before flags are accessed by the program.
954 // The return value will be ErrHelp if -help was set but not defined.
955 func (f *FlagSet) Parse(arguments []string) error {
957 f.args = make([]string, 0, len(arguments))
959 assign := func(flag *Flag, value, origArg string) error {
960 return f.setFlag(flag, value, origArg)
963 err := f.parseArgs(arguments, assign)
965 switch f.errorHandling {
966 case ContinueOnError:
977 type parseFunc func(flag *Flag, value, origArg string) error
979 // ParseAll parses flag definitions from the argument list, which should not
980 // include the command name. The arguments for fn are flag and value. Must be
981 // called after all flags in the FlagSet are defined and before flags are
982 // accessed by the program. The return value will be ErrHelp if -help was set
984 func (f *FlagSet) ParseAll(arguments []string, fn func(flag *Flag, value string) error) error {
986 f.args = make([]string, 0, len(arguments))
988 assign := func(flag *Flag, value, origArg string) error {
989 return fn(flag, value)
992 err := f.parseArgs(arguments, assign)
994 switch f.errorHandling {
995 case ContinueOnError:
1006 // Parsed reports whether f.Parse has been called.
1007 func (f *FlagSet) Parsed() bool {
1011 // Parse parses the command-line flags from os.Args[1:]. Must be called
1012 // after all flags are defined and before flags are accessed by the program.
1014 // Ignore errors; CommandLine is set for ExitOnError.
1015 CommandLine.Parse(os.Args[1:])
1018 // ParseAll parses the command-line flags from os.Args[1:] and called fn for each.
1019 // The arguments for fn are flag and value. Must be called after all flags are
1020 // defined and before flags are accessed by the program.
1021 func ParseAll(fn func(flag *Flag, value string) error) {
1022 // Ignore errors; CommandLine is set for ExitOnError.
1023 CommandLine.ParseAll(os.Args[1:], fn)
1026 // SetInterspersed sets whether to support interspersed option/non-option arguments.
1027 func SetInterspersed(interspersed bool) {
1028 CommandLine.SetInterspersed(interspersed)
1031 // Parsed returns true if the command-line flags have been parsed.
1032 func Parsed() bool {
1033 return CommandLine.Parsed()
1036 // CommandLine is the default set of command-line flags, parsed from os.Args.
1037 var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
1039 // NewFlagSet returns a new, empty flag set with the specified name and
1040 // error handling property.
1041 func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
1044 errorHandling: errorHandling,
1051 // SetInterspersed sets whether to support interspersed option/non-option arguments.
1052 func (f *FlagSet) SetInterspersed(interspersed bool) {
1053 f.interspersed = interspersed
1056 // Init sets the name and error handling property for a flag set.
1057 // By default, the zero FlagSet uses an empty name and the
1058 // ContinueOnError error handling policy.
1059 func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
1061 f.errorHandling = errorHandling
1062 f.argsLenAtDash = -1