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 flag implements command-line flag parsing.
7
8# Usage
9
10Define flags using [flag.String], [Bool], [Int], etc.
11
12This declares an integer flag, -n, stored in the pointer nFlag, with type *int:
13
14	import "flag"
15	var nFlag = flag.Int("n", 1234, "help message for flag n")
16
17If you like, you can bind the flag to a variable using the Var() functions.
18
19	var flagvar int
20	func init() {
21		flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
22	}
23
24Or you can create custom flags that satisfy the Value interface (with
25pointer receivers) and couple them to flag parsing by
26
27	flag.Var(&flagVal, "name", "help message for flagname")
28
29For such flags, the default value is just the initial value of the variable.
30
31After all flags are defined, call
32
33	flag.Parse()
34
35to parse the command line into the defined flags.
36
37Flags may then be used directly. If you're using the flags themselves,
38they are all pointers; if you bind to variables, they're values.
39
40	fmt.Println("ip has value ", *ip)
41	fmt.Println("flagvar has value ", flagvar)
42
43After parsing, the arguments following the flags are available as the
44slice [flag.Args] or individually as [flag.Arg](i).
45The arguments are indexed from 0 through [flag.NArg]-1.
46
47# Command line flag syntax
48
49The following forms are permitted:
50
51	-flag
52	--flag   // double dashes are also permitted
53	-flag=x
54	-flag x  // non-boolean flags only
55
56One or two dashes may be used; they are equivalent.
57The last form is not permitted for boolean flags because the
58meaning of the command
59
60	cmd -x *
61
62where * is a Unix shell wildcard, will change if there is a file
63called 0, false, etc. You must use the -flag=false form to turn
64off a boolean flag.
65
66Flag parsing stops just before the first non-flag argument
67("-" is a non-flag argument) or after the terminator "--".
68
69Integer flags accept 1234, 0664, 0x1234 and may be negative.
70Boolean flags may be:
71
72	1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False
73
74Duration flags accept any input valid for time.ParseDuration.
75
76The default set of command-line flags is controlled by
77top-level functions.  The [FlagSet] type allows one to define
78independent sets of flags, such as to implement subcommands
79in a command-line interface. The methods of [FlagSet] are
80analogous to the top-level functions for the command-line
81flag set.
82*/
83package flag
84
85import (
86	"encoding"
87	"errors"
88	"fmt"
89	"io"
90	"os"
91	"reflect"
92	"runtime"
93	"slices"
94	"strconv"
95	"strings"
96	"time"
97)
98
99// ErrHelp is the error returned if the -help or -h flag is invoked
100// but no such flag is defined.
101var ErrHelp = errors.New("flag: help requested")
102
103// errParse is returned by Set if a flag's value fails to parse, such as with an invalid integer for Int.
104// It then gets wrapped through failf to provide more information.
105var errParse = errors.New("parse error")
106
107// errRange is returned by Set if a flag's value is out of range.
108// It then gets wrapped through failf to provide more information.
109var errRange = errors.New("value out of range")
110
111func numError(err error) error {
112	ne, ok := err.(*strconv.NumError)
113	if !ok {
114		return err
115	}
116	if ne.Err == strconv.ErrSyntax {
117		return errParse
118	}
119	if ne.Err == strconv.ErrRange {
120		return errRange
121	}
122	return err
123}
124
125// -- bool Value
126type boolValue bool
127
128func newBoolValue(val bool, p *bool) *boolValue {
129	*p = val
130	return (*boolValue)(p)
131}
132
133func (b *boolValue) Set(s string) error {
134	v, err := strconv.ParseBool(s)
135	if err != nil {
136		err = errParse
137	}
138	*b = boolValue(v)
139	return err
140}
141
142func (b *boolValue) Get() any { return bool(*b) }
143
144func (b *boolValue) String() string { return strconv.FormatBool(bool(*b)) }
145
146func (b *boolValue) IsBoolFlag() bool { return true }
147
148// optional interface to indicate boolean flags that can be
149// supplied without "=value" text
150type boolFlag interface {
151	Value
152	IsBoolFlag() bool
153}
154
155// -- int Value
156type intValue int
157
158func newIntValue(val int, p *int) *intValue {
159	*p = val
160	return (*intValue)(p)
161}
162
163func (i *intValue) Set(s string) error {
164	v, err := strconv.ParseInt(s, 0, strconv.IntSize)
165	if err != nil {
166		err = numError(err)
167	}
168	*i = intValue(v)
169	return err
170}
171
172func (i *intValue) Get() any { return int(*i) }
173
174func (i *intValue) String() string { return strconv.Itoa(int(*i)) }
175
176// -- int64 Value
177type int64Value int64
178
179func newInt64Value(val int64, p *int64) *int64Value {
180	*p = val
181	return (*int64Value)(p)
182}
183
184func (i *int64Value) Set(s string) error {
185	v, err := strconv.ParseInt(s, 0, 64)
186	if err != nil {
187		err = numError(err)
188	}
189	*i = int64Value(v)
190	return err
191}
192
193func (i *int64Value) Get() any { return int64(*i) }
194
195func (i *int64Value) String() string { return strconv.FormatInt(int64(*i), 10) }
196
197// -- uint Value
198type uintValue uint
199
200func newUintValue(val uint, p *uint) *uintValue {
201	*p = val
202	return (*uintValue)(p)
203}
204
205func (i *uintValue) Set(s string) error {
206	v, err := strconv.ParseUint(s, 0, strconv.IntSize)
207	if err != nil {
208		err = numError(err)
209	}
210	*i = uintValue(v)
211	return err
212}
213
214func (i *uintValue) Get() any { return uint(*i) }
215
216func (i *uintValue) String() string { return strconv.FormatUint(uint64(*i), 10) }
217
218// -- uint64 Value
219type uint64Value uint64
220
221func newUint64Value(val uint64, p *uint64) *uint64Value {
222	*p = val
223	return (*uint64Value)(p)
224}
225
226func (i *uint64Value) Set(s string) error {
227	v, err := strconv.ParseUint(s, 0, 64)
228	if err != nil {
229		err = numError(err)
230	}
231	*i = uint64Value(v)
232	return err
233}
234
235func (i *uint64Value) Get() any { return uint64(*i) }
236
237func (i *uint64Value) String() string { return strconv.FormatUint(uint64(*i), 10) }
238
239// -- string Value
240type stringValue string
241
242func newStringValue(val string, p *string) *stringValue {
243	*p = val
244	return (*stringValue)(p)
245}
246
247func (s *stringValue) Set(val string) error {
248	*s = stringValue(val)
249	return nil
250}
251
252func (s *stringValue) Get() any { return string(*s) }
253
254func (s *stringValue) String() string { return string(*s) }
255
256// -- float64 Value
257type float64Value float64
258
259func newFloat64Value(val float64, p *float64) *float64Value {
260	*p = val
261	return (*float64Value)(p)
262}
263
264func (f *float64Value) Set(s string) error {
265	v, err := strconv.ParseFloat(s, 64)
266	if err != nil {
267		err = numError(err)
268	}
269	*f = float64Value(v)
270	return err
271}
272
273func (f *float64Value) Get() any { return float64(*f) }
274
275func (f *float64Value) String() string { return strconv.FormatFloat(float64(*f), 'g', -1, 64) }
276
277// -- time.Duration Value
278type durationValue time.Duration
279
280func newDurationValue(val time.Duration, p *time.Duration) *durationValue {
281	*p = val
282	return (*durationValue)(p)
283}
284
285func (d *durationValue) Set(s string) error {
286	v, err := time.ParseDuration(s)
287	if err != nil {
288		err = errParse
289	}
290	*d = durationValue(v)
291	return err
292}
293
294func (d *durationValue) Get() any { return time.Duration(*d) }
295
296func (d *durationValue) String() string { return (*time.Duration)(d).String() }
297
298// -- encoding.TextUnmarshaler Value
299type textValue struct{ p encoding.TextUnmarshaler }
300
301func newTextValue(val encoding.TextMarshaler, p encoding.TextUnmarshaler) textValue {
302	ptrVal := reflect.ValueOf(p)
303	if ptrVal.Kind() != reflect.Ptr {
304		panic("variable value type must be a pointer")
305	}
306	defVal := reflect.ValueOf(val)
307	if defVal.Kind() == reflect.Ptr {
308		defVal = defVal.Elem()
309	}
310	if defVal.Type() != ptrVal.Type().Elem() {
311		panic(fmt.Sprintf("default type does not match variable type: %v != %v", defVal.Type(), ptrVal.Type().Elem()))
312	}
313	ptrVal.Elem().Set(defVal)
314	return textValue{p}
315}
316
317func (v textValue) Set(s string) error {
318	return v.p.UnmarshalText([]byte(s))
319}
320
321func (v textValue) Get() interface{} {
322	return v.p
323}
324
325func (v textValue) String() string {
326	if m, ok := v.p.(encoding.TextMarshaler); ok {
327		if b, err := m.MarshalText(); err == nil {
328			return string(b)
329		}
330	}
331	return ""
332}
333
334// -- func Value
335type funcValue func(string) error
336
337func (f funcValue) Set(s string) error { return f(s) }
338
339func (f funcValue) String() string { return "" }
340
341// -- boolFunc Value
342type boolFuncValue func(string) error
343
344func (f boolFuncValue) Set(s string) error { return f(s) }
345
346func (f boolFuncValue) String() string { return "" }
347
348func (f boolFuncValue) IsBoolFlag() bool { return true }
349
350// Value is the interface to the dynamic value stored in a flag.
351// (The default value is represented as a string.)
352//
353// If a Value has an IsBoolFlag() bool method returning true,
354// the command-line parser makes -name equivalent to -name=true
355// rather than using the next command-line argument.
356//
357// Set is called once, in command line order, for each flag present.
358// The flag package may call the [String] method with a zero-valued receiver,
359// such as a nil pointer.
360type Value interface {
361	String() string
362	Set(string) error
363}
364
365// Getter is an interface that allows the contents of a [Value] to be retrieved.
366// It wraps the [Value] interface, rather than being part of it, because it
367// appeared after Go 1 and its compatibility rules. All [Value] types provided
368// by this package satisfy the [Getter] interface, except the type used by [Func].
369type Getter interface {
370	Value
371	Get() any
372}
373
374// ErrorHandling defines how [FlagSet.Parse] behaves if the parse fails.
375type ErrorHandling int
376
377// These constants cause [FlagSet.Parse] to behave as described if the parse fails.
378const (
379	ContinueOnError ErrorHandling = iota // Return a descriptive error.
380	ExitOnError                          // Call os.Exit(2) or for -h/-help Exit(0).
381	PanicOnError                         // Call panic with a descriptive error.
382)
383
384// A FlagSet represents a set of defined flags. The zero value of a FlagSet
385// has no name and has [ContinueOnError] error handling.
386//
387// [Flag] names must be unique within a FlagSet. An attempt to define a flag whose
388// name is already in use will cause a panic.
389type FlagSet struct {
390	// Usage is the function called when an error occurs while parsing flags.
391	// The field is a function (not a method) that may be changed to point to
392	// a custom error handler. What happens after Usage is called depends
393	// on the ErrorHandling setting; for the command line, this defaults
394	// to ExitOnError, which exits the program after calling Usage.
395	Usage func()
396
397	name          string
398	parsed        bool
399	actual        map[string]*Flag
400	formal        map[string]*Flag
401	args          []string // arguments after flags
402	errorHandling ErrorHandling
403	output        io.Writer         // nil means stderr; use Output() accessor
404	undef         map[string]string // flags which didn't exist at the time of Set
405}
406
407// A Flag represents the state of a flag.
408type Flag struct {
409	Name     string // name as it appears on command line
410	Usage    string // help message
411	Value    Value  // value as set
412	DefValue string // default value (as text); for usage message
413}
414
415// sortFlags returns the flags as a slice in lexicographical sorted order.
416func sortFlags(flags map[string]*Flag) []*Flag {
417	result := make([]*Flag, len(flags))
418	i := 0
419	for _, f := range flags {
420		result[i] = f
421		i++
422	}
423	slices.SortFunc(result, func(a, b *Flag) int {
424		return strings.Compare(a.Name, b.Name)
425	})
426	return result
427}
428
429// Output returns the destination for usage and error messages. [os.Stderr] is returned if
430// output was not set or was set to nil.
431func (f *FlagSet) Output() io.Writer {
432	if f.output == nil {
433		return os.Stderr
434	}
435	return f.output
436}
437
438// Name returns the name of the flag set.
439func (f *FlagSet) Name() string {
440	return f.name
441}
442
443// ErrorHandling returns the error handling behavior of the flag set.
444func (f *FlagSet) ErrorHandling() ErrorHandling {
445	return f.errorHandling
446}
447
448// SetOutput sets the destination for usage and error messages.
449// If output is nil, [os.Stderr] is used.
450func (f *FlagSet) SetOutput(output io.Writer) {
451	f.output = output
452}
453
454// VisitAll visits the flags in lexicographical order, calling fn for each.
455// It visits all flags, even those not set.
456func (f *FlagSet) VisitAll(fn func(*Flag)) {
457	for _, flag := range sortFlags(f.formal) {
458		fn(flag)
459	}
460}
461
462// VisitAll visits the command-line flags in lexicographical order, calling
463// fn for each. It visits all flags, even those not set.
464func VisitAll(fn func(*Flag)) {
465	CommandLine.VisitAll(fn)
466}
467
468// Visit visits the flags in lexicographical order, calling fn for each.
469// It visits only those flags that have been set.
470func (f *FlagSet) Visit(fn func(*Flag)) {
471	for _, flag := range sortFlags(f.actual) {
472		fn(flag)
473	}
474}
475
476// Visit visits the command-line flags in lexicographical order, calling fn
477// for each. It visits only those flags that have been set.
478func Visit(fn func(*Flag)) {
479	CommandLine.Visit(fn)
480}
481
482// Lookup returns the [Flag] structure of the named flag, returning nil if none exists.
483func (f *FlagSet) Lookup(name string) *Flag {
484	return f.formal[name]
485}
486
487// Lookup returns the [Flag] structure of the named command-line flag,
488// returning nil if none exists.
489func Lookup(name string) *Flag {
490	return CommandLine.formal[name]
491}
492
493// Set sets the value of the named flag.
494func (f *FlagSet) Set(name, value string) error {
495	return f.set(name, value)
496}
497func (f *FlagSet) set(name, value string) error {
498	flag, ok := f.formal[name]
499	if !ok {
500		// Remember that a flag that isn't defined is being set.
501		// We return an error in this case, but in addition if
502		// subsequently that flag is defined, we want to panic
503		// at the definition point.
504		// This is a problem which occurs if both the definition
505		// and the Set call are in init code and for whatever
506		// reason the init code changes evaluation order.
507		// See issue 57411.
508		_, file, line, ok := runtime.Caller(2)
509		if !ok {
510			file = "?"
511			line = 0
512		}
513		if f.undef == nil {
514			f.undef = map[string]string{}
515		}
516		f.undef[name] = fmt.Sprintf("%s:%d", file, line)
517
518		return fmt.Errorf("no such flag -%v", name)
519	}
520	err := flag.Value.Set(value)
521	if err != nil {
522		return err
523	}
524	if f.actual == nil {
525		f.actual = make(map[string]*Flag)
526	}
527	f.actual[name] = flag
528	return nil
529}
530
531// Set sets the value of the named command-line flag.
532func Set(name, value string) error {
533	return CommandLine.set(name, value)
534}
535
536// isZeroValue determines whether the string represents the zero
537// value for a flag.
538func isZeroValue(flag *Flag, value string) (ok bool, err error) {
539	// Build a zero value of the flag's Value type, and see if the
540	// result of calling its String method equals the value passed in.
541	// This works unless the Value type is itself an interface type.
542	typ := reflect.TypeOf(flag.Value)
543	var z reflect.Value
544	if typ.Kind() == reflect.Pointer {
545		z = reflect.New(typ.Elem())
546	} else {
547		z = reflect.Zero(typ)
548	}
549	// Catch panics calling the String method, which shouldn't prevent the
550	// usage message from being printed, but that we should report to the
551	// user so that they know to fix their code.
552	defer func() {
553		if e := recover(); e != nil {
554			if typ.Kind() == reflect.Pointer {
555				typ = typ.Elem()
556			}
557			err = fmt.Errorf("panic calling String method on zero %v for flag %s: %v", typ, flag.Name, e)
558		}
559	}()
560	return value == z.Interface().(Value).String(), nil
561}
562
563// UnquoteUsage extracts a back-quoted name from the usage
564// string for a flag and returns it and the un-quoted usage.
565// Given "a `name` to show" it returns ("name", "a name to show").
566// If there are no back quotes, the name is an educated guess of the
567// type of the flag's value, or the empty string if the flag is boolean.
568func UnquoteUsage(flag *Flag) (name string, usage string) {
569	// Look for a back-quoted name, but avoid the strings package.
570	usage = flag.Usage
571	for i := 0; i < len(usage); i++ {
572		if usage[i] == '`' {
573			for j := i + 1; j < len(usage); j++ {
574				if usage[j] == '`' {
575					name = usage[i+1 : j]
576					usage = usage[:i] + name + usage[j+1:]
577					return name, usage
578				}
579			}
580			break // Only one back quote; use type name.
581		}
582	}
583	// No explicit name, so use type if we can find one.
584	name = "value"
585	switch fv := flag.Value.(type) {
586	case boolFlag:
587		if fv.IsBoolFlag() {
588			name = ""
589		}
590	case *durationValue:
591		name = "duration"
592	case *float64Value:
593		name = "float"
594	case *intValue, *int64Value:
595		name = "int"
596	case *stringValue:
597		name = "string"
598	case *uintValue, *uint64Value:
599		name = "uint"
600	}
601	return
602}
603
604// PrintDefaults prints, to standard error unless configured otherwise, the
605// default values of all defined command-line flags in the set. See the
606// documentation for the global function PrintDefaults for more information.
607func (f *FlagSet) PrintDefaults() {
608	var isZeroValueErrs []error
609	f.VisitAll(func(flag *Flag) {
610		var b strings.Builder
611		fmt.Fprintf(&b, "  -%s", flag.Name) // Two spaces before -; see next two comments.
612		name, usage := UnquoteUsage(flag)
613		if len(name) > 0 {
614			b.WriteString(" ")
615			b.WriteString(name)
616		}
617		// Boolean flags of one ASCII letter are so common we
618		// treat them specially, putting their usage on the same line.
619		if b.Len() <= 4 { // space, space, '-', 'x'.
620			b.WriteString("\t")
621		} else {
622			// Four spaces before the tab triggers good alignment
623			// for both 4- and 8-space tab stops.
624			b.WriteString("\n    \t")
625		}
626		b.WriteString(strings.ReplaceAll(usage, "\n", "\n    \t"))
627
628		// Print the default value only if it differs to the zero value
629		// for this flag type.
630		if isZero, err := isZeroValue(flag, flag.DefValue); err != nil {
631			isZeroValueErrs = append(isZeroValueErrs, err)
632		} else if !isZero {
633			if _, ok := flag.Value.(*stringValue); ok {
634				// put quotes on the value
635				fmt.Fprintf(&b, " (default %q)", flag.DefValue)
636			} else {
637				fmt.Fprintf(&b, " (default %v)", flag.DefValue)
638			}
639		}
640		fmt.Fprint(f.Output(), b.String(), "\n")
641	})
642	// If calling String on any zero flag.Values triggered a panic, print
643	// the messages after the full set of defaults so that the programmer
644	// knows to fix the panic.
645	if errs := isZeroValueErrs; len(errs) > 0 {
646		fmt.Fprintln(f.Output())
647		for _, err := range errs {
648			fmt.Fprintln(f.Output(), err)
649		}
650	}
651}
652
653// PrintDefaults prints, to standard error unless configured otherwise,
654// a usage message showing the default settings of all defined
655// command-line flags.
656// For an integer valued flag x, the default output has the form
657//
658//	-x int
659//		usage-message-for-x (default 7)
660//
661// The usage message will appear on a separate line for anything but
662// a bool flag with a one-byte name. For bool flags, the type is
663// omitted and if the flag name is one byte the usage message appears
664// on the same line. The parenthetical default is omitted if the
665// default is the zero value for the type. The listed type, here int,
666// can be changed by placing a back-quoted name in the flag's usage
667// string; the first such item in the message is taken to be a parameter
668// name to show in the message and the back quotes are stripped from
669// the message when displayed. For instance, given
670//
671//	flag.String("I", "", "search `directory` for include files")
672//
673// the output will be
674//
675//	-I directory
676//		search directory for include files.
677//
678// To change the destination for flag messages, call [CommandLine].SetOutput.
679func PrintDefaults() {
680	CommandLine.PrintDefaults()
681}
682
683// defaultUsage is the default function to print a usage message.
684func (f *FlagSet) defaultUsage() {
685	if f.name == "" {
686		fmt.Fprintf(f.Output(), "Usage:\n")
687	} else {
688		fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name)
689	}
690	f.PrintDefaults()
691}
692
693// NOTE: Usage is not just defaultUsage(CommandLine)
694// because it serves (via godoc flag Usage) as the example
695// for how to write your own usage function.
696
697// Usage prints a usage message documenting all defined command-line flags
698// to [CommandLine]'s output, which by default is [os.Stderr].
699// It is called when an error occurs while parsing flags.
700// The function is a variable that may be changed to point to a custom function.
701// By default it prints a simple header and calls [PrintDefaults]; for details about the
702// format of the output and how to control it, see the documentation for [PrintDefaults].
703// Custom usage functions may choose to exit the program; by default exiting
704// happens anyway as the command line's error handling strategy is set to
705// [ExitOnError].
706var Usage = func() {
707	fmt.Fprintf(CommandLine.Output(), "Usage of %s:\n", os.Args[0])
708	PrintDefaults()
709}
710
711// NFlag returns the number of flags that have been set.
712func (f *FlagSet) NFlag() int { return len(f.actual) }
713
714// NFlag returns the number of command-line flags that have been set.
715func NFlag() int { return len(CommandLine.actual) }
716
717// Arg returns the i'th argument. Arg(0) is the first remaining argument
718// after flags have been processed. Arg returns an empty string if the
719// requested element does not exist.
720func (f *FlagSet) Arg(i int) string {
721	if i < 0 || i >= len(f.args) {
722		return ""
723	}
724	return f.args[i]
725}
726
727// Arg returns the i'th command-line argument. Arg(0) is the first remaining argument
728// after flags have been processed. Arg returns an empty string if the
729// requested element does not exist.
730func Arg(i int) string {
731	return CommandLine.Arg(i)
732}
733
734// NArg is the number of arguments remaining after flags have been processed.
735func (f *FlagSet) NArg() int { return len(f.args) }
736
737// NArg is the number of arguments remaining after flags have been processed.
738func NArg() int { return len(CommandLine.args) }
739
740// Args returns the non-flag arguments.
741func (f *FlagSet) Args() []string { return f.args }
742
743// Args returns the non-flag command-line arguments.
744func Args() []string { return CommandLine.args }
745
746// BoolVar defines a bool flag with specified name, default value, and usage string.
747// The argument p points to a bool variable in which to store the value of the flag.
748func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string) {
749	f.Var(newBoolValue(value, p), name, usage)
750}
751
752// BoolVar defines a bool flag with specified name, default value, and usage string.
753// The argument p points to a bool variable in which to store the value of the flag.
754func BoolVar(p *bool, name string, value bool, usage string) {
755	CommandLine.Var(newBoolValue(value, p), name, usage)
756}
757
758// Bool defines a bool flag with specified name, default value, and usage string.
759// The return value is the address of a bool variable that stores the value of the flag.
760func (f *FlagSet) Bool(name string, value bool, usage string) *bool {
761	p := new(bool)
762	f.BoolVar(p, name, value, usage)
763	return p
764}
765
766// Bool defines a bool flag with specified name, default value, and usage string.
767// The return value is the address of a bool variable that stores the value of the flag.
768func Bool(name string, value bool, usage string) *bool {
769	return CommandLine.Bool(name, value, usage)
770}
771
772// IntVar defines an int flag with specified name, default value, and usage string.
773// The argument p points to an int variable in which to store the value of the flag.
774func (f *FlagSet) IntVar(p *int, name string, value int, usage string) {
775	f.Var(newIntValue(value, p), name, usage)
776}
777
778// IntVar defines an int flag with specified name, default value, and usage string.
779// The argument p points to an int variable in which to store the value of the flag.
780func IntVar(p *int, name string, value int, usage string) {
781	CommandLine.Var(newIntValue(value, p), name, usage)
782}
783
784// Int defines an int flag with specified name, default value, and usage string.
785// The return value is the address of an int variable that stores the value of the flag.
786func (f *FlagSet) Int(name string, value int, usage string) *int {
787	p := new(int)
788	f.IntVar(p, name, value, usage)
789	return p
790}
791
792// Int defines an int flag with specified name, default value, and usage string.
793// The return value is the address of an int variable that stores the value of the flag.
794func Int(name string, value int, usage string) *int {
795	return CommandLine.Int(name, value, usage)
796}
797
798// Int64Var defines an int64 flag with specified name, default value, and usage string.
799// The argument p points to an int64 variable in which to store the value of the flag.
800func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string) {
801	f.Var(newInt64Value(value, p), name, usage)
802}
803
804// Int64Var defines an int64 flag with specified name, default value, and usage string.
805// The argument p points to an int64 variable in which to store the value of the flag.
806func Int64Var(p *int64, name string, value int64, usage string) {
807	CommandLine.Var(newInt64Value(value, p), name, usage)
808}
809
810// Int64 defines an int64 flag with specified name, default value, and usage string.
811// The return value is the address of an int64 variable that stores the value of the flag.
812func (f *FlagSet) Int64(name string, value int64, usage string) *int64 {
813	p := new(int64)
814	f.Int64Var(p, name, value, usage)
815	return p
816}
817
818// Int64 defines an int64 flag with specified name, default value, and usage string.
819// The return value is the address of an int64 variable that stores the value of the flag.
820func Int64(name string, value int64, usage string) *int64 {
821	return CommandLine.Int64(name, value, usage)
822}
823
824// UintVar defines a uint flag with specified name, default value, and usage string.
825// The argument p points to a uint variable in which to store the value of the flag.
826func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string) {
827	f.Var(newUintValue(value, p), name, usage)
828}
829
830// UintVar defines a uint flag with specified name, default value, and usage string.
831// The argument p points to a uint variable in which to store the value of the flag.
832func UintVar(p *uint, name string, value uint, usage string) {
833	CommandLine.Var(newUintValue(value, p), name, usage)
834}
835
836// Uint defines a uint flag with specified name, default value, and usage string.
837// The return value is the address of a uint variable that stores the value of the flag.
838func (f *FlagSet) Uint(name string, value uint, usage string) *uint {
839	p := new(uint)
840	f.UintVar(p, name, value, usage)
841	return p
842}
843
844// Uint defines a uint flag with specified name, default value, and usage string.
845// The return value is the address of a uint variable that stores the value of the flag.
846func Uint(name string, value uint, usage string) *uint {
847	return CommandLine.Uint(name, value, usage)
848}
849
850// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
851// The argument p points to a uint64 variable in which to store the value of the flag.
852func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string) {
853	f.Var(newUint64Value(value, p), name, usage)
854}
855
856// Uint64Var defines a uint64 flag with specified name, default value, and usage string.
857// The argument p points to a uint64 variable in which to store the value of the flag.
858func Uint64Var(p *uint64, name string, value uint64, usage string) {
859	CommandLine.Var(newUint64Value(value, p), name, usage)
860}
861
862// Uint64 defines a uint64 flag with specified name, default value, and usage string.
863// The return value is the address of a uint64 variable that stores the value of the flag.
864func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 {
865	p := new(uint64)
866	f.Uint64Var(p, name, value, usage)
867	return p
868}
869
870// Uint64 defines a uint64 flag with specified name, default value, and usage string.
871// The return value is the address of a uint64 variable that stores the value of the flag.
872func Uint64(name string, value uint64, usage string) *uint64 {
873	return CommandLine.Uint64(name, value, usage)
874}
875
876// StringVar defines a string flag with specified name, default value, and usage string.
877// The argument p points to a string variable in which to store the value of the flag.
878func (f *FlagSet) StringVar(p *string, name string, value string, usage string) {
879	f.Var(newStringValue(value, p), name, usage)
880}
881
882// StringVar defines a string flag with specified name, default value, and usage string.
883// The argument p points to a string variable in which to store the value of the flag.
884func StringVar(p *string, name string, value string, usage string) {
885	CommandLine.Var(newStringValue(value, p), name, usage)
886}
887
888// String defines a string flag with specified name, default value, and usage string.
889// The return value is the address of a string variable that stores the value of the flag.
890func (f *FlagSet) String(name string, value string, usage string) *string {
891	p := new(string)
892	f.StringVar(p, name, value, usage)
893	return p
894}
895
896// String defines a string flag with specified name, default value, and usage string.
897// The return value is the address of a string variable that stores the value of the flag.
898func String(name string, value string, usage string) *string {
899	return CommandLine.String(name, value, usage)
900}
901
902// Float64Var defines a float64 flag with specified name, default value, and usage string.
903// The argument p points to a float64 variable in which to store the value of the flag.
904func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string) {
905	f.Var(newFloat64Value(value, p), name, usage)
906}
907
908// Float64Var defines a float64 flag with specified name, default value, and usage string.
909// The argument p points to a float64 variable in which to store the value of the flag.
910func Float64Var(p *float64, name string, value float64, usage string) {
911	CommandLine.Var(newFloat64Value(value, p), name, usage)
912}
913
914// Float64 defines a float64 flag with specified name, default value, and usage string.
915// The return value is the address of a float64 variable that stores the value of the flag.
916func (f *FlagSet) Float64(name string, value float64, usage string) *float64 {
917	p := new(float64)
918	f.Float64Var(p, name, value, usage)
919	return p
920}
921
922// Float64 defines a float64 flag with specified name, default value, and usage string.
923// The return value is the address of a float64 variable that stores the value of the flag.
924func Float64(name string, value float64, usage string) *float64 {
925	return CommandLine.Float64(name, value, usage)
926}
927
928// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
929// The argument p points to a time.Duration variable in which to store the value of the flag.
930// The flag accepts a value acceptable to time.ParseDuration.
931func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
932	f.Var(newDurationValue(value, p), name, usage)
933}
934
935// DurationVar defines a time.Duration flag with specified name, default value, and usage string.
936// The argument p points to a time.Duration variable in which to store the value of the flag.
937// The flag accepts a value acceptable to time.ParseDuration.
938func DurationVar(p *time.Duration, name string, value time.Duration, usage string) {
939	CommandLine.Var(newDurationValue(value, p), name, usage)
940}
941
942// Duration defines a time.Duration flag with specified name, default value, and usage string.
943// The return value is the address of a time.Duration variable that stores the value of the flag.
944// The flag accepts a value acceptable to time.ParseDuration.
945func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration {
946	p := new(time.Duration)
947	f.DurationVar(p, name, value, usage)
948	return p
949}
950
951// Duration defines a time.Duration flag with specified name, default value, and usage string.
952// The return value is the address of a time.Duration variable that stores the value of the flag.
953// The flag accepts a value acceptable to time.ParseDuration.
954func Duration(name string, value time.Duration, usage string) *time.Duration {
955	return CommandLine.Duration(name, value, usage)
956}
957
958// TextVar defines a flag with a specified name, default value, and usage string.
959// The argument p must be a pointer to a variable that will hold the value
960// of the flag, and p must implement encoding.TextUnmarshaler.
961// If the flag is used, the flag value will be passed to p's UnmarshalText method.
962// The type of the default value must be the same as the type of p.
963func (f *FlagSet) TextVar(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string) {
964	f.Var(newTextValue(value, p), name, usage)
965}
966
967// TextVar defines a flag with a specified name, default value, and usage string.
968// The argument p must be a pointer to a variable that will hold the value
969// of the flag, and p must implement encoding.TextUnmarshaler.
970// If the flag is used, the flag value will be passed to p's UnmarshalText method.
971// The type of the default value must be the same as the type of p.
972func TextVar(p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string) {
973	CommandLine.Var(newTextValue(value, p), name, usage)
974}
975
976// Func defines a flag with the specified name and usage string.
977// Each time the flag is seen, fn is called with the value of the flag.
978// If fn returns a non-nil error, it will be treated as a flag value parsing error.
979func (f *FlagSet) Func(name, usage string, fn func(string) error) {
980	f.Var(funcValue(fn), name, usage)
981}
982
983// Func defines a flag with the specified name and usage string.
984// Each time the flag is seen, fn is called with the value of the flag.
985// If fn returns a non-nil error, it will be treated as a flag value parsing error.
986func Func(name, usage string, fn func(string) error) {
987	CommandLine.Func(name, usage, fn)
988}
989
990// BoolFunc defines a flag with the specified name and usage string without requiring values.
991// Each time the flag is seen, fn is called with the value of the flag.
992// If fn returns a non-nil error, it will be treated as a flag value parsing error.
993func (f *FlagSet) BoolFunc(name, usage string, fn func(string) error) {
994	f.Var(boolFuncValue(fn), name, usage)
995}
996
997// BoolFunc defines a flag with the specified name and usage string without requiring values.
998// Each time the flag is seen, fn is called with the value of the flag.
999// If fn returns a non-nil error, it will be treated as a flag value parsing error.
1000func BoolFunc(name, usage string, fn func(string) error) {
1001	CommandLine.BoolFunc(name, usage, fn)
1002}
1003
1004// Var defines a flag with the specified name and usage string. The type and
1005// value of the flag are represented by the first argument, of type [Value], which
1006// typically holds a user-defined implementation of [Value]. For instance, the
1007// caller could create a flag that turns a comma-separated string into a slice
1008// of strings by giving the slice the methods of [Value]; in particular, [Set] would
1009// decompose the comma-separated string into the slice.
1010func (f *FlagSet) Var(value Value, name string, usage string) {
1011	// Flag must not begin "-" or contain "=".
1012	if strings.HasPrefix(name, "-") {
1013		panic(f.sprintf("flag %q begins with -", name))
1014	} else if strings.Contains(name, "=") {
1015		panic(f.sprintf("flag %q contains =", name))
1016	}
1017
1018	// Remember the default value as a string; it won't change.
1019	flag := &Flag{name, usage, value, value.String()}
1020	_, alreadythere := f.formal[name]
1021	if alreadythere {
1022		var msg string
1023		if f.name == "" {
1024			msg = f.sprintf("flag redefined: %s", name)
1025		} else {
1026			msg = f.sprintf("%s flag redefined: %s", f.name, name)
1027		}
1028		panic(msg) // Happens only if flags are declared with identical names
1029	}
1030	if pos := f.undef[name]; pos != "" {
1031		panic(fmt.Sprintf("flag %s set at %s before being defined", name, pos))
1032	}
1033	if f.formal == nil {
1034		f.formal = make(map[string]*Flag)
1035	}
1036	f.formal[name] = flag
1037}
1038
1039// Var defines a flag with the specified name and usage string. The type and
1040// value of the flag are represented by the first argument, of type [Value], which
1041// typically holds a user-defined implementation of [Value]. For instance, the
1042// caller could create a flag that turns a comma-separated string into a slice
1043// of strings by giving the slice the methods of [Value]; in particular, [Set] would
1044// decompose the comma-separated string into the slice.
1045func Var(value Value, name string, usage string) {
1046	CommandLine.Var(value, name, usage)
1047}
1048
1049// sprintf formats the message, prints it to output, and returns it.
1050func (f *FlagSet) sprintf(format string, a ...any) string {
1051	msg := fmt.Sprintf(format, a...)
1052	fmt.Fprintln(f.Output(), msg)
1053	return msg
1054}
1055
1056// failf prints to standard error a formatted error and usage message and
1057// returns the error.
1058func (f *FlagSet) failf(format string, a ...any) error {
1059	msg := f.sprintf(format, a...)
1060	f.usage()
1061	return errors.New(msg)
1062}
1063
1064// usage calls the Usage method for the flag set if one is specified,
1065// or the appropriate default usage function otherwise.
1066func (f *FlagSet) usage() {
1067	if f.Usage == nil {
1068		f.defaultUsage()
1069	} else {
1070		f.Usage()
1071	}
1072}
1073
1074// parseOne parses one flag. It reports whether a flag was seen.
1075func (f *FlagSet) parseOne() (bool, error) {
1076	if len(f.args) == 0 {
1077		return false, nil
1078	}
1079	s := f.args[0]
1080	if len(s) < 2 || s[0] != '-' {
1081		return false, nil
1082	}
1083	numMinuses := 1
1084	if s[1] == '-' {
1085		numMinuses++
1086		if len(s) == 2 { // "--" terminates the flags
1087			f.args = f.args[1:]
1088			return false, nil
1089		}
1090	}
1091	name := s[numMinuses:]
1092	if len(name) == 0 || name[0] == '-' || name[0] == '=' {
1093		return false, f.failf("bad flag syntax: %s", s)
1094	}
1095
1096	// it's a flag. does it have an argument?
1097	f.args = f.args[1:]
1098	hasValue := false
1099	value := ""
1100	for i := 1; i < len(name); i++ { // equals cannot be first
1101		if name[i] == '=' {
1102			value = name[i+1:]
1103			hasValue = true
1104			name = name[0:i]
1105			break
1106		}
1107	}
1108
1109	flag, ok := f.formal[name]
1110	if !ok {
1111		if name == "help" || name == "h" { // special case for nice help message.
1112			f.usage()
1113			return false, ErrHelp
1114		}
1115		return false, f.failf("flag provided but not defined: -%s", name)
1116	}
1117
1118	if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
1119		if hasValue {
1120			if err := fv.Set(value); err != nil {
1121				return false, f.failf("invalid boolean value %q for -%s: %v", value, name, err)
1122			}
1123		} else {
1124			if err := fv.Set("true"); err != nil {
1125				return false, f.failf("invalid boolean flag %s: %v", name, err)
1126			}
1127		}
1128	} else {
1129		// It must have a value, which might be the next argument.
1130		if !hasValue && len(f.args) > 0 {
1131			// value is the next arg
1132			hasValue = true
1133			value, f.args = f.args[0], f.args[1:]
1134		}
1135		if !hasValue {
1136			return false, f.failf("flag needs an argument: -%s", name)
1137		}
1138		if err := flag.Value.Set(value); err != nil {
1139			return false, f.failf("invalid value %q for flag -%s: %v", value, name, err)
1140		}
1141	}
1142	if f.actual == nil {
1143		f.actual = make(map[string]*Flag)
1144	}
1145	f.actual[name] = flag
1146	return true, nil
1147}
1148
1149// Parse parses flag definitions from the argument list, which should not
1150// include the command name. Must be called after all flags in the [FlagSet]
1151// are defined and before flags are accessed by the program.
1152// The return value will be [ErrHelp] if -help or -h were set but not defined.
1153func (f *FlagSet) Parse(arguments []string) error {
1154	f.parsed = true
1155	f.args = arguments
1156	for {
1157		seen, err := f.parseOne()
1158		if seen {
1159			continue
1160		}
1161		if err == nil {
1162			break
1163		}
1164		switch f.errorHandling {
1165		case ContinueOnError:
1166			return err
1167		case ExitOnError:
1168			if err == ErrHelp {
1169				os.Exit(0)
1170			}
1171			os.Exit(2)
1172		case PanicOnError:
1173			panic(err)
1174		}
1175	}
1176	return nil
1177}
1178
1179// Parsed reports whether f.Parse has been called.
1180func (f *FlagSet) Parsed() bool {
1181	return f.parsed
1182}
1183
1184// Parse parses the command-line flags from [os.Args][1:]. Must be called
1185// after all flags are defined and before flags are accessed by the program.
1186func Parse() {
1187	// Ignore errors; CommandLine is set for ExitOnError.
1188	CommandLine.Parse(os.Args[1:])
1189}
1190
1191// Parsed reports whether the command-line flags have been parsed.
1192func Parsed() bool {
1193	return CommandLine.Parsed()
1194}
1195
1196// CommandLine is the default set of command-line flags, parsed from [os.Args].
1197// The top-level functions such as [BoolVar], [Arg], and so on are wrappers for the
1198// methods of CommandLine.
1199var CommandLine = NewFlagSet(os.Args[0], ExitOnError)
1200
1201func init() {
1202	// Override generic FlagSet default Usage with call to global Usage.
1203	// Note: This is not CommandLine.Usage = Usage,
1204	// because we want any eventual call to use any updated value of Usage,
1205	// not the value it has when this line is run.
1206	CommandLine.Usage = commandLineUsage
1207}
1208
1209func commandLineUsage() {
1210	Usage()
1211}
1212
1213// NewFlagSet returns a new, empty flag set with the specified name and
1214// error handling property. If the name is not empty, it will be printed
1215// in the default usage message and in error messages.
1216func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet {
1217	f := &FlagSet{
1218		name:          name,
1219		errorHandling: errorHandling,
1220	}
1221	f.Usage = f.defaultUsage
1222	return f
1223}
1224
1225// Init sets the name and error handling property for a flag set.
1226// By default, the zero [FlagSet] uses an empty name and the
1227// [ContinueOnError] error handling policy.
1228func (f *FlagSet) Init(name string, errorHandling ErrorHandling) {
1229	f.name = name
1230	f.errorHandling = errorHandling
1231}
1232