2020-02-12 09:39:46 +00:00
|
|
|
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 {
|
2020-02-12 14:55:03 +00:00
|
|
|
return fmt.Sprintf("-%s | --%s", a.sname, a.lname)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *arg) getType() string {
|
|
|
|
switch a.value.(type) {
|
|
|
|
case *string:
|
|
|
|
return "string"
|
|
|
|
case *int:
|
|
|
|
return "int"
|
|
|
|
case *bool:
|
|
|
|
return "bool"
|
|
|
|
case *float64:
|
|
|
|
return "float"
|
|
|
|
case *[]string:
|
|
|
|
return "[]string"
|
|
|
|
case *[]int:
|
|
|
|
return "[]int"
|
|
|
|
case *[]float64:
|
|
|
|
return "[]float"
|
|
|
|
default:
|
|
|
|
return "not support"
|
2020-02-12 09:39:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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:
|
2020-02-12 14:55:03 +00:00
|
|
|
return a.parseStringSlice(args)
|
2020-02-12 09:39:46 +00:00
|
|
|
case *[]int:
|
2020-02-12 14:55:03 +00:00
|
|
|
return a.parseIntSlice(args)
|
2020-02-12 09:39:46 +00:00
|
|
|
case *[]float64:
|
2020-02-12 14:55:03 +00:00
|
|
|
return a.parseFloatSlice(args)
|
2020-02-12 09:39:46 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2020-02-12 14:55:03 +00:00
|
|
|
func (a *arg) parseStringSlice(args []string) (err error) {
|
|
|
|
if len(args) == 0 {
|
|
|
|
return ErrNoArg
|
|
|
|
}
|
|
|
|
|
|
|
|
*((a.value).(*[]string)) = append(*((a.value).(*[]string)), args...)
|
|
|
|
a.parsed = true
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-02-12 09:39:46 +00:00
|
|
|
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 {
|
2020-02-12 14:55:03 +00:00
|
|
|
return fmt.Errorf("[%s] bad int value (%v)", a.name(), args[0])
|
2020-02-12 09:39:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-02-12 14:55:03 +00:00
|
|
|
func (a *arg) parseIntSlice(args []string) (err error) {
|
|
|
|
if len(args) == 0 {
|
|
|
|
return ErrNoArg
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, v := range args {
|
|
|
|
if i, err := strconv.Atoi(v); err == nil {
|
|
|
|
*((a.value).(*[]int)) = append(*((a.value).(*[]int)), i)
|
|
|
|
} else {
|
|
|
|
return fmt.Errorf("[%s] bad int value (%v)", a.name(), v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
a.parsed = true
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-02-12 09:39:46 +00:00
|
|
|
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 {
|
2020-02-12 14:55:03 +00:00
|
|
|
return fmt.Errorf("[%s] bad float value (%v)", a.name(), args[0])
|
2020-02-12 09:39:46 +00:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
2020-02-12 14:55:03 +00:00
|
|
|
|
|
|
|
func (a *arg) parseFloatSlice(args []string) (err error) {
|
|
|
|
if len(args) == 0 {
|
|
|
|
return ErrNoArg
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, v := range args {
|
|
|
|
if f, err := strconv.ParseFloat(v, 64); err == nil {
|
|
|
|
*((a.value).(*[]float64)) = append(*((a.value).(*[]float64)), f)
|
|
|
|
} else {
|
|
|
|
return fmt.Errorf("[%s] bad float value (%v)", a.name(), v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
a.parsed = true
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|