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  }