From 9578d76a8fd70ca766178175f5ba97ce284b6ff6 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Wed, 29 Nov 2023 20:30:50 +0100 Subject: Genesis commit --- LICENSE | 14 +++++++++++++ err.go | 15 ++++++++++++++ go.mod | 3 +++ opts.go | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 LICENSE create mode 100644 err.go create mode 100644 go.mod create mode 100644 opts.go diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e663355 --- /dev/null +++ b/LICENSE @@ -0,0 +1,14 @@ +BSD Zero Clause License + +Copyright (c) 2023 Thomas Voss + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/err.go b/err.go new file mode 100644 index 0000000..b964c11 --- /dev/null +++ b/err.go @@ -0,0 +1,15 @@ +package opts + +import "fmt" + +type ErrBadOption rune + +func (e ErrBadOption) Error() string { + return fmt.Sprintf("unknown option ā€˜%cā€™", e) +} + +type ErrNoArgument rune + +func (e ErrNoArgument) Error() string { + return fmt.Sprintf("expected argument for option ā€˜%cā€™", e) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..afe5f05 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module git.sr.ht/~mango/opts + +go 1.21.4 diff --git a/opts.go b/opts.go new file mode 100644 index 0000000..c7ab697 --- /dev/null +++ b/opts.go @@ -0,0 +1,71 @@ +package opts + +type ArgMode int + +const ( + None ArgMode = iota + Required + Optional +) + +type Flag struct { + Key rune + Value string +} + +type LongOpt struct { + Short rune + Long string + Arg ArgMode +} + +func Get(args []string, optstr string) (flags []Flag, optind int, err error) { + argmap := make(map[rune]bool) + + rs := []rune(optstr) + for i, r := range rs { + if r != ':' { + argmap[r] = false + } else if i > 0 { + argmap[rs[i-1]] = true + } + } + + for i := 1; i < len(args); i++ { + arg := args[i] + if len(arg) == 0 || arg == "-" || arg[0] != '-' { + optind = i + return + } else if arg == "--" { + optind = i + 1 + return + } + + rs := []rune(arg[1:]) + outer: + for j, r := range rs { + argp, ok := argmap[r] + if !ok { + return nil, 0, ErrBadOption(r) + } + + switch { + case argp && j < len(rs)-1: + s := string(rs[j+1:]) + flags = append(flags, Flag{r, s}) + break outer + case argp: + i++ + if i >= len(args) { + return nil, 0, ErrNoArgument(r) + } + flags = append(flags, Flag{r, args[i]}) + break outer + } + flags = append(flags, Flag{Key: r}) + } + } + + optind = len(args) + return +} -- cgit v1.2.3