aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-07-25 14:46:59 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-07-27 10:22:23 +0200
commit68faa5258297b6ba1a167e8233e59ca2c6b2b995 (patch)
treed826029465de57deb3c84218f9475e346f37ecd5
parent0889ba7a79553599d0faaf78fb2403b90b1e1be4 (diff)
prog: parse comments in serialized programs
Remember per-call comments, will be useful for annotating tests. Also support this form: call() # comment
-rw-r--r--prog/encoding.go21
-rw-r--r--prog/encoding_test.go32
-rw-r--r--prog/prog.go7
3 files changed, 53 insertions, 7 deletions
diff --git a/prog/encoding.go b/prog/encoding.go
index f0d96da95..8c853fa4a 100644
--- a/prog/encoding.go
+++ b/prog/encoding.go
@@ -9,6 +9,7 @@ import (
"encoding/hex"
"fmt"
"strconv"
+ "strings"
)
// String generates a very compact program description (mostly for debug output).
@@ -156,8 +157,14 @@ func (target *Target) Deserialize(data []byte) (prog *Prog, err error) {
}
p := newParser(data)
vars := make(map[string]*ResultArg)
+ comment := ""
for p.Scan() {
- if p.EOF() || p.Char() == '#' {
+ if p.EOF() {
+ comment = ""
+ continue
+ }
+ if p.Char() == '#' {
+ comment = strings.TrimSpace(p.s[p.i+1:])
continue
}
name := p.Ident()
@@ -173,8 +180,9 @@ func (target *Target) Deserialize(data []byte) (prog *Prog, err error) {
return nil, fmt.Errorf("unknown syscall %v", name)
}
c := &Call{
- Meta: meta,
- Ret: MakeReturnArg(meta.Ret),
+ Meta: meta,
+ Ret: MakeReturnArg(meta.Ret),
+ Comment: comment,
}
prog.Calls = append(prog.Calls, c)
p.Parse('(')
@@ -197,8 +205,12 @@ func (target *Target) Deserialize(data []byte) (prog *Prog, err error) {
}
}
p.Parse(')')
+ p.SkipWs()
if !p.EOF() {
- return nil, fmt.Errorf("tailing data (line #%v)", p.l)
+ if p.Char() != '#' {
+ return nil, fmt.Errorf("tailing data (line #%v)", p.l)
+ }
+ c.Comment = strings.TrimSpace(p.s[p.i+1:])
}
for i := len(c.Args); i < len(meta.Args); i++ {
c.Args = append(c.Args, target.defaultArg(meta.Args[i]))
@@ -209,6 +221,7 @@ func (target *Target) Deserialize(data []byte) (prog *Prog, err error) {
if r != "" && c.Ret != nil {
vars[r] = c.Ret
}
+ comment = ""
}
if err := p.Err(); err != nil {
return nil, err
diff --git a/prog/encoding_test.go b/prog/encoding_test.go
index c641fd5e6..7ecd811bc 100644
--- a/prog/encoding_test.go
+++ b/prog/encoding_test.go
@@ -303,3 +303,35 @@ func testSerializeDeserialize(t *testing.T, p0 *Prog, data0, data1 []byte) (bool
}
return true, 0, 0
}
+
+func TestDeserializeComments(t *testing.T) {
+ target := initTargetTest(t, "test", "64")
+ p, err := target.Deserialize([]byte(`
+# comment1
+# comment2
+serialize0()
+serialize0()
+# comment3
+serialize0()
+# comment4
+serialize0() # comment5
+#comment6
+
+serialize0()
+#comment7
+`))
+ if err != nil {
+ t.Fatal(err)
+ }
+ for i, want := range []string{
+ "comment2",
+ "",
+ "comment3",
+ "comment5",
+ "",
+ } {
+ if got := p.Calls[i].Comment; got != want {
+ t.Errorf("bad call %v comment: %q, want %q", i, got, want)
+ }
+ }
+}
diff --git a/prog/prog.go b/prog/prog.go
index 19db1893d..95f95ad27 100644
--- a/prog/prog.go
+++ b/prog/prog.go
@@ -13,9 +13,10 @@ type Prog struct {
}
type Call struct {
- Meta *Syscall
- Args []Arg
- Ret *ResultArg
+ Meta *Syscall
+ Args []Arg
+ Ret *ResultArg
+ Comment string
}
type Arg interface {