Skip to content
This repository has been archived by the owner on May 18, 2024. It is now read-only.

Commit

Permalink
cmd/c2go: support -test
Browse files Browse the repository at this point in the history
  • Loading branch information
xushiwei committed Apr 13, 2022
1 parent 4664862 commit 7751550
Showing 1 changed file with 132 additions and 16 deletions.
148 changes: 132 additions & 16 deletions cmd/c2go/c2go.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package main

import (
"bytes"
"flag"
"fmt"
"io"
"os"
"os/exec"
"path"
"path/filepath"
"strings"

"github.com/goplus/c2go/cl"
"github.com/goplus/c2go/clang/parser"
Expand All @@ -15,10 +19,12 @@ import (

var (
verbose = flag.Bool("v", false, "print verbose information")
test = flag.Bool("test", false, "run test")
)

func usage() {
fmt.Fprintf(os.Stderr, "Usage: c2go [-v] [pkgname] source.c\n")
fmt.Fprintf(os.Stderr, "Usage: c2go [-test -v] [pkgname] source.c\n")
flag.PrintDefaults()
}

func isDir(name string) bool {
Expand Down Expand Up @@ -55,15 +61,12 @@ func main() {
err := preprocessor.Do(infile, outfile, nil)
check(err)
default:
if isDir(infile) {
files, err := filepath.Glob("*.c")
check(err)
switch len(files) {
if strings.HasSuffix(infile, "/...") {
infile = strings.TrimSuffix(infile, "/...")
execDirRecursively(infile, run, *test)
} else if isDir(infile) {
switch n := execDir(pkgname, infile, run, *test); n {
case 1:
infile = files[0]
outfile = infile + ".i"
err := preprocessor.Do(infile, outfile, nil)
check(err)
case 0:
fatalf("no *.c files in this directory.\n")
default:
Expand All @@ -72,8 +75,62 @@ func main() {
} else {
fatalf("%s is not a .c file.\n", infile)
}
return
}
execFile(pkgname, outfile, run, *test)
}

func execDirRecursively(dir string, doRunApp, doRunTest bool) {
if strings.HasPrefix(dir, "_") {
return
}
fis, err := os.ReadDir(dir)
check(err)
var cfiles int
for _, fi := range fis {
if fi.IsDir() {
pkgDir := path.Join(dir, fi.Name())
execDirRecursively(pkgDir, doRunApp, doRunTest)
continue
}
if strings.HasSuffix(fi.Name(), ".c") {
cfiles++
}
}
if cfiles == 1 {
if doRunTest {
fmt.Printf("Testing %s ...\n", dir)
}
execDir("main", dir, doRunApp, doRunTest)
}
}

func execDir(pkgname string, dir string, doRunApp, doRunTest bool) int {
cwd, err := os.Getwd()
check(err)

err = os.Chdir(dir)
check(err)

defer os.Chdir(cwd)

var infile, outfile string
files, err := filepath.Glob("*.c")
check(err)
switch n := len(files); n {
case 1:
infile = files[0]
outfile = infile + ".i"
err := preprocessor.Do(infile, outfile, nil)
check(err)
execFile(pkgname, outfile, doRunApp, doRunTest)
fallthrough
default:
return n
}
}

func execFile(pkgname string, outfile string, doRunApp, doRunTest bool) {
doc, _, err := parser.ParseFile(outfile, 0)
check(err)

Expand All @@ -84,15 +141,74 @@ func main() {
err = gox.WriteFile(gofile, pkg, false)
check(err)

if run {
files, err := filepath.Glob("*.go")
check(err)
if doRunTest {
runTest("")
} else if doRunApp {
runGoApp("", os.Stdout, os.Stderr, false)
}
}

func checkEqual(prompt string, a, expected []byte) {
if bytes.Equal(a, expected) {
return
}

fmt.Fprintln(os.Stderr, "==> Result of", prompt)
os.Stderr.Write(a)

fmt.Fprintln(os.Stderr, "\n==> Expected", prompt)
os.Stderr.Write(expected)
}

func runTest(dir string) {
var goOut, goErr bytes.Buffer
var cOut, cErr bytes.Buffer
dontRunTest := runGoApp(dir, &goOut, &goErr, true)
if dontRunTest {
return
}
runCApp(dir, &cOut, &cErr)
checkEqual("output", goOut.Bytes(), cOut.Bytes())
checkEqual("stderr", goErr.Bytes(), cErr.Bytes())
}

func runGoApp(dir string, stdout, stderr io.Writer, doRunTest bool) (dontRunTest bool) {
files, err := filepath.Glob("*.go")
check(err)

cmd := exec.Command("go", append([]string{"run"}, files...)...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
check(cmd.Run())
if doRunTest {
for _, file := range files {
if filepath.Base(file) == "main.go" {
dontRunTest = true
return
}
}
}
cmd := exec.Command("go", append([]string{"run"}, files...)...)
cmd.Dir = dir
cmd.Stdout = stdout
cmd.Stderr = stderr
check(cmd.Run())
return
}

func runCApp(dir string, stdout, stderr io.Writer) {
files, err := filepath.Glob("*.c")
check(err)

cmd := exec.Command("clang", files...)
cmd.Dir = dir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
check(cmd.Run())

cmd2 := exec.Command("./a.out")
cmd.Dir = dir
cmd2.Stdout = stdout
cmd2.Stderr = stderr
check(cmd2.Run())

os.Remove("./a.out")
}

func check(err error) {
Expand Down

0 comments on commit 7751550

Please sign in to comment.