modernc.org/cc@v1.0.1/generate.go (about) 1 // Copyright 2016 The CC Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build ignore 6 7 package main 8 9 import ( 10 "bytes" 11 "flag" 12 "io/ioutil" 13 "log" 14 "os" 15 "os/exec" 16 "path/filepath" 17 ) 18 19 func yy() (nm string, err error) { 20 y, err := os.Create("parser.y") 21 if err != nil { 22 return "", err 23 } 24 y.Close() 25 26 nm = y.Name() 27 cmd := exec.Command( 28 "yy", 29 "-astImport", "\"go/token\"\n\n\"modernc.org/xc\"", 30 "-kind", "Case", 31 "-o", nm, 32 "-prettyString", "PrettyString", 33 "parser.yy", 34 ) 35 if out, err := cmd.CombinedOutput(); err != nil { 36 os.Remove(nm) 37 log.Printf("%s", out) 38 39 return "", err 40 } 41 42 return nm, nil 43 } 44 45 func goyacc(y string) (err error) { 46 t, err := ioutil.TempFile("", "go-generate-xegen-") 47 if err != nil { 48 log.Fatal(err) 49 } 50 defer func() { 51 t.Close() 52 if e := os.Remove(t.Name()); e != nil && err == nil { 53 err = e 54 } 55 }() 56 57 cmd := exec.Command("goyacc", "-o", os.DevNull, "-xegen", t.Name(), "-ex", y) 58 if out, err := cmd.CombinedOutput(); err != nil { 59 log.Printf("%s\n", out) 60 return err 61 } 62 63 xerrors, err := ioutil.ReadFile("xerrors") 64 if err != nil { 65 return err 66 } 67 68 if _, err := t.Seek(0, 2); err != nil { 69 return err 70 } 71 72 if _, err := t.Write(xerrors); err != nil { 73 return err 74 } 75 76 cmd = exec.Command("goyacc", "-cr", "-xe", t.Name(), "-o", "parser.go", "-dlvalf", "%v", "-dlval", "PrettyString(lval.Token)", y) 77 if out, err := cmd.CombinedOutput(); err != nil { 78 log.Printf("%s", out) 79 return err 80 } else { 81 log.Printf("%s", out) 82 } 83 84 return nil 85 } 86 87 func main() { 88 if err := main0(); err != nil { 89 log.Fatal(err) 90 } 91 } 92 93 func main0() (err error) { 94 log.SetFlags(log.Lshortfile) 95 p2 := flag.Bool("2", false, "") 96 flag.Parse() 97 if *p2 { 98 return main2() 99 } 100 101 os.Remove("ast.go") 102 os.Remove("ast_test.go") 103 y, err := yy() 104 if err != nil { 105 return err 106 } 107 108 return goyacc(y) 109 } 110 111 func main2() (err error) { 112 goCmd := exec.Command("go", "test", "-generating", "-run", "^Example") 113 out, err := goCmd.CombinedOutput() // Errors are expected and wanted here. 114 feCmd := exec.Command("fe") 115 feCmd.Stdin = bytes.NewBuffer(out) 116 if out, err = feCmd.CombinedOutput(); err != nil { 117 log.Printf("%s", out) 118 return err 119 } 120 121 matches, err := filepath.Glob("*_test.go") 122 if err != nil { 123 return err 124 } 125 126 cmd := exec.Command("pcregrep", append([]string{"-nM", `failed|panic|\/\/ <nil>|// false|// -1|Output:\n}`}, matches...)...) 127 if out, _ = cmd.CombinedOutput(); len(out) != 0 { // Error != nil when no matches 128 log.Printf("%s", out) 129 } 130 return nil 131 }