package argparse import ( "errors" "fmt" "reflect" ) type Parser struct { args []*arg parsed bool } type arg struct { sname string lname string // value number count size int value interface{} unique bool parsed bool } func New() *Parser { return &Parser{ args: make([]*arg, 0), } } func (p *Parser) addArg(a *arg) error { for _, v := range p.args { if (v.sname == a.sname || v.lname == a.lname) && (a.unique || v.unique) { return errors.New("option name dup") } } p.args = append(p.args, a) return nil } func (p *Parser) typeVar(i interface{}, short, long string, size int, unique bool) { t := reflect.ValueOf(i) if t.Kind() != reflect.Ptr { panic(errors.New("var type not ptr")) } a := &arg{ sname: short, lname: long, value: i, size: size, unique: unique, } if err := p.addArg(a); err != nil { panic(fmt.Errorf("unable to add String: %s\n", err)) } } func (p *Parser) Parse(a []string) error { copyArg := make([]string, len(a)) copy(copyArg, a) err := p.parse(©Arg) if err != nil { return err } return nil } // in loop func func (p *Parser) parse(args *[]string) error { if p.parsed { return nil } if len(*args) < 1 { return nil } err := p.parseArguemtns(args) if err != nil { return err } p.parsed = true return nil } func (p *Parser) parseArguemtns(args *[]string) error { n := len(p.args) for i := 0; i < n; i++ { nn := len(*args) oarg := p.args[i] for j := 0; j < nn; j++ { s := (*args)[j] if s == "" { continue } ct, err := oarg.check(s) if err != nil { return err } if ct > 0 { valpos := j + 1 if len(*args) < valpos+oarg.size { return fmt.Errorf("no enough arguments for %s", oarg.name()) } err := oarg.parse((*args)[valpos : valpos+oarg.size]) if err != nil { return err } oarg.reduce(j, args) continue } } } return nil } func (p *Parser) String(short, long string) *string { var result string p.typeVar(&result, short, long, 1, true) return &result } func (p *Parser) StringVar(i *string, short, long string) { p.typeVar(i, short, long, 1, true) } func (p *Parser) Int(short, long string) *int { var result int p.typeVar(&result, short, long, 1, true) return &result } func (p *Parser) IntVar(i *int, short, long string) { p.typeVar(i, short, long, 1, true) } func (p *Parser) Bool(short, long string) *bool { var result bool p.typeVar(&result, short, long, 0, true) return &result } func (p *Parser) BoolVar(i *bool, short, long string) { p.typeVar(i, short, long, 0, true) } func (p *Parser) Float(short, long string) *float64 { var result float64 p.typeVar(&result, short, long, 1, true) return &result } func (p *Parser) FloatVar(i *float64, short, long string) { p.typeVar(i, short, long, 1, true) }