/
procfs_parser_linux.go
95 lines (78 loc) · 1.7 KB
/
procfs_parser_linux.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Package serialdet provides method for finding active serial ports
package serialdet
import (
"regexp"
"strings"
)
// Headers.
const (
procfsUSBHeadPrefix = "usbserinfo:1.0"
procfsSerHeadPrefix = "serinfo:1.0"
)
// Files to TTY.
const (
devUSBTTY = "/dev/ttyUSB"
devSerTTY = "/dev/ttyS"
)
// Regular expressions for parsing devices.
const (
procfsUSBRe = `^.+name:"(?P<Name>.+)" .+port:(?P<Port>\d+) .+$`
procfsSerRe = `^(?P<Port>\d+):.+uart:(?P<Name>\w+) .+$`
)
const serialInvalidName = "unknown"
type parserInfo struct {
re *regexp.Regexp
path string
}
var parserInfoByHead = map[string]parserInfo{
procfsUSBHeadPrefix: {
re: regexp.MustCompile(procfsUSBRe),
path: devUSBTTY,
},
procfsSerHeadPrefix: {
re: regexp.MustCompile(procfsSerRe),
path: devSerTTY,
},
}
type procfsParser struct {
info *parserInfo
list []SerialPortInfo
}
func (p *procfsParser) Reset() {
p.info = nil
}
func (p procfsParser) GetList() (res []SerialPortInfo) {
res = make([]SerialPortInfo, len(p.list))
copy(res, p.list)
return res
}
func (p *procfsParser) AddLine(line string) error {
// Resolve type
if p.info == nil {
p.list = make([]SerialPortInfo, 0)
for h, t := range parserInfoByHead {
if strings.HasPrefix(line, h) {
p.info = &t
return nil
}
}
return ErrInvalidInformationHeader
}
var matched = p.info.re.FindStringSubmatch(line)
if len(matched) != 3 {
return ErrInvalidRow
}
var info SerialPortInfo
for i, expName := range p.info.re.SubexpNames() {
switch expName {
case "Name":
info.description = matched[i]
case "Port":
info.path = p.info.path + matched[i]
}
}
if info.description != serialInvalidName {
p.list = append(p.list, info)
}
return nil
}