aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-05-22 05:28:31 +0200
committerDmitry Vyukov <dvyukov@google.com>2017-08-18 11:26:50 +0200
commit127a9c2b65ae07f309e839c3b8e5ab2ee7983e56 (patch)
tree3a4dd2af0a2fc09b2bba1dad738c7657d1b0de1d /tools
parent5809a8e05714bda367f3fd57f9b983a3403f04b0 (diff)
pkg/ast: new parser for sys descriptions
The old parser in sys/sysparser is too hacky, difficult to extend and drops debug info too early, so that we can't produce proper error messages. Add a new parser that is build like a proper language parser and preserves full debug info for every token.
Diffstat (limited to 'tools')
-rw-r--r--tools/syz-fmt/syz-fmt.go72
1 files changed, 72 insertions, 0 deletions
diff --git a/tools/syz-fmt/syz-fmt.go b/tools/syz-fmt/syz-fmt.go
new file mode 100644
index 000000000..f78e8b8dc
--- /dev/null
+++ b/tools/syz-fmt/syz-fmt.go
@@ -0,0 +1,72 @@
+// Copyright 2017 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.
+
+// syz-fmt re-formats sys files into standard form.
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/google/syzkaller/pkg/ast"
+)
+
+func main() {
+ if len(os.Args) < 2 {
+ fmt.Fprintf(os.Stderr, "usage: syz-fmt files... or dirs...\n")
+ os.Exit(1)
+ }
+ for _, arg := range os.Args[1:] {
+ st, err := os.Stat(arg)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to stat %v: %v\n", arg, err)
+ os.Exit(1)
+ }
+ if st.IsDir() {
+ files, err := ioutil.ReadDir(arg)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to read dir %v: %v\n", arg, err)
+ os.Exit(1)
+ }
+ for _, file := range files {
+ if !strings.HasSuffix(file.Name(), ".txt") {
+ continue
+ }
+ processFile(filepath.Join(arg, file.Name()), file.Mode())
+ }
+ } else {
+ processFile(arg, st.Mode())
+ }
+ }
+}
+
+func processFile(file string, mode os.FileMode) {
+ data, err := ioutil.ReadFile(file)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "failed to read file %v: %v\n", file, err)
+ os.Exit(1)
+ }
+ errorHandler := func(pos ast.Pos, msg string) {
+ fmt.Fprintf(os.Stderr, "%v:%v:%v: %v", pos.File, pos.Line, pos.Col, msg)
+ }
+ top, ok := ast.Parse(data, filepath.Base(file), errorHandler)
+ if !ok {
+ os.Exit(1)
+ }
+ formatted := ast.Format(top)
+ if bytes.Equal(data, formatted) {
+ return
+ }
+ if err := os.Rename(file, file+"~"); err != nil {
+ fmt.Fprintf(os.Stderr, "%v\n", err)
+ os.Exit(1)
+ }
+ if err := ioutil.WriteFile(file, formatted, mode); err != nil {
+ fmt.Fprintf(os.Stderr, "%v\n", err)
+ os.Exit(1)
+ }
+}