175 lines
3.0 KiB
Go
175 lines
3.0 KiB
Go
|
package argparse
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
ErrArgTooMany = errors.New("arg too manu")
|
||
|
ErrNoArg = errors.New("no arg")
|
||
|
)
|
||
|
|
||
|
func (a *arg) check(s string) (count int, err error) {
|
||
|
res := a.checkLongName(s)
|
||
|
if res > 0 {
|
||
|
return res, nil
|
||
|
}
|
||
|
return a.checkShortName(s)
|
||
|
}
|
||
|
|
||
|
func (a *arg) checkLongName(s string) int {
|
||
|
if a.lname != "" {
|
||
|
if len(s) > 2 && strings.HasPrefix(s, "--") && s[2] != '-' {
|
||
|
if s[2:] == a.lname {
|
||
|
return 1
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
func (a *arg) checkShortName(s string) (int, error) {
|
||
|
if a.sname != "" {
|
||
|
if len(s) > 1 && strings.HasPrefix(s, "-") && s[1] != '-' {
|
||
|
if s[1:] == a.sname {
|
||
|
return 1, nil
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return 0, nil
|
||
|
}
|
||
|
|
||
|
func (a *arg) reduce(pos int, args *[]string) {
|
||
|
a.reduceLongName(pos, args)
|
||
|
a.reduceShortName(pos, args)
|
||
|
}
|
||
|
|
||
|
func (a *arg) reduceLongName(pos int, args *[]string) {
|
||
|
s := (*args)[pos]
|
||
|
if a.lname == "" {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if res := a.checkLongName(s); res == 0 {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
for i := pos; i <= pos+a.size; i++ {
|
||
|
(*args)[i] = ""
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (a *arg) reduceShortName(pos int, args *[]string) {
|
||
|
s := (*args)[pos]
|
||
|
if a.sname == "" {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if res, err := a.checkShortName(s); res == 0 || err != nil {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
for i := pos; i <= pos+a.size; i++ {
|
||
|
(*args)[i] = ""
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (a *arg) name() string {
|
||
|
if a.sname == "" {
|
||
|
return fmt.Sprintf("--%s", a.lname)
|
||
|
} else if a.lname == "" {
|
||
|
return fmt.Sprintf("-%s", a.sname)
|
||
|
} else {
|
||
|
return fmt.Sprintf("-%s|--%s", a.sname, a.lname)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (a *arg) parse(args []string) error {
|
||
|
if a.unique && a.parsed {
|
||
|
return fmt.Errorf("[%s] can only parsent once\n", a.name())
|
||
|
}
|
||
|
return a.parseType(args)
|
||
|
}
|
||
|
|
||
|
func (a *arg) parseType(args []string) error {
|
||
|
var err error
|
||
|
switch a.value.(type) {
|
||
|
case *string:
|
||
|
return a.parseString(args)
|
||
|
case *int:
|
||
|
return a.parseInt(args)
|
||
|
case *bool:
|
||
|
return a.parseBool(args)
|
||
|
case *float64:
|
||
|
return a.parseFloat(args)
|
||
|
case *[]string:
|
||
|
case *[]int:
|
||
|
case *[]float64:
|
||
|
default:
|
||
|
err = fmt.Errorf("unsupport type [%t]", a.value)
|
||
|
}
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
func (a *arg) parseString(args []string) error {
|
||
|
var err error
|
||
|
|
||
|
if len(args) > 1 {
|
||
|
return ErrArgTooMany
|
||
|
}
|
||
|
if len(args) == 0 {
|
||
|
return ErrNoArg
|
||
|
}
|
||
|
|
||
|
*((a.value).(*string)) = args[0]
|
||
|
a.parsed = true
|
||
|
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
func (a *arg) parseInt(args []string) error {
|
||
|
var err error
|
||
|
|
||
|
if len(args) > 1 {
|
||
|
return ErrArgTooMany
|
||
|
}
|
||
|
if len(args) == 0 {
|
||
|
return ErrNoArg
|
||
|
}
|
||
|
|
||
|
if i, err := strconv.Atoi(args[0]); err == nil {
|
||
|
*((a.value).(*int)) = i
|
||
|
a.parsed = true
|
||
|
} else {
|
||
|
return fmt.Errorf("[%s] bad int value", a.name())
|
||
|
}
|
||
|
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
func (a *arg) parseBool(args []string) error {
|
||
|
*a.value.(*bool) = true
|
||
|
a.parsed = true
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (a *arg) parseFloat(args []string) (err error) {
|
||
|
if len(args) > 1 {
|
||
|
return ErrArgTooMany
|
||
|
}
|
||
|
if len(args) == 0 {
|
||
|
return ErrNoArg
|
||
|
}
|
||
|
|
||
|
if f, err := strconv.ParseFloat(args[0], 64); err == nil {
|
||
|
*a.value.(*float64) = f
|
||
|
a.parsed = true
|
||
|
} else {
|
||
|
return fmt.Errorf("[%s] bad float value", a.name())
|
||
|
}
|
||
|
return
|
||
|
}
|