getopt

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 7, 2024 License: MIT Imports: 4 Imported by: 0

Documentation

Overview

Package getopt provides GNU-style argument parsing for both short and long arguments.

Differences from Posix and GNU getopt:

  1. There are no global variables. All operations are performed on a Getopt struct that maintains state between successive calls. To read an option's argument value, read [Opt.Arg] instead of optarg. To reset option-parsing, create a new Getopt struct instead of assign optreset.
  2. The opterr setting is permanently false. Errors are never printed anywhere by this library. Instead, errors are returned and the caller can choose what to do with them. The text of the errors corresponds to messages that would be printed by GNU getopt. The leading ':' in the option spec that controls error-reporting is accepted for compatibility, but it's ignored.
  3. A struct is returned instead of just the matched option character. The struct includes the option character, any value that would have been in optarg, as well as any value that would have been returned in the longindex argument to getopt_long.
  4. The optopt value is not used. Instead, the relevant unrecognized character or option name is available in the Option field of whatever error gets returned.
  5. The Flag and Val fields of Option have type rune, not int.
  6. The list of options and arguments cannot be changed in the middle of parsing. The argument list and option definition are set once at the start, and then you just call Getopt or GetoptLong with no parameters.
  7. The POSIXLY_CORRECT environment variable is ignored. The library runs as though the environment variable is never set. Use leading '+' or '-' characters in the option specification instead; see Ordering for more.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Iterate added in v0.2.0

func Iterate(args []string, opts string, remaining *[]string) iter.Seq2[*Opt, error]

Iterate returns an iterator for options parsed from the given argument list. When iteration terminates, the slice pointer, if non-nil, will hold the remaining unparsed arguments.

Example
args := []string{"prg", "-a", "arg1", "-b", "arg2"}
optionDefinition := "ab"

var remaining []string
for opt, err := range getopt.Iterate(args, optionDefinition, &remaining) {
	if err != nil {
		_, _ = fmt.Println(err.Error())
		break
	}
	switch opt.C {
	case 'a':
		_, _ = fmt.Println("got option a")
	case 'b':
		_, _ = fmt.Println("got option b")
	}
}
_, _ = fmt.Printf("Remaining arguments: %v", remaining)
Output:

got option a
got option b
Remaining arguments: [arg1 arg2]

func IterateLong added in v0.2.0

func IterateLong(args []string, opts string, longOptions []Option, remaining *[]string) iter.Seq2[*Opt, error]

IterateLong returns an iterator for options parsed from the given argument list and option definitions. When iteration terminates, the slice pointer, if non-nil, will hold the remaining unparsed arguments.

Example
args := []string{"prg", "-d", "--bbb", "-a"}
optionDefinition := "ab"
longOpts := []getopt.Option{
	{Name: "aaa", Val: 'a'},
	{Name: "bbb", Val: 'b'},
}
for opt, err := range getopt.IterateLong(args, optionDefinition, longOpts, nil) {
	if err != nil {
		_, _ = fmt.Println(err.Error())
		continue
	}
	if opt.LongInd == -1 {
		_, _ = fmt.Printf("Got short option '%c'\n", opt.C)
	} else {
		_, _ = fmt.Printf("Got long option '%s'\n", longOpts[opt.LongInd].Name)
	}
}
Output:

unrecognized option '-d'
Got long option 'bbb'
Got short option 'a'

func IterateLongOnly added in v0.2.0

func IterateLongOnly(args []string, opts string, longOptions []Option, remaining *[]string) iter.Seq2[*Opt, error]

IterateLongOnly returns an iterator for options parsed from the given argument list and option definitions. When iteration terminates, the slice pointer, if non-nil, will hold the remaining unparsed arguments.

Types

type AmbiguousOptionError

type AmbiguousOptionError struct {
	Option     string
	Candidates []string
	// contains filtered or unexported fields
}

AmbiguousOptionError is returned when there is no exact match for Option, but more than one abbreviated match, which are given in Candidates.

Example
longopts := []Option{
	{Name: "one", HasArg: NoArgument, Val: '1'},
	{Name: "two", HasArg: NoArgument, Val: '2'},
	{Name: "one-one", HasArg: NoArgument, Val: '3'},
	{Name: "four", HasArg: NoArgument, Val: '4'},
	{Name: "onto", HasArg: NoArgument, Val: '5'},
}
argv := []string{"program", "--on"}

gopt := NewLong(argv, "12345", longopts)
_, err := gopt.GetoptLong()
_, _ = fmt.Println(err.Error())
Output:

option '--on' is ambiguous; possibilities: '--one' '--one-one' '--onto'

func (AmbiguousOptionError) Error

func (e AmbiguousOptionError) Error() string

type ArgumentDisposition

type ArgumentDisposition int

ArgumentDisposition is an enum specifying whether an option expects to be followed by an argument. Use it when defining the Option list for long options.

const (
	NoArgument       ArgumentDisposition = iota // The option does not take an argument.
	RequiredArgument                            // The option requires an argument.
	OptionalArgument                            // The option takes an optional argument.
)

These ArgumentDisposition values are used for the HasArg field of Option values.

type ArgumentNotAllowedError

type ArgumentNotAllowedError struct {
	Option string
	// contains filtered or unexported fields
}

ArgumentNotAllowedError is returned when Option does not accept arguments but one is provided anyway.

Example
longopts := []Option{
	{Name: "sample", HasArg: NoArgument},
}
argv := []string{"program", "--sample=arg"}

gopt := NewLong(argv, "", longopts)
_, err := gopt.Getopt()
_, _ = fmt.Println(err.Error())
Output:

option '--sample' doesn't allow an argument

func (ArgumentNotAllowedError) Error

func (e ArgumentNotAllowedError) Error() string

type ArgumentRequiredError

type ArgumentRequiredError struct {
	Option string
	// contains filtered or unexported fields
}

ArgumentRequiredError is returned when Option expects an argument and none is given.

Example
argv := []string{"program", "-a"}

gopt := New(argv, "a:")
_, err := gopt.Getopt()
_, _ = fmt.Println(err.Error())
Output:

option '-a' requires an argument

func (ArgumentRequiredError) Error

func (e ArgumentRequiredError) Error() string

type Getopt

type Getopt struct {
	Args []string // Args holds a copy of the argument list. It gets permuted during parsing.
	// contains filtered or unexported fields
}

Getopt is an option parser.

func New

func New(args []string, opts string) *Getopt

New creates a new Getopt using the argument list and short option specification passed in here. Unlike the Posix getopt, this library stores the argument list and the option definition in the Getopt struct so that each successive call in the parsing loop doesn't need to repeat the same list of parameters.

The opts string is a list of characters that are recognized option letters, optionally followed by colons to specify that that letter takes an argument (returned via Opt.Arg). If a letter in opts is followed by two colons, its argument is optional. This behavior mimics the GNU extension.

The argument '--' causes premature termination of argument scanning, explicitly telling Getopt that there are no more options.

If opts begins with '-', then non-option arguments are treated as arguments to the option 1. This behavior mimics the GNU extension. If opts begins with '+', then arguments will not be permuted during parsing; parsing will stop when a non-option argument is encountered.

The argument list is assumed to include the program name at index 0; it is not returned or processed as a real argument.

func NewLong

func NewLong(args []string, opts string, longOptions []Option) *Getopt

NewLong creates a new Getopt using the argument list and short and long option specifications given. See Getopt.

If opts includes 'W' followed by ';', then a GNU extension is enabled that allows long options to be specified as arguments to the short option '-W'. For example, the argument sequence '-W foo=bar' will behave just as if it were '--foo=bar'.

func (*Getopt) Getopt

func (g *Getopt) Getopt() (*Opt, error)

Getopt scans elements of Args for option characters.

If an element of Args starts with '-', and is not exactly "-" or "--", then it is an option element. The characters of this element (aside from the initial '-') are option characters. If Getopt is called repeatedly, it returns successively each of the option characters from each of the option elements.

If Getopt finds another option character, it returns an Opt pointer and updates Getopt.Optind so that the next call to Getopt can resume the scan with the next option character or argument.

If there are no more option characters, Getopt returns nil. Then Getopt.Optind is the index in Args of the first argument that is not an option. (The arguments have been permuted so that those that are not options now come last.)

If an option character is seen that was not listed in the opt string when calling New or NewLong, then Getopt returns an UnrecognizedOptionError. It does not print messages to stderr; in that respect, it behaves as if the Posix value opterr is always false.

If an option wants an argument, then the subsequent text in the same Args element, or the text of the next Args element, is returned in Opt.Arg. If the option's argument is optional, then if there is text in the current Args element, it is returned in Opt.Arg. Otherwise, Opt.Arg will be nil.

Long-named options begin with '--' instead of '-'. Their names may be abbreviated as long as the abbreviation is unique or is an exact match for some defined option. If they have an argument, it follows the option name in the same Args element, separated from the option name by a '=', or else in next Args element. When Getopt finds a long-named option, it returns an Opt whose C field is 0 if that option's 'Flag' field is non-nil, or the value of the option's 'Val' field if the 'Flag' field is nil.

func (*Getopt) GetoptLong

func (g *Getopt) GetoptLong() (*Opt, error)

GetoptLong is identical to Getopt.Getopt.

func (*Getopt) GetoptLongOnly

func (g *Getopt) GetoptLongOnly() (*Opt, error)

GetoptLongOnly is identical to Getopt.Getopt and Getopt.GetoptLong, except that '-' as well as '--' can introduce long-named options.

func (*Getopt) Optind

func (g *Getopt) Optind() int

Optind returns the argument index of the next argument to be scanned. When the returned Opt pointer is nil, Optind will be the index of the first non-option element in Args, which is where the caller should pick up scanning.

Example
argv := []string{"program", "-a", "f1", "f2", "f3"}

gopt := New(argv, "a:")
for opt, err := gopt.Getopt(); opt != nil && err == nil; opt, err = gopt.Getopt() {
	_, _ = fmt.Printf("Got argument: %s\n", *opt.Arg)
}
_, _ = fmt.Printf("Remaining arguments: %v", gopt.Args[gopt.Optind():])
Output:

Got argument: f1
Remaining arguments: [f2 f3]

type Opt

type Opt struct {
	C       rune
	Arg     *string
	LongInd int
}

Opt is a result from parsing one option off a given argument list.

If C is 0, then a long option was matched, Flag pointed at a variable, and the variable has been assigned a value from Val. Opt.Arg holds the argument for that option, if any, and LongInd holds the index of the long option that matched.

If C is 1, then ordering is ReturnInOrder and Arg points to the current non-option argument.

Otherwise, C holds the rune value of the matched short option or Val of the matched long option. When a short option is matched, LongInd will be -1. When a long option is matched, LongInd holds the zero-based index of the matched option from the longopts argument to NewLong.

type Option

type Option struct {
	Name   string
	HasArg ArgumentDisposition
	Flag   *rune
	Val    rune
}

Option describes the long-named options requested by the application. The longopts argument to NewLong is a slice of this type.

If Flag is not nil, then it points to a variable that will have its value set to Val when the option is found, but will be left unchanged if the option is not found.

To have a long-named option do something other than set a rune to a compiled-in constant, such as set a value from Opt.Arg, set the option's Flag to nil and its Val to a nonzero value (such as the option's equivalent single-letter option character, if there is one). For long options that have a nil Flag, Getopt returns the Val field in Opt.C.

type Ordering

type Ordering int

Ordering describes how to deal with options that follow non-option arguments. Values are documented here for expository purposes but are not used by any client code.

The special argument '--' forces an end of option-scanning regardless of the ordering mode in effect. In the case of ReturnInOrder, only '--' can cause Getopt to return -1 with Optind != len(Args).

const (
	// RequireOrder means options that follow non-option arguments are not recognized as options. Getopt will stop
	// processing the argument list when the first non-option is seen. This mode can be useful when implementing a tool
	// that has subcommands, where the main command and the subcommands have their separate sets of options. This
	// behavior is what POSIX specifies should happen, although it is not the default in this package. To use this mode,
	// start the short option specification with a '+'.
	RequireOrder Ordering = iota

	// Permute means Getopt will permute the contents of Args as it scans, so that eventually all the non-options are at
	// the end. This allows options to be given in any order and is the default behavior.
	Permute

	// ReturnInOrder is an option available to programs that expect options and other arguments in any order and that
	// care about the ordering of the two. In this mode, non-option arguments are returned as though they belong to an
	// option with a character code of 1. To request this ordering behavior, start the short option specification with a
	// '-'.
	ReturnInOrder
)

type UnrecognizedOptionError

type UnrecognizedOptionError struct {
	Option string
	// contains filtered or unexported fields
}

UnrecognizedOptionError is returned when Option on the command line is not a recogized option.

Example
argv := []string{"program", "-c"}

gopt := New(argv, "ab")
_, err := gopt.Getopt()
_, _ = fmt.Println(err.Error())
Output:

unrecognized option '-c'

func (UnrecognizedOptionError) Error

func (e UnrecognizedOptionError) Error() string

Directories

Path Synopsis
magefiles module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL