summaryrefslogtreecommitdiffstats
path: root/vendor/modernc.org/opt/opt.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/modernc.org/opt/opt.go')
-rw-r--r--vendor/modernc.org/opt/opt.go152
1 files changed, 152 insertions, 0 deletions
diff --git a/vendor/modernc.org/opt/opt.go b/vendor/modernc.org/opt/opt.go
new file mode 100644
index 00000000..0085e9f2
--- /dev/null
+++ b/vendor/modernc.org/opt/opt.go
@@ -0,0 +1,152 @@
+// Package opt implements command-line flag parsing.
+package opt // import "modernc.org/opt"
+
+import (
+ "fmt"
+ "strings"
+)
+
+type opt struct {
+ handler func(opt, arg string) error
+ name string
+
+ arg bool // Enable argument, e.g. `-I foo` or `-I=foo`
+}
+
+// A Set represents a set of defined options.
+type Set struct {
+ cfg map[string]*opt
+ imm []*opt
+}
+
+// NewSet returns a new, empty option set.
+func NewSet() *Set { return &Set{cfg: map[string]*opt{}} }
+
+// Opt defines a simple option, e.g. `-f`. When the option is found during
+// Parse, the handler is called with the value of the option, e.g. "-f".
+func (p *Set) Opt(name string, handler func(opt string) error) {
+ p.cfg[name] = &opt{
+ handler: func(opt, arg string) error { return handler(opt) },
+ }
+}
+
+// Arg defines a simple option with an argument, e.g. `-I foo` or `-I=foo`.
+// Setting imm argument enables additionally `-Ifoo`. When the option is found
+// during Parse, the handler is called with the values of the option and the
+// argument, e.g. "-I" and "foo" for all of the variants.
+func (p *Set) Arg(name string, imm bool, handler func(opt, arg string) error) {
+ switch {
+ case imm:
+ p.imm = append(p.imm, &opt{
+ handler: handler,
+ name: name,
+ })
+ default:
+ p.cfg[name] = &opt{
+ arg: true,
+ handler: handler,
+ name: name,
+ }
+ }
+}
+
+// Parse parses opts. Must be called after all options are defined. The handler
+// is called for all items in opts that were not defined before using Opt or
+// Arg.
+//
+// If any handler returns a non-nil error, Parse will stop. If the error is of
+// type Skip, the error returned by Parse will contain all the unprocessed
+// items of opts.
+//
+// The opts slice must not be modified by any handler while Parser is
+// executing.
+func (p *Set) Parse(opts []string, handler func(string) error) (err error) {
+ defer func() {
+ switch err.(type) {
+ case Skip:
+ err = Skip(opts)
+ }
+ }()
+
+ for len(opts) != 0 {
+ opt := opts[0]
+ opts = opts[1:]
+ var arg string
+ out:
+ switch {
+ case strings.HasPrefix(opt, "-"):
+ name := opt[1:]
+ for _, cfg := range p.imm {
+ if strings.HasPrefix(name, cfg.name) {
+ switch {
+ case name == cfg.name:
+ if len(opts) == 0 {
+ return fmt.Errorf("missing argument of %s", opt)
+ }
+
+ if err = cfg.handler(opt, opts[0]); err != nil {
+ return err
+ }
+
+ opts = opts[1:]
+ default:
+ if err = cfg.handler(opt[:len(cfg.name)+1], name[len(cfg.name):]); err != nil {
+ return err
+ }
+ }
+ break out
+ }
+ }
+
+ if n := strings.IndexByte(opt, '='); n > 0 {
+ arg = opt[n+1:]
+ name = opt[1:n]
+ opt = opt[:n]
+ }
+ switch cfg := p.cfg[name]; {
+ case cfg == nil:
+ if err = handler(opt); err != nil {
+ return err
+ }
+ default:
+ switch {
+ case cfg.arg:
+ switch {
+ case arg != "":
+ if err = cfg.handler(opt, arg); err != nil {
+ return err
+ }
+ default:
+ if len(opts) == 0 {
+ return fmt.Errorf("missing argument of %s", opt)
+ }
+
+ if err = cfg.handler(opt, opts[0]); err != nil {
+ return err
+ }
+
+ opts = opts[1:]
+ }
+ default:
+ if err = cfg.handler(opt, ""); err != nil {
+ return err
+ }
+ }
+ }
+ default:
+ if opt == "" {
+ break
+ }
+
+ if err = handler(opt); err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+}
+
+// Skip is an error that contains all unprocessed items passed to Parse.
+type Skip []string
+
+func (s Skip) Error() string { return fmt.Sprint([]string(s)) }