1// Copyright 2017 syzkaller project authors. All rights reserved. 2// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4// syz-fmt re-formats sys files into standard form. 5package main 6 7import ( 8 "bytes" 9 "fmt" 10 "io/ioutil" 11 "os" 12 "path/filepath" 13 "strings" 14 15 "github.com/google/syzkaller/pkg/ast" 16) 17 18func main() { 19 if len(os.Args) < 2 { 20 fmt.Fprintf(os.Stderr, "usage: syz-fmt files... or dirs...\n") 21 os.Exit(1) 22 } 23 for _, arg := range os.Args[1:] { 24 st, err := os.Stat(arg) 25 if err != nil { 26 fmt.Fprintf(os.Stderr, "failed to stat %v: %v\n", arg, err) 27 os.Exit(1) 28 } 29 if st.IsDir() { 30 files, err := ioutil.ReadDir(arg) 31 if err != nil { 32 fmt.Fprintf(os.Stderr, "failed to read dir %v: %v\n", arg, err) 33 os.Exit(1) 34 } 35 for _, file := range files { 36 if !strings.HasSuffix(file.Name(), ".txt") { 37 continue 38 } 39 processFile(filepath.Join(arg, file.Name()), file.Mode()) 40 } 41 } else { 42 processFile(arg, st.Mode()) 43 } 44 } 45} 46 47func processFile(file string, mode os.FileMode) { 48 data, err := ioutil.ReadFile(file) 49 if err != nil { 50 fmt.Fprintf(os.Stderr, "failed to read file %v: %v\n", file, err) 51 os.Exit(1) 52 } 53 desc := ast.Parse(data, filepath.Base(file), nil) 54 if desc == nil { 55 os.Exit(1) 56 } 57 formatted := ast.Format(desc) 58 if bytes.Equal(data, formatted) { 59 return 60 } 61 fmt.Printf("reformatting %v\n", file) 62 if err := os.Rename(file, file+"~"); err != nil { 63 fmt.Fprintf(os.Stderr, "%v\n", err) 64 os.Exit(1) 65 } 66 if err := ioutil.WriteFile(file, formatted, mode); err != nil { 67 fmt.Fprintf(os.Stderr, "%v\n", err) 68 os.Exit(1) 69 } 70} 71