aboutsummaryrefslogtreecommitdiff
path: root/opts.go
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2023-11-29 20:30:50 +0100
committerThomas Voss <mail@thomasvoss.com> 2023-11-29 20:30:50 +0100
commit9578d76a8fd70ca766178175f5ba97ce284b6ff6 (patch)
tree5f545cc463bb23d57a51eb754b67c86b9943584f /opts.go
Genesis commit
Diffstat (limited to 'opts.go')
-rw-r--r--opts.go71
1 files changed, 71 insertions, 0 deletions
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
+}