aboutsummaryrefslogtreecommitdiffstats
path: root/sys/sysparser/parser.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-06-17 13:17:11 +0200
committerDmitry Vyukov <dvyukov@google.com>2017-06-17 14:41:15 +0200
commit2007005ac39f66f3fb6314745ffb22b6d30314d3 (patch)
treedbdfe1600cf905199e058ff799b0c8f31efcf7a8 /sys/sysparser/parser.go
parent017b5dea530573ce49ccc6f09c469a78c7dbaede (diff)
sys/sysparser: move from sysparser
Diffstat (limited to 'sys/sysparser/parser.go')
-rw-r--r--sys/sysparser/parser.go100
1 files changed, 100 insertions, 0 deletions
diff --git a/sys/sysparser/parser.go b/sys/sysparser/parser.go
new file mode 100644
index 000000000..d5021eee6
--- /dev/null
+++ b/sys/sysparser/parser.go
@@ -0,0 +1,100 @@
+// Copyright 2015/2016 syzkaller project authors. All rights reserved.
+// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
+
+package sysparser
+
+import (
+ "bufio"
+ "fmt"
+ "io"
+ "os"
+)
+
+type parser struct {
+ r *bufio.Scanner
+ s string
+ i int
+ l int
+}
+
+func newParser(r io.Reader) *parser {
+ return &parser{r: bufio.NewScanner(r)}
+}
+
+func (p *parser) Scan() bool {
+ if !p.r.Scan() {
+ if err := p.r.Err(); err != nil {
+ failf("failed to read input file: %v", err)
+ }
+ return false
+ }
+ p.s = p.r.Text()
+ p.i = 0
+ p.l++
+ return true
+}
+
+func (p *parser) Str() string {
+ return p.s
+}
+
+func (p *parser) EOF() bool {
+ return p.i == len(p.s)
+}
+
+func (p *parser) Char() byte {
+ if p.EOF() {
+ p.failf("unexpected eof")
+ }
+ return p.s[p.i]
+}
+
+func (p *parser) Parse(ch byte) {
+ if p.EOF() {
+ p.failf("want %s, got EOF", string(ch))
+ }
+ if p.s[p.i] != ch {
+ p.failf("want '%v', got '%v'", string(ch), string(p.s[p.i]))
+ }
+ p.i++
+ p.SkipWs()
+}
+
+func (p *parser) SkipWs() {
+ for p.i < len(p.s) && (p.s[p.i] == ' ' || p.s[p.i] == '\t') {
+ p.i++
+ }
+}
+
+func (p *parser) Ident() string {
+ start, end := p.i, 0
+ if p.Char() == '"' {
+ p.Parse('"')
+ for p.Char() != '"' {
+ p.i++
+ }
+ end = p.i + 1
+ p.Parse('"')
+ } else {
+ for p.i < len(p.s) &&
+ (p.s[p.i] >= 'a' && p.s[p.i] <= 'z' ||
+ p.s[p.i] >= 'A' && p.s[p.i] <= 'Z' ||
+ p.s[p.i] >= '0' && p.s[p.i] <= '9' ||
+ p.s[p.i] == '_' || p.s[p.i] == '$' || // $ is for n-way syscalls (like ptrace$peek)
+ p.s[p.i] == '-' || p.s[p.i] == ':') { // : is for ranged int (like int32[-3:10])
+ p.i++
+ }
+ if start == p.i {
+ p.failf("failed to parse identifier at pos %v", start)
+ }
+ end = p.i
+ }
+ s := p.s[start:end]
+ p.SkipWs()
+ return s
+}
+
+func (p *parser) failf(msg string, args ...interface{}) {
+ fmt.Fprintf(os.Stderr, "line #%v: %v\n", p.l, p.s)
+ failf(msg, args...)
+}