diff options
author | Jan Mercl <0xjnml@gmail.com> | 2017-07-01 23:04:53 +0200 |
---|---|---|
committer | Jan Mercl <0xjnml@gmail.com> | 2017-07-01 23:04:53 +0200 |
commit | 5e8a085cfb2f6df373a2a68436b1c1acacba592b (patch) | |
tree | 6cd0e355f252b4e45331b7e476904c9b588ddce5 /generator.go | |
parent | 8370d1a12ed5bbad6630675316ee3985d8372a7b (diff) |
Add a couple of tests. Build only on linux, do not pass.
modified: Makefile
modified: all_test.go
modified: generator.go
modified: internal/bin/bin_linux_386.go
modified: internal/bin/bin_linux_amd64.go
new file: internal/mptest/mptest_linux_386.go
new file: internal/mptest/mptest_linux_amd64.go
new file: internal/threadtest1/threadtest1_linux_386.go
new file: internal/threadtest1/threadtest1_linux_amd64.go
new file: internal/threadtest2/threadtest2_linux_386.go
new file: internal/threadtest2/threadtest2_linux_amd64.go
new file: internal/threadtest4/threadtest4_linux_386.go
new file: internal/threadtest4/threadtest4_linux_amd64.go
modified: main.c
new file: sqlite.h
new file: testdata/mptest/config01.test
new file: testdata/mptest/config02.test
new file: testdata/mptest/crash01.test
new file: testdata/mptest/crash02.subtest
new file: testdata/mptest/multiwrite01.test
Diffstat (limited to 'generator.go')
-rw-r--r-- | generator.go | 336 |
1 files changed, 288 insertions, 48 deletions
diff --git a/generator.go b/generator.go index adcf212..f813ce4 100644 --- a/generator.go +++ b/generator.go @@ -12,6 +12,7 @@ import ( "fmt" "go/format" "go/scanner" + "go/token" "io" "io/ioutil" "os" @@ -45,12 +46,17 @@ var ( ) const ( - prologue = `/* + sqliteRepo = "sqlite.org" + version = "3190300" + + prologueSqlite = `// Code generated by ccgo. DO NOT EDIT. + +/* %s */ -// Code generated by ccgo DO NOT EDIT. +%s package bin @@ -71,6 +77,43 @@ func ftrace(s string, args ...interface{}) { os.Stderr.Sync() } ` + + prologueTest = `// Code generated by ccgo. DO NOT EDIT. + +%s + +package main + +import ( + "math" + "os" + "unsafe" + + "github.com/cznic/crt" + "github.com/cznic/sqlite/internal/bin" +) + +var argv []*int8 + +func main() { + for _, v := range os.Args { + argv = append(argv, (*int8)(crt.CString(v))) + } + argv = append(argv, nil) + X_start(crt.NewTLS(), int32(len(os.Args)), &argv[0]) +} + +` + + defines = ` + #define HAVE_MALLOC_H 1 + #define HAVE_MALLOC_USABLE_SIZE 1 + #define HAVE_USLEEP 1 + #define SQLITE_DEBUG 1 + #define SQLITE_ENABLE_API_ARMOR 1 + #define SQLITE_USE_URI 1 + #define SQLITE_WITHOUT_MSIZE 1 + ` ) func findRepo(s string) string { @@ -121,32 +164,29 @@ func errStr(err error) string { } } -func unconvert(pth string) { - wd, err := os.Getwd() - if err != nil { - log.Fatal(err) - } - - defer func() { - if err := os.Chdir(wd); err != nil { - log.Fatal(err) - } - }() - - if err := os.Chdir(filepath.Dir(pth)); err != nil { - log.Fatal(err) - } - - if out, err := exec.Command(unconvertBin, "-apply").CombinedOutput(); err != nil { - log.Fatalf("unconvert: %s\n%s", err, out) - } -} - -func build(predef string, tus [][]string, opts ...cc.Opt) ([]*cc.TranslationUnit, []byte) { +func build(predef string, tus [][]string, qualifiers []string, opts ...cc.Opt) ([]*cc.TranslationUnit, []byte) { ndbg := "" if *ndebug { ndbg = "#define NDEBUG 1" } + + var lpos token.Position + if *cpp { + opts = append(opts, cc.Cpp(func(toks []xc.Token) { + if len(toks) != 0 { + p := toks[0].Position() + if p.Filename != lpos.Filename { + fmt.Fprintf(os.Stderr, "# %d %q\n", p.Line, p.Filename) + } + lpos = p + } + for _, v := range toks { + os.Stderr.WriteString(cc.TokSrc(v)) + } + os.Stderr.WriteString("\n") + })) + } + var build []*cc.TranslationUnit tus = append(tus, []string{ccir.CRT0Path}) for _, src := range tus { @@ -173,6 +213,7 @@ func build(predef string, tus [][]string, opts ...cc.Opt) ([]*cc.TranslationUnit cc.EnableNonConstStaticInitExpressions(), cc.EnableWideBitFieldTypes(), cc.ErrLimit(*errLimit), + cc.KeepComments(), cc.SysIncludePaths([]string{ccir.LibcIncludePath}), }, opts...)..., ) @@ -184,7 +225,7 @@ func build(predef string, tus [][]string, opts ...cc.Opt) ([]*cc.TranslationUnit } var out buffer.Bytes - if err := ccgo.New(build, &out); err != nil { + if err := ccgo.New(build, &out, ccgo.Packages(qualifiers)); err != nil { log.Fatal(err) } @@ -255,36 +296,125 @@ func macros(buf io.Writer, ast *cc.TranslationUnit) { fmt.Fprintf(buf, ")\n") } -func main() { - const repo = "sqlite.org/sqlite-amalgamation-3190300/" +func unconvert(pth string) { + wd, err := os.Getwd() + if err != nil { + log.Fatal(err) + } - log.SetFlags(log.Lshortfile | log.Lmicroseconds) - var err error - if unconvertBin, err = exec.LookPath("unconvert"); err != nil { - log.Fatal("Please install the unconvert tool (go get -u github.com/mdempsky/unconvert)") + defer func() { + if err := os.Chdir(wd); err != nil { + log.Fatal(err) + } + }() + + if err := os.Chdir(filepath.Dir(pth)); err != nil { + log.Fatal(err) } - flag.Parse() - pth := findRepo(repo) - if pth == "" { - log.Fatalf("repository not found: %v", repo) + if out, err := exec.Command(unconvertBin, "-apply").CombinedOutput(); err != nil { + log.Fatalf("unconvert: %s\n%s", err, out) + } +} + +func cp(dst, src, glob string) { + pat := filepath.Join(filepath.FromSlash(src), glob) + m, err := filepath.Glob(pat) + if err != nil { + log.Fatal(err) + } + + if len(m) == 0 { + log.Fatalf("cp(%q, %q, %q): no files for %q", dst, src, glob, pat) + } + + dst = filepath.FromSlash(dst) + for _, v := range m { + f, err := ioutil.ReadFile(v) + if err != nil { + log.Fatal(err) + } + + _, nm := filepath.Split(v) + if err := ioutil.WriteFile(filepath.Join(dst, nm), f, 0664); err != nil { + log.Fatal(err) + } + } +} + +func header(f string) []byte { + b, err := ioutil.ReadFile(f) + if err != nil { + log.Fatal(err) + } + + var s scanner.Scanner + s.Init(token.NewFileSet().AddFile(f, -1, len(b)), b, nil, scanner.ScanComments) + var buf buffer.Bytes + fmt.Fprintf(&buf, "/* %s */", filepath.Base(f)) + for { + _, tok, lit := s.Scan() + switch tok { + case token.COMMENT: + buf.WriteString(lit) + buf.WriteByte('\n') + default: + return buf.Bytes() + } + } +} + +func tidyComment(s string) string { + if strings.HasPrefix(s, "/*") { + s = s[len("/*") : len(s)-len("*/")] + } + a := strings.Split(strings.TrimSpace(s), "\n") + for i, v := range a { + if strings.HasPrefix(v, "** ") { + a[i] = a[i][len("** "):] + continue + } + + if v == "**" { + a[i] = "" + } + } + for i, v := range a { + a[i] = strings.TrimSpace(v) + } + return "// " + strings.Join(a, "\n// ") + "\n" +} + +func tidyComments(b []byte) string { + var s scanner.Scanner + s.Init(token.NewFileSet().AddFile("", -1, len(b)), b, nil, scanner.ScanComments) + var a []string + for { + _, tok, lit := s.Scan() + if tok == token.EOF { + return strings.Join(a, "\n") + } + + a = append(a, tidyComment(lit)) + } +} + +func sqlite() { + repo := findRepo(sqliteRepo) + if repo == "" { + log.Fatalf("repository not found: %v", sqliteRepo) return } + pth := filepath.Join(repo, "sqlite-amalgamation-"+version) + sqlite3 := filepath.Join(pth, "sqlite3.c") asta, src := build( - ` - #define HAVE_MALLOC_H 1 - #define HAVE_MALLOC_USABLE_SIZE 1 - #define HAVE_USLEEP 1 - #define SQLITE_DEBUG 1 - #define SQLITE_ENABLE_API_ARMOR 1 - #define SQLITE_USE_URI 1 - #define SQLITE_WITHOUT_MSIZE 1 - `, + defines, [][]string{ {"main.c"}, - {filepath.Join(pth, "sqlite3.c")}, + {sqlite3}, }, + nil, cc.EnableAnonymousStructFields(), cc.IncludePaths([]string{pth}), ) @@ -295,20 +425,130 @@ func main() { log.Fatal(err) } - fmt.Fprintf(&b, prologue, lic) + fmt.Fprintf(&b, prologueSqlite, lic, tidyComments(header(sqlite3))) macros(&b, asta[0]) b.Write(src) b2, err := format.Source(b.Bytes()) if err != nil { b2 = b.Bytes() } - if err := os.MkdirAll("internal/bin", 0775); err != nil { + if err := os.MkdirAll(filepath.Join("internal", "bin"), 0775); err != nil { log.Fatal(err) } - dst := fmt.Sprintf("internal/bin/bin_%s_%s.go", runtime.GOOS, runtime.GOARCH) + dst := fmt.Sprintf(filepath.Join("internal", "bin", "bin_%s_%s.go"), runtime.GOOS, runtime.GOARCH) if err := ioutil.WriteFile(dst, b2, 0664); err != nil { log.Fatal(err) } + unconvert(dst) } + +func mpTest() { + repo := findRepo(sqliteRepo) + if repo == "" { + log.Fatalf("repository not found: %v", sqliteRepo) + return + } + + sqlitePth := filepath.Join(repo, "sqlite-amalgamation-"+version) + pth := filepath.Join(repo, "sqlite-src-"+version, "mptest") + tag := "mptest" + test := filepath.Join(pth, tag+".c") + _, src := build( + defines, + [][]string{ + {filepath.Join(sqlitePth, "sqlite3.c")}, + {test}, + }, + []string{"bin"}, + cc.EnableAnonymousStructFields(), + cc.IncludePaths([]string{sqlitePth}), + ) + + var b bytes.Buffer + fmt.Fprintf(&b, prologueTest, tidyComments(header(test))) + b.Write(src) + b2, err := format.Source(b.Bytes()) + if err != nil { + b2 = b.Bytes() + } + if err := os.MkdirAll(filepath.Join("internal", tag), 0775); err != nil { + log.Fatal(err) + } + + if err := os.MkdirAll(filepath.Join("testdata", tag), 0775); err != nil { + log.Fatal(err) + } + + dst := fmt.Sprintf(filepath.Join("internal", tag, tag+"_%s_%s.go"), runtime.GOOS, runtime.GOARCH) + if err := ioutil.WriteFile(dst, b2, 0664); err != nil { + log.Fatal(err) + } + + unconvert(dst) + cp(filepath.Join("testdata", tag), pth, "*.test") + cp(filepath.Join("testdata", tag), pth, "*.subtest") +} + +func threadTest(n int) { + repo := findRepo(sqliteRepo) + if repo == "" { + log.Fatalf("repository not found: %v", sqliteRepo) + return + } + + sqlitePth := filepath.Join(repo, "sqlite-amalgamation-"+version) + pth := filepath.Join(repo, "sqlite-src-"+version, "test") + tag := fmt.Sprintf("threadtest%v", n) + test := filepath.Join(pth, tag+".c") + _, src := build( + defines, + [][]string{ + {filepath.Join(sqlitePth, "sqlite3.c")}, + {test}, + }, + []string{"bin"}, + cc.EnableAnonymousStructFields(), + cc.IncludePaths([]string{".", sqlitePth, filepath.Join(repo, "sqlite-src-"+version, "src")}), + ) + + var b bytes.Buffer + fmt.Fprintf(&b, prologueTest, tidyComments(header(test))) + b.Write(src) + b2, err := format.Source(b.Bytes()) + if err != nil { + b2 = b.Bytes() + } + if err := os.MkdirAll(filepath.Join("internal", tag), 0775); err != nil { + log.Fatal(err) + } + + if err := os.MkdirAll(filepath.Join("testdata", tag), 0775); err != nil { + log.Fatal(err) + } + + dst := fmt.Sprintf(filepath.Join("internal", tag, tag+"_%s_%s.go"), runtime.GOOS, runtime.GOARCH) + if err := ioutil.WriteFile(dst, b2, 0664); err != nil { + log.Fatal(err) + } + + unconvert(dst) +} + +func main() { + log.SetFlags(log.Lshortfile | log.Lmicroseconds) + var err error + if unconvertBin, err = exec.LookPath("unconvert"); err != nil { + log.Fatal("Please install the unconvert tool (go get -u github.com/mdempsky/unconvert)") + } + + flag.Parse() + + sqlite() + mpTest() + threadTest(1) + threadTest(2) + // threadTest(3) depends on unexported function. + threadTest(4) +} |