| package flags |
| |
| import ( |
| "fmt" |
| "strings" |
| "unicode/utf8" |
| ) |
| |
| func (p *Parser) storeDefaults() { |
| p.EachGroup(func(index int, grp *Group) { |
| grp.storeDefaults() |
| }) |
| } |
| |
| func (p *Parser) parseOption(group *Group, args []string, name string, option *Option, canarg bool, argument *string, index int) (error, int, *Option) { |
| var err error |
| |
| if !option.canArgument() { |
| if canarg && argument != nil { |
| return newError(ErrNoArgumentForBool, |
| fmt.Sprintf("bool flag `%s' cannot have an argument", option)), |
| index, |
| option |
| } |
| |
| err = option.Set(nil) |
| } else if canarg && (argument != nil || index < len(args) && !argumentIsOption(args[index])) { |
| if argument == nil { |
| argument = &args[index] |
| index++ |
| } |
| |
| err = option.Set(argument) |
| } else if option.OptionalArgument { |
| option.clear() |
| |
| for _, v := range option.OptionalValue { |
| err = option.Set(&v) |
| |
| if err != nil { |
| break |
| } |
| } |
| } else { |
| return newError(ErrExpectedArgument, |
| fmt.Sprintf("expected argument for flag `%s'", option)), |
| index, |
| option |
| } |
| |
| if err != nil { |
| if _, ok := err.(*Error); !ok { |
| err = newError(ErrMarshal, |
| fmt.Sprintf("invalid argument for flag `%s' (expected %s): %s", |
| option, |
| option.Value.Type(), |
| err.Error())) |
| } |
| } |
| |
| return err, index, option |
| } |
| |
| func (p *Parser) parseLong(args []string, name string, argument *string, index int) (error, int, *Option) { |
| name = strings.ToLower(name) |
| |
| var option *Option |
| var group *Group |
| |
| p.EachGroup(func(index int, grp *Group) { |
| if opt := grp.LongNames[name]; opt != nil { |
| option = opt |
| group = grp |
| } |
| }) |
| |
| if option != nil { |
| return p.parseOption(group, args, name, option, true, argument, index) |
| } |
| |
| return newError(ErrUnknownFlag, |
| fmt.Sprintf("unknown flag `%s'", name)), |
| index, |
| nil |
| } |
| |
| func (p *Parser) getShort(name rune) (*Option, *Group) { |
| var option *Option |
| var group *Group |
| |
| p.EachGroup(func(index int, grp *Group) { |
| if opt := grp.ShortNames[name]; opt != nil { |
| option = opt |
| group = grp |
| } |
| }) |
| |
| if option != nil { |
| return option, group |
| } |
| |
| return nil, nil |
| } |
| |
| func (p *Parser) parseShort(args []string, name rune, islast bool, argument *string, index int) (error, int, *Option) { |
| names := make([]byte, utf8.RuneLen(name)) |
| utf8.EncodeRune(names, name) |
| |
| option, grp := p.getShort(name) |
| |
| if option != nil { |
| if option.canArgument() && !islast && !option.OptionalArgument { |
| return newError(ErrExpectedArgument, |
| fmt.Sprintf("expected argument for flag `%s'", option)), |
| index, |
| option |
| } |
| |
| return p.parseOption(grp, args, string(names), option, islast, argument, index) |
| } |
| |
| return newError(ErrUnknownFlag, |
| fmt.Sprintf("unknown flag `%s'", string(names))), |
| index, |
| nil |
| } |
| |
| func (p *Parser) parseIni(ini Ini) error { |
| for groupName, section := range ini { |
| group := p.GroupsMap[strings.ToLower(groupName)] |
| |
| if group == nil { |
| return newError(ErrUnknownGroup, |
| fmt.Sprintf("could not find option group `%s'", groupName)) |
| } |
| |
| for name, val := range section { |
| opt, usedName := group.lookupByName(name, true) |
| |
| if opt == nil { |
| if (p.Options & IgnoreUnknown) == None { |
| return newError(ErrUnknownFlag, |
| fmt.Sprintf("unknown option: %s", name)) |
| } |
| |
| continue |
| } |
| |
| if opt.tag.Get("no-ini") != "" { |
| continue |
| } |
| |
| opt.iniUsedName = usedName |
| |
| pval := &val |
| |
| if opt.isBool() && len(val) == 0 { |
| pval = nil |
| } |
| |
| if err := opt.Set(pval); err != nil { |
| return wrapError(err) |
| } |
| } |
| } |
| |
| return nil |
| } |
| |
| func (p *Parser) currentCommander() *Commander { |
| if p.currentCommand != nil { |
| return &p.currentCommand.Commander |
| } |
| |
| return &p.Commander |
| } |
| |
| func (p *Parser) eachTopLevelGroup(cb func(int, *Group)) { |
| index := 0 |
| |
| for _, group := range p.Groups { |
| if !group.IsCommand { |
| index = group.each(index, cb) |
| } |
| } |
| } |