101 lines
1.4 KiB
Go
101 lines
1.4 KiB
Go
|
package crushmap
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"strconv"
|
||
|
)
|
||
|
|
||
|
func tunableState(l *lex) stateFn {
|
||
|
l.lexIgnore()
|
||
|
|
||
|
if r := l.lexPeek(); r != ' ' {
|
||
|
l.lexErr(fmt.Sprintf("unexpected token %q", r))
|
||
|
return l.lexPop()
|
||
|
}
|
||
|
|
||
|
l.lexEmit(itemTunableBeg)
|
||
|
|
||
|
return tunableKeyState
|
||
|
}
|
||
|
|
||
|
func tunableKeyState(l *lex) stateFn {
|
||
|
l.lexTake(" \t")
|
||
|
l.lexIgnore()
|
||
|
|
||
|
loop:
|
||
|
for {
|
||
|
r := l.lexPeek()
|
||
|
switch r {
|
||
|
case '\n', '#':
|
||
|
l.lexErr(fmt.Sprintf("unexpected token %q", r))
|
||
|
return l.lexPop()
|
||
|
case ' ':
|
||
|
break loop
|
||
|
default:
|
||
|
l.lexNext()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
l.lexEmit(itemTunableKey)
|
||
|
|
||
|
return tunableValState
|
||
|
}
|
||
|
|
||
|
func tunableValState(l *lex) stateFn {
|
||
|
l.lexTake(" \t")
|
||
|
l.lexIgnore()
|
||
|
|
||
|
loop:
|
||
|
for {
|
||
|
r := l.lexPeek()
|
||
|
switch r {
|
||
|
case '\n', '#', ' ':
|
||
|
break loop
|
||
|
default:
|
||
|
l.lexNext()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
l.lexEmit(itemTunableVal)
|
||
|
|
||
|
l.lexEmit(itemTunableEnd)
|
||
|
|
||
|
return l.lexPop()
|
||
|
}
|
||
|
|
||
|
func (p *textParser) handleTunable() (string, interface{}, error) {
|
||
|
var key string
|
||
|
var val interface{}
|
||
|
|
||
|
Loop:
|
||
|
for {
|
||
|
tok, done := p.l.lexNextToken()
|
||
|
if done {
|
||
|
break Loop
|
||
|
}
|
||
|
|
||
|
switch tok.itype {
|
||
|
case itemEOF, itemTunableEnd:
|
||
|
break Loop
|
||
|
case itemComment:
|
||
|
continue
|
||
|
case itemTunableKey:
|
||
|
key = tok.ivalue
|
||
|
case itemTunableVal:
|
||
|
id, err := strconv.Atoi(tok.ivalue)
|
||
|
if err != nil {
|
||
|
val = tok.ivalue
|
||
|
} else {
|
||
|
val = id
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if key == "" {
|
||
|
return "", nil, errors.New("invalid tunable")
|
||
|
}
|
||
|
|
||
|
return key, val, nil
|
||
|
}
|