getopt

package module
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Feb 28, 2025 License: MIT Imports: 5 Imported by: 0

README

getopt

Go Reference CI Go Report Card codecov Mentioned in Awesome Go

Package getopt provides a zero-dependency Go implementation of the Unix getopt function for parsing command-line options.

The getopt package supports parsing options using the POSIX convention, supporting short options (e.g., -a) and option arguments. It also supports GNU extensions, including support for long options (e.g., --option), options with optional arguments, and permuting non-option parameters.

Install

go get github.com/jon-codes/getopt

Usage

This package emulates the C getopt function, but uses a state machine to encapsulate variables (instead of the global optind, optopt, optarg used in C). Rather than implement a high-level interface for defining CLI flags, it aims to implement an accurate emulation of C getopt that can be used by higher-level tools.

Collect all options into a slice:

state := getopt.NewState(os.Args)
config := getopt.Config{Opts: getopt.OptStr(`ab:c::`)}
opts, err := state.Parse(config)

Iterate over each option for finer control:

state := getopt.NewState(os.Args)
config := getopt.Config{Opts: getopt.OptStr(`ab:c::`)}

for opt, err := range state.All(config) {
    if err != nil {
        break
    }
    switch opt.Char {
    case 'a':
        fmt.Printf("Found opt a\n")
    case 'b':
        fmt.Printf("Found opt b with arg %s\n", opt.OptArg)
    case 'c':
        fmt.Printf("Found opt c")
        if opt.OptArg != "" {
            fmt.Printf(" with arg %s", opt.OptArg)
        }
        fmt.Printf("\n")
    }
}

Behavior

This package uses GNU libc as a reference for behavior, since many expect the non-standard features it provides. This is accomplished via a C test generator that runs getopt for all functions and parsing modes.

It supports the same configuration options as the GNU options via Mode:

  • ModeGNU: enables default behavior.
  • ModePosix: enables the '+' compatibility mode, disabling permuting arguments and terminating parsing on the first parameter.
  • ModeInOrder: enables the '-' optstring prefix mode, treating all parameters as though they were arguments to an option with character code 1.

The specific libc function that is emulated can be configured via Func:

  • FuncGetOpt: parse only traditional POSIX short options (e.g., -a).
  • FuncGetOptLong: parse short options, and GNU extension long options (e.g., --option).
  • FuncGetOptLongOnly: parse short and long options, but allow long options to begin with a single dash (like pkg/flag).

The parser differs from GNU libc's getopt in the following ways:

  • It accepts multi-byte runes in short and long option definitions.
  • This package does not implement the same argument permutation as GNU libc. The value of OptInd and order of arguments mid-parsing may differ, and only the final order is validated against the GNU implementation.

API Documentation

The full API documentation can be found at pkg.go.dev. The API for major version 1.x.x is stable -- any breaking changes to the API will require a new major version.

Acknowledgements

The algorithm for permuting arguments is from musl-libc, and is used under the linked MIT License:

| Copyright © 2005-2020 Rich Felker, et al.

Documentation

Overview

Package getopt implements the Unix getopt function for parsing command-line options.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrDone          = errors.New("getopt: done")
	ErrUnknownOpt    = errors.New("getopt: unrecognized option")
	ErrIllegalOptArg = errors.New("getopt: option disallows arguments")
	ErrMissingOptArg = errors.New("getopt: option requires an argument")
)

Errors that can be returned during option parsing.

Functions

This section is empty.

Types

type Config

type Config struct {
	Opts     []Opt     // allowed short options
	LongOpts []LongOpt // allowed long options
	Func     Func      // parsing function
	Mode     Mode      // parsing behavior
}

A Config defines the rules and behavior used when parsing options. Note the zero values for Func (FuncGetOpt) and Mode (ModeGNU), which will determine the parsing behavior unless set otherwise.

type Func

type Func int

Func indicates which POSIX or GNU extension function to emulate during option parsing.

const (
	FuncGetOpt         Func = iota // behave like `getopt`
	FuncGetOptLong                 // behave like `getopt_long`
	FuncGetOptLongOnly             // behave like `getopt_long_only`
)

type HasArg

type HasArg int

HasArg defines rules for parsing option arguments.

const (
	NoArgument       HasArg = iota // option may not take an argument
	RequiredArgument               // option requires an argument
	OptionalArgument               // option may optionally accept an argument
)

type LongOpt

type LongOpt struct {
	Name   string // option name
	HasArg HasArg // option argument rule
}

A LongOpt is a parsing rule for a named, long command-line option (e.g., --option).

func LongOptStr

func LongOptStr(longOptStr string) (longOpts []LongOpt)

OptStr parses a long option string, returning a slice of LongOpt.

The option string uses the same format as --longoptions in the GNU getopt(1) command. Option names are comma-separated, and argument rules are designated by colon suffixes, like with OptStr.

type Mode

type Mode int

Mode indicates which behavior to enable during option parsing.

const (
	ModeGNU     Mode = iota // enable GNU extension behavior
	ModePOSIX               // enable POSIX behavior (terminate on first parameter)
	ModeInOrder             // enable "in-order" behavior (parse parameters as options)
)

type Opt

type Opt struct {
	Char   rune   // option character
	HasArg HasArg // option argument rule
}

An Opt is a parsing rule for a short, single-character command-line option (e.g., -a).

func OptStr

func OptStr(optStr string) (opts []Opt)

OptStr parses an option string, returning a slice of Opt.

The option string uses the same format as getopt, with each character representing an option. Options with a single ":" suffix require an argument. Options with a double "::" suffix optionally accept an argument. Options with no suffix do not allow arguments.

type Result

type Result struct {
	Char   rune   // parsed short option character
	Name   string // parsed long option name
	OptArg string // parsed option argument
}

type State

type State struct {
	// contains filtered or unexported fields
}

func NewState

func NewState(args []string) *State

NewState returns a new State to parse options from args, starting with the element at index 1.

func (*State) All

func (s *State) All(c Config) iter.Seq2[Result, error]

All returns an iterator that yields successive parsing results.

func (*State) Args

func (s *State) Args() []string

Args returns the current slice of arguments in State. This may differ from the slice used to initialize State, since parsing can permute the argument order.

func (*State) GetOpt

func (s *State) GetOpt(c Config) (res Result, err error)

GetOpt returns the result of parsing the next option in State.

If parsing has successfully completed, err will be ErrDone. Otherwise, the returned Result indicates either a valid option, or the properties of an invalid option if err is non-nil.

func (*State) OptInd

func (s *State) OptInd() int

OptInd returns the index of the next argument that will be parsed in State.

After all options have been parsed, OptInd will index the first parameter (non-option) argument returned by State.Args. If no parameters are present, the index will be invalid, since the next argument's index would have exceeded the bounds of the argument slice. State.Params provides safe access to parameters.

func (*State) Params

func (s *State) Params() []string

Params returns the slice of parameter (non-option) arguments. If parsing has not successfully completed with ErrDone, this may include arguments that otherwise be parsed as options.

func (*State) Parse

func (s *State) Parse(c Config) ([]Result, error)

Parse returns a slice of Result by calling State.GetOpt until an error is returned.

func (*State) Reset

func (s *State) Reset(args []string)

Reset recycles an existing State, resetting it to parse options from args, starting with the element at index 1.

Jump to

Keyboard shortcuts

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