136 lines
1.9 KiB
Go
136 lines
1.9 KiB
Go
|
package crushmap
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"strconv"
|
||
|
)
|
||
|
|
||
|
func deviceState(l *lex) stateFn {
|
||
|
l.lexIgnore()
|
||
|
l.lexEmit(itemDeviceBeg)
|
||
|
|
||
|
return deviceIDState
|
||
|
}
|
||
|
|
||
|
func deviceIDState(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(itemDeviceID)
|
||
|
return deviceNameState
|
||
|
}
|
||
|
|
||
|
func deviceNameState(l *lex) stateFn {
|
||
|
l.lexTake(" \t")
|
||
|
l.lexIgnore()
|
||
|
|
||
|
loop:
|
||
|
for {
|
||
|
r := l.lexPeek()
|
||
|
switch r {
|
||
|
case ' ', '\n', '#', '\t':
|
||
|
break loop
|
||
|
default:
|
||
|
l.lexNext()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
l.lexEmit(itemDeviceName)
|
||
|
return deviceIdentState
|
||
|
}
|
||
|
|
||
|
func deviceIdentState(l *lex) stateFn {
|
||
|
l.lexTake(" \t")
|
||
|
l.lexIgnore()
|
||
|
|
||
|
loop:
|
||
|
for {
|
||
|
r := l.lexPeek()
|
||
|
switch r {
|
||
|
case '\n', '#':
|
||
|
l.lexEmit(itemDeviceEnd)
|
||
|
return l.lexPop()
|
||
|
case ' ':
|
||
|
break loop
|
||
|
default:
|
||
|
l.lexNext()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
switch l.lexCurrent() {
|
||
|
case "class":
|
||
|
l.lexIgnore()
|
||
|
return deviceClassState
|
||
|
}
|
||
|
|
||
|
return l.lexPop()
|
||
|
}
|
||
|
|
||
|
func deviceClassState(l *lex) stateFn {
|
||
|
l.lexTake(" \t")
|
||
|
l.lexIgnore()
|
||
|
|
||
|
loop:
|
||
|
for {
|
||
|
r := l.lexPeek()
|
||
|
switch r {
|
||
|
case '\n', '#', ' ':
|
||
|
break loop
|
||
|
default:
|
||
|
l.lexNext()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
l.lexEmit(itemDeviceClass)
|
||
|
return deviceIdentState
|
||
|
}
|
||
|
|
||
|
func (p *textParser) handleDevice() (*Device, error) {
|
||
|
idevice := &Device{ID: -1}
|
||
|
|
||
|
Loop:
|
||
|
for {
|
||
|
tok, done := p.l.lexNextToken()
|
||
|
if done {
|
||
|
break Loop
|
||
|
}
|
||
|
switch tok.itype {
|
||
|
case itemEOF, itemDeviceEnd:
|
||
|
break Loop
|
||
|
case itemComment:
|
||
|
continue
|
||
|
case itemDeviceID:
|
||
|
id, err := strconv.Atoi(tok.ivalue)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
idevice.ID = int32(id)
|
||
|
case itemDeviceName:
|
||
|
idevice.Name = tok.ivalue
|
||
|
case itemDeviceClass:
|
||
|
idevice.Class = tok.ivalue
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if idevice.Name == "" {
|
||
|
return nil, errors.New("invalid device")
|
||
|
}
|
||
|
|
||
|
return idevice, nil
|
||
|
}
|