mirror of
https://github.com/glebarez/go-sqlite.git
synced 2025-10-08 01:01:02 +08:00
Release the {cgo,VM}-free Linux/Intel version.
modified: Makefile new file: all_linux_test.go renamed: all_test.go -> all_test_windows.go new file: doc.go new file: generate_linux.go new file: generate_windows.go modified: generator.go new file: generator_windows.go modified: internal/bin/bin_linux_386.go modified: internal/bin/bin_linux_amd64.go modified: main.c modified: sqlite.go modified: sqlite_go18.go new file: sqlite_windows.go
This commit is contained in:
4
Makefile
4
Makefile
@@ -29,13 +29,13 @@ cpu: clean
|
|||||||
go tool pprof -lines *.test cpu.out
|
go tool pprof -lines *.test cpu.out
|
||||||
|
|
||||||
edit:
|
edit:
|
||||||
@ 1>/dev/null 2>/dev/null gvim -p Makefile main.c all_test.go sqlite.go
|
@ 1>/dev/null 2>/dev/null gvim -p Makefile main.c *.go
|
||||||
|
|
||||||
editor:
|
editor:
|
||||||
gofmt -l -s -w *.go
|
gofmt -l -s -w *.go
|
||||||
indent -linux *.c
|
indent -linux *.c
|
||||||
|
go test -i
|
||||||
go test 2>&1 | tee log
|
go test 2>&1 | tee log
|
||||||
go build
|
|
||||||
|
|
||||||
internalError:
|
internalError:
|
||||||
egrep -ho '"internal error.*"' *.go | sort | cat -n
|
egrep -ho '"internal error.*"' *.go | sort | cat -n
|
||||||
|
320
all_linux_test.go
Normal file
320
all_linux_test.go
Normal file
@@ -0,0 +1,320 @@
|
|||||||
|
// Copyright 2017 The Sqlite Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package sqlite
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"database/sql"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func caller(s string, va ...interface{}) {
|
||||||
|
if s == "" {
|
||||||
|
s = strings.Repeat("%v ", len(va))
|
||||||
|
}
|
||||||
|
_, fn, fl, _ := runtime.Caller(2)
|
||||||
|
fmt.Fprintf(os.Stderr, "# caller: %s:%d: ", path.Base(fn), fl)
|
||||||
|
fmt.Fprintf(os.Stderr, s, va...)
|
||||||
|
fmt.Fprintln(os.Stderr)
|
||||||
|
_, fn, fl, _ = runtime.Caller(1)
|
||||||
|
fmt.Fprintf(os.Stderr, "# \tcallee: %s:%d: ", path.Base(fn), fl)
|
||||||
|
fmt.Fprintln(os.Stderr)
|
||||||
|
os.Stderr.Sync()
|
||||||
|
}
|
||||||
|
|
||||||
|
func dbg(s string, va ...interface{}) {
|
||||||
|
if s == "" {
|
||||||
|
s = strings.Repeat("%v ", len(va))
|
||||||
|
}
|
||||||
|
_, fn, fl, _ := runtime.Caller(1)
|
||||||
|
fmt.Fprintf(os.Stderr, "# dbg %s:%d: ", path.Base(fn), fl)
|
||||||
|
fmt.Fprintf(os.Stderr, s, va...)
|
||||||
|
fmt.Fprintln(os.Stderr)
|
||||||
|
os.Stderr.Sync()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TODO(...interface{}) string { //TODOOK
|
||||||
|
_, fn, fl, _ := runtime.Caller(1)
|
||||||
|
return fmt.Sprintf("# TODO: %s:%d:\n", path.Base(fn), fl) //TODOOK
|
||||||
|
}
|
||||||
|
|
||||||
|
func use(...interface{}) {}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
use(caller, dbg, TODO) //TODOOK
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Add "-tags virtual.profile" to the command.
|
||||||
|
profileAll = flag.Bool("profile", false, "")
|
||||||
|
profileFunctions = flag.Bool("profile_functions", false, "")
|
||||||
|
profileInstructions = flag.Bool("profile_instructions", false, "")
|
||||||
|
profileLines = flag.Bool("profile_lines", false, "")
|
||||||
|
profileRate = flag.Int("profile_rate", 1000, "")
|
||||||
|
recsPerSec = flag.Bool("recs_per_sec_as_mbps", false, "Show records per second as MB/s.")
|
||||||
|
)
|
||||||
|
|
||||||
|
func tempDB(t testing.TB) (string, *sql.DB) {
|
||||||
|
dir, err := ioutil.TempDir("", "sqlite-test-")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
db, err := sql.Open(driverName, filepath.Join(dir, "tmp.db"))
|
||||||
|
if err != nil {
|
||||||
|
os.RemoveAll(dir)
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return dir, db
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestScalar(t *testing.T) {
|
||||||
|
dir, db := tempDB(t)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
db.Close()
|
||||||
|
os.RemoveAll(dir)
|
||||||
|
}()
|
||||||
|
|
||||||
|
t1 := time.Date(2017, 4, 20, 1, 2, 3, 56789, time.UTC)
|
||||||
|
t2 := time.Date(2018, 5, 21, 2, 3, 4, 98765, time.UTC)
|
||||||
|
r, err := db.Exec(`
|
||||||
|
create table t(i int, f double, b bool, s text, t time);
|
||||||
|
insert into t values(12, 3.14, ?, "foo", ?), (34, 2.78, ?, "bar", ?);
|
||||||
|
`,
|
||||||
|
true, t1,
|
||||||
|
false, t2,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
n, err := r.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if g, e := n, int64(2); g != e {
|
||||||
|
t.Fatal(g, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := db.Query("select * from t")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type rec struct {
|
||||||
|
i int
|
||||||
|
f float64
|
||||||
|
b bool
|
||||||
|
s string
|
||||||
|
t string
|
||||||
|
}
|
||||||
|
var a []rec
|
||||||
|
for rows.Next() {
|
||||||
|
var r rec
|
||||||
|
if err := rows.Scan(&r.i, &r.f, &r.b, &r.s, &r.t); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
a = append(a, r)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if g, e := len(a), 2; g != e {
|
||||||
|
t.Fatal(g, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
if g, e := a[0], (rec{12, 3.14, true, "foo", t1.String()}); g != e {
|
||||||
|
t.Fatal(g, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
if g, e := a[1], (rec{34, 2.78, false, "bar", t2.String()}); g != e {
|
||||||
|
t.Fatal(g, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBlob(t *testing.T) {
|
||||||
|
dir, db := tempDB(t)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
db.Close()
|
||||||
|
os.RemoveAll(dir)
|
||||||
|
}()
|
||||||
|
|
||||||
|
b1 := []byte(time.Now().String())
|
||||||
|
b2 := []byte("\x00foo\x00bar\x00")
|
||||||
|
if _, err := db.Exec(`
|
||||||
|
create table t(b blob);
|
||||||
|
insert into t values(?), (?);
|
||||||
|
`, b1, b2,
|
||||||
|
); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := db.Query("select * from t")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type rec struct {
|
||||||
|
b []byte
|
||||||
|
}
|
||||||
|
var a []rec
|
||||||
|
for rows.Next() {
|
||||||
|
var r rec
|
||||||
|
if err := rows.Scan(&r.b); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
a = append(a, r)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if g, e := len(a), 2; g != e {
|
||||||
|
t.Fatal(g, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
if g, e := a[0].b, b1; !bytes.Equal(g, e) {
|
||||||
|
t.Fatal(g, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
if g, e := a[1].b, b2; !bytes.Equal(g, e) {
|
||||||
|
t.Fatal(g, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkInsertMemory(b *testing.B) {
|
||||||
|
db, err := sql.Open(driverName, "file::memory:")
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
db.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
if _, err := db.Exec(`
|
||||||
|
create table t(i int);
|
||||||
|
begin;
|
||||||
|
`); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := db.Prepare("insert into t values(?)")
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
if _, err := s.Exec(int64(i)); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.StopTimer()
|
||||||
|
if *recsPerSec {
|
||||||
|
b.SetBytes(1e6)
|
||||||
|
}
|
||||||
|
if _, err := db.Exec(`commit;`); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkNextMemory(b *testing.B) {
|
||||||
|
db, err := sql.Open(driverName, "file::memory:")
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
db.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
if _, err := db.Exec(`
|
||||||
|
create table t(i int);
|
||||||
|
begin;
|
||||||
|
`); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := db.Prepare("insert into t values(?)")
|
||||||
|
if err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
if _, err := s.Exec(int64(i)); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err := db.Exec("commit"); err != nil {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err := db.Query("select * from t")
|
||||||
|
if err != nil {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
if !r.Next() {
|
||||||
|
b.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.StopTimer()
|
||||||
|
if *recsPerSec {
|
||||||
|
b.SetBytes(1e6)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/cznic/sqlite/issues/11
|
||||||
|
func TestIssue11(t *testing.T) {
|
||||||
|
const N = 6570
|
||||||
|
dir, db := tempDB(t)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
db.Close()
|
||||||
|
os.RemoveAll(dir)
|
||||||
|
}()
|
||||||
|
|
||||||
|
if _, err := db.Exec(`
|
||||||
|
CREATE TABLE t1 (t INT);
|
||||||
|
BEGIN;
|
||||||
|
`,
|
||||||
|
); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := 0; i < N; i++ {
|
||||||
|
if _, err := db.Exec("INSERT INTO t1 (t) VALUES (?)", i); err != nil {
|
||||||
|
t.Fatalf("#%v: %v", i, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if _, err := db.Exec("COMMIT;"); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
51
doc.go
Normal file
51
doc.go
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
// Copyright 2017 The Sqlite Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package sqlite is an in-process implementation of a self-contained,
|
||||||
|
// serverless, zero-configuration, transactional SQL database engine. (Work In Progress)
|
||||||
|
//
|
||||||
|
// Changelog
|
||||||
|
//
|
||||||
|
// 2017-06-05 Linux/Intel no more uses the VM (cznic/virtual).
|
||||||
|
//
|
||||||
|
// Connecting to a database
|
||||||
|
//
|
||||||
|
// To access a Sqlite database do something like
|
||||||
|
//
|
||||||
|
// import (
|
||||||
|
// "database/sql"
|
||||||
|
//
|
||||||
|
// _ "github.com/cznic/sqlite"
|
||||||
|
// )
|
||||||
|
//
|
||||||
|
// ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// db, err := sql.Open("sqlite", dsnURI)
|
||||||
|
//
|
||||||
|
// ...
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Do not use in production
|
||||||
|
//
|
||||||
|
// This is an experimental, pre-alpha, technology preview package. Performance
|
||||||
|
// is not (yet) a priority. When this virtual machine approach, hopefully,
|
||||||
|
// reaches a reasonable level of completeness and correctness, the plan is to
|
||||||
|
// eventually mechanically translate the IR form, produced by
|
||||||
|
// http://github.com/cznic/ccir, to Go. Unreadable Go, presumably.
|
||||||
|
//
|
||||||
|
// Even though the translation to Go is now done for Linux/Intel, the package
|
||||||
|
// status is still as described above, it's just closer to the alpha release in
|
||||||
|
// this respect. The alpha release is due when the C runtime support of SQLite
|
||||||
|
// in cznic/crt will be complete.
|
||||||
|
//
|
||||||
|
// Supported platforms and architectures
|
||||||
|
//
|
||||||
|
// See http://github.com/cznic/ccir. To add a newly supported os/arch
|
||||||
|
// combination to this package try running 'go generate'.
|
||||||
|
//
|
||||||
|
// Sqlite documentation
|
||||||
|
//
|
||||||
|
// See https://sqlite.org/docs.html
|
||||||
|
package sqlite
|
7
generate_linux.go
Normal file
7
generate_linux.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2017 The Sqlite Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:generate go run generator.go
|
||||||
|
|
||||||
|
package sqlite
|
7
generate_windows.go
Normal file
7
generate_windows.go
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2017 The Sqlite Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:generate go run generator_windows.go
|
||||||
|
|
||||||
|
package sqlite
|
214
generator.go
214
generator.go
@@ -8,13 +8,10 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"compress/gzip"
|
|
||||||
"encoding/gob"
|
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/format"
|
"go/format"
|
||||||
"go/scanner"
|
"go/scanner"
|
||||||
"go/token"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
@@ -26,11 +23,10 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/cznic/cc"
|
"github.com/cznic/cc"
|
||||||
|
"github.com/cznic/ccgo"
|
||||||
"github.com/cznic/ccir"
|
"github.com/cznic/ccir"
|
||||||
"github.com/cznic/internal/buffer"
|
"github.com/cznic/internal/buffer"
|
||||||
"github.com/cznic/ir"
|
|
||||||
"github.com/cznic/strutil"
|
"github.com/cznic/strutil"
|
||||||
"github.com/cznic/virtual"
|
|
||||||
"github.com/cznic/xc"
|
"github.com/cznic/xc"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -46,6 +42,55 @@ var (
|
|||||||
yydebug = flag.Int("yydebug", 0, "")
|
yydebug = flag.Int("yydebug", 0, "")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
prologue = `/*
|
||||||
|
|
||||||
|
%s
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Code generated by ccgo DO NOT EDIT.
|
||||||
|
|
||||||
|
package bin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"runtime"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/cznic/crt"
|
||||||
|
"github.com/edsrzf/mmap-go"
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
const minAlloc = 2<<5
|
||||||
|
|
||||||
|
var (
|
||||||
|
inf = math.Inf(1)
|
||||||
|
)
|
||||||
|
|
||||||
|
func ftrace(s string, args ...interface{}) {
|
||||||
|
_, fn, fl, _ := runtime.Caller(1)
|
||||||
|
fmt.Fprintf(os.Stderr, "# %%s:%%d: %%v\n", path.Base(fn), fl, fmt.Sprintf(s, args...))
|
||||||
|
os.Stderr.Sync()
|
||||||
|
}
|
||||||
|
|
||||||
|
func Init(heapSize, heapReserve int) int {
|
||||||
|
heap, err := mmap.MapRegion(nil, heapSize+heapReserve, mmap.RDWR, mmap.ANON, 0)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tls := crt.NewTLS()
|
||||||
|
crt.RegisterHeap(unsafe.Pointer(&heap[0]), int64(heapSize+heapReserve))
|
||||||
|
crt.X__register_stdfiles(tls, Xstdin, Xstdout, Xstderr)
|
||||||
|
return int(Xinit(tls, int32(heapSize)))
|
||||||
|
}
|
||||||
|
`
|
||||||
|
)
|
||||||
|
|
||||||
func findRepo(s string) string {
|
func findRepo(s string) string {
|
||||||
s = filepath.FromSlash(s)
|
s = filepath.FromSlash(s)
|
||||||
for _, v := range strings.Split(strutil.Gopath(), string(os.PathListSeparator)) {
|
for _, v := range strings.Split(strutil.Gopath(), string(os.PathListSeparator)) {
|
||||||
@@ -94,32 +139,13 @@ func errStr(err error) string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func build(predef string, tus [][]string, opts ...cc.Opt) ([]*cc.TranslationUnit, *virtual.Binary) {
|
func build(predef string, tus [][]string, opts ...cc.Opt) ([]*cc.TranslationUnit, []byte) {
|
||||||
var b buffer.Bytes
|
|
||||||
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(&b, "# %d %q\n", p.Line, p.Filename)
|
|
||||||
}
|
|
||||||
lpos = p
|
|
||||||
}
|
|
||||||
for _, v := range toks {
|
|
||||||
b.WriteString(cc.TokSrc(v))
|
|
||||||
}
|
|
||||||
b.WriteByte('\n')
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
ndbg := ""
|
ndbg := ""
|
||||||
if *ndebug {
|
if *ndebug {
|
||||||
ndbg = "#define NDEBUG 1"
|
ndbg = "#define NDEBUG 1"
|
||||||
}
|
}
|
||||||
var build [][]ir.Object
|
var build []*cc.TranslationUnit
|
||||||
tus = append(tus, []string{ccir.CRT0Path})
|
tus = append(tus, []string{ccir.CRT0Path})
|
||||||
var asta []*cc.TranslationUnit
|
|
||||||
for _, src := range tus {
|
for _, src := range tus {
|
||||||
model, err := ccir.NewModel()
|
model, err := ccir.NewModel()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -129,6 +155,7 @@ func build(predef string, tus [][]string, opts ...cc.Opt) ([]*cc.TranslationUnit
|
|||||||
ast, err := cc.Parse(
|
ast, err := cc.Parse(
|
||||||
fmt.Sprintf(`
|
fmt.Sprintf(`
|
||||||
%s
|
%s
|
||||||
|
#define _CCGO 1
|
||||||
#define __arch__ %s
|
#define __arch__ %s
|
||||||
#define __os__ %s
|
#define __os__ %s
|
||||||
#include <builtin.h>
|
#include <builtin.h>
|
||||||
@@ -138,79 +165,31 @@ func build(predef string, tus [][]string, opts ...cc.Opt) ([]*cc.TranslationUnit
|
|||||||
model,
|
model,
|
||||||
append([]cc.Opt{
|
append([]cc.Opt{
|
||||||
cc.AllowCompatibleTypedefRedefinitions(),
|
cc.AllowCompatibleTypedefRedefinitions(),
|
||||||
|
cc.EnableEmptyStructs(),
|
||||||
cc.EnableImplicitFuncDef(),
|
cc.EnableImplicitFuncDef(),
|
||||||
cc.EnableNonConstStaticInitExpressions(),
|
cc.EnableNonConstStaticInitExpressions(),
|
||||||
cc.EnableWideBitFieldTypes(),
|
|
||||||
cc.ErrLimit(*errLimit),
|
cc.ErrLimit(*errLimit),
|
||||||
cc.SysIncludePaths([]string{ccir.LibcIncludePath}),
|
cc.SysIncludePaths([]string{ccir.LibcIncludePath}),
|
||||||
}, opts...)...,
|
}, opts...)...,
|
||||||
)
|
)
|
||||||
if s := b.Bytes(); len(s) != 0 {
|
|
||||||
log.Printf("\n%s", s)
|
|
||||||
b.Close()
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(errStr(err))
|
log.Fatal(errStr(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
asta = append(asta, ast)
|
build = append(build, ast)
|
||||||
objs, err := ccir.New(ast)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if *oLog {
|
|
||||||
for i, v := range objs {
|
|
||||||
switch x := v.(type) {
|
|
||||||
case *ir.DataDefinition:
|
|
||||||
fmt.Fprintf(&b, "# [%v]: %T %v %v\n", i, x, x.ObjectBase, x.Value)
|
|
||||||
case *ir.FunctionDefinition:
|
|
||||||
fmt.Fprintf(&b, "# [%v]: %T %v %v\n", i, x, x.ObjectBase, x.Arguments)
|
|
||||||
for i, v := range x.Body {
|
|
||||||
fmt.Fprintf(&b, "%#05x\t%v\n", i, v)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
log.Fatalf("[%v]: %T %v: %v", i, x, x, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i, v := range objs {
|
|
||||||
if err := v.Verify(); err != nil {
|
|
||||||
switch x := v.(type) {
|
|
||||||
case *ir.FunctionDefinition:
|
|
||||||
fmt.Fprintf(&b, "# [%v, err]: %T %v %v\n", i, x, x.ObjectBase, x.Arguments)
|
|
||||||
for i, v := range x.Body {
|
|
||||||
fmt.Fprintf(&b, "%#05x\t%v\n", i, v)
|
|
||||||
}
|
|
||||||
log.Fatalf("# [%v]: Verify (A): %v\n%s", i, err, b.Bytes())
|
|
||||||
default:
|
|
||||||
log.Fatalf("[%v]: %T %v: %v", i, x, x, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
build = append(build, objs)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
linked, err := ir.LinkMain(build...)
|
var out buffer.Bytes
|
||||||
if err != nil {
|
if err := ccgo.New(build, &out); err != nil {
|
||||||
log.Fatalf("ir.LinkMain: %s\n%s", err, b.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range linked {
|
|
||||||
if err := v.Verify(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bin, err := virtual.LoadMain(linked)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return asta, bin
|
return build, out.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
func macros(buf io.Writer, ast *cc.TranslationUnit) {
|
func macros(buf io.Writer, ast *cc.TranslationUnit) {
|
||||||
|
fmt.Fprintf(buf, `const (
|
||||||
|
`)
|
||||||
var a []string
|
var a []string
|
||||||
for k, v := range ast.Macros {
|
for k, v := range ast.Macros {
|
||||||
if v.Value != nil && v.Type.Kind() != cc.Bool {
|
if v.Value != nil && v.Type.Kind() != cc.Bool {
|
||||||
@@ -269,6 +248,7 @@ func macros(buf io.Writer, ast *cc.TranslationUnit) {
|
|||||||
dd := ast.Declarations.Identifiers[dict.SID(v)].Node.(*cc.DirectDeclarator)
|
dd := ast.Declarations.Identifiers[dict.SID(v)].Node.(*cc.DirectDeclarator)
|
||||||
fmt.Fprintf(buf, "X%s = %v\n", v, dd.EnumVal)
|
fmt.Fprintf(buf, "X%s = %v\n", v, dd.EnumVal)
|
||||||
}
|
}
|
||||||
|
fmt.Fprintf(buf, ")\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -282,10 +262,10 @@ func main() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
asta, bin := build(
|
asta, src := build(
|
||||||
`
|
`
|
||||||
//#define SQLITE_DEBUG 1
|
#define SQLITE_DEBUG 1
|
||||||
//#define SQLITE_ENABLE_API_ARMOR 1
|
#define SQLITE_ENABLE_API_ARMOR 1
|
||||||
#define SQLITE_ENABLE_MEMSYS5 1
|
#define SQLITE_ENABLE_MEMSYS5 1
|
||||||
#define SQLITE_USE_URI 1
|
#define SQLITE_USE_URI 1
|
||||||
`,
|
`,
|
||||||
@@ -297,70 +277,24 @@ func main() {
|
|||||||
cc.IncludePaths([]string{pth}),
|
cc.IncludePaths([]string{pth}),
|
||||||
)
|
)
|
||||||
|
|
||||||
var b0 bytes.Buffer
|
var b bytes.Buffer
|
||||||
enc := gob.NewEncoder(&b0)
|
|
||||||
if err := enc.Encode(&bin); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var b1 bytes.Buffer
|
|
||||||
comp := gzip.NewWriter(&b1)
|
|
||||||
if _, err := comp.Write(b0.Bytes()); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := comp.Close(); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var b2 buffer.Bytes
|
|
||||||
lic, err := ioutil.ReadFile("SQLITE-LICENSE")
|
lic, err := ioutil.ReadFile("SQLITE-LICENSE")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
b2.WriteString(`// Code generated by running "go generate". DO NOT EDIT.
|
fmt.Fprintf(&b, prologue, lic)
|
||||||
|
macros(&b, asta[0])
|
||||||
/*
|
b.Write(src)
|
||||||
|
b2, err := format.Source(b.Bytes())
|
||||||
`)
|
|
||||||
b2.Write(lic)
|
|
||||||
b2.WriteString(`
|
|
||||||
*/
|
|
||||||
|
|
||||||
package bin
|
|
||||||
|
|
||||||
const (
|
|
||||||
`)
|
|
||||||
macros(&b2, asta[0])
|
|
||||||
b2.WriteString(`
|
|
||||||
Data = "`)
|
|
||||||
b := b1.Bytes()
|
|
||||||
for _, v := range b {
|
|
||||||
switch {
|
|
||||||
case v == '\\':
|
|
||||||
b2.WriteString(`\\`)
|
|
||||||
case v == '"':
|
|
||||||
b2.WriteString(`\"`)
|
|
||||||
case v < ' ', v >= 0x7f:
|
|
||||||
fmt.Fprintf(&b2, `\x%02x`, v)
|
|
||||||
default:
|
|
||||||
b2.WriteByte(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
b2.WriteString(`"
|
|
||||||
)
|
|
||||||
`)
|
|
||||||
b3, err := format.Source(b2.Bytes())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b3 = b
|
b2 = b.Bytes()
|
||||||
}
|
}
|
||||||
os.MkdirAll("internal/bin", 0775)
|
if err := os.MkdirAll("internal/bin", 0775); err != nil {
|
||||||
if err := ioutil.WriteFile(fmt.Sprintf("internal/bin/bin_%s_%s.go", runtime.GOOS, runtime.GOARCH), b3, 0664); err != nil {
|
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("code %#08x, text %#08x, data %#08x, bss %#08x, pc2func %v, pc2line %v, symbols %v, gz %v\n",
|
if err := ioutil.WriteFile(fmt.Sprintf("internal/bin/bin_%s_%s.go", runtime.GOOS, runtime.GOARCH), b2, 0664); err != nil {
|
||||||
len(bin.Code), len(bin.Text), len(bin.Data), bin.BSS, len(bin.Functions), len(bin.Lines), len(bin.Sym), b1.Len(),
|
log.Fatal(err)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
366
generator_windows.go
Normal file
366
generator_windows.go
Normal file
@@ -0,0 +1,366 @@
|
|||||||
|
// Copyright 2017 The Sqlite Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"compress/gzip"
|
||||||
|
"encoding/gob"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"go/format"
|
||||||
|
"go/scanner"
|
||||||
|
"go/token"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/cznic/cc"
|
||||||
|
"github.com/cznic/ccir"
|
||||||
|
"github.com/cznic/internal/buffer"
|
||||||
|
"github.com/cznic/ir"
|
||||||
|
"github.com/cznic/strutil"
|
||||||
|
"github.com/cznic/virtual"
|
||||||
|
"github.com/cznic/xc"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
cpp = flag.Bool("cpp", false, "")
|
||||||
|
dict = xc.Dict
|
||||||
|
errLimit = flag.Int("errlimit", 10, "")
|
||||||
|
filter = flag.String("re", "", "")
|
||||||
|
ndebug = flag.Bool("ndebug", false, "")
|
||||||
|
noexec = flag.Bool("noexec", false, "")
|
||||||
|
oLog = flag.Bool("log", false, "")
|
||||||
|
trace = flag.Bool("trc", false, "")
|
||||||
|
yydebug = flag.Int("yydebug", 0, "")
|
||||||
|
)
|
||||||
|
|
||||||
|
func findRepo(s string) string {
|
||||||
|
s = filepath.FromSlash(s)
|
||||||
|
for _, v := range strings.Split(strutil.Gopath(), string(os.PathListSeparator)) {
|
||||||
|
p := filepath.Join(v, "src", s)
|
||||||
|
fi, err := os.Lstat(p)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if fi.IsDir() {
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if p, err = filepath.Rel(wd, p); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func errStr(err error) string {
|
||||||
|
switch x := err.(type) {
|
||||||
|
case scanner.ErrorList:
|
||||||
|
if len(x) != 1 {
|
||||||
|
x.RemoveMultiples()
|
||||||
|
}
|
||||||
|
var b bytes.Buffer
|
||||||
|
for i, v := range x {
|
||||||
|
if i != 0 {
|
||||||
|
b.WriteByte('\n')
|
||||||
|
}
|
||||||
|
b.WriteString(v.Error())
|
||||||
|
if i == 9 {
|
||||||
|
fmt.Fprintf(&b, "\n\t... and %v more errors", len(x)-10)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
|
default:
|
||||||
|
return err.Error()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func build(predef string, tus [][]string, opts ...cc.Opt) ([]*cc.TranslationUnit, *virtual.Binary) {
|
||||||
|
var b buffer.Bytes
|
||||||
|
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(&b, "# %d %q\n", p.Line, p.Filename)
|
||||||
|
}
|
||||||
|
lpos = p
|
||||||
|
}
|
||||||
|
for _, v := range toks {
|
||||||
|
b.WriteString(cc.TokSrc(v))
|
||||||
|
}
|
||||||
|
b.WriteByte('\n')
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
ndbg := ""
|
||||||
|
if *ndebug {
|
||||||
|
ndbg = "#define NDEBUG 1"
|
||||||
|
}
|
||||||
|
var build [][]ir.Object
|
||||||
|
tus = append(tus, []string{ccir.CRT0Path})
|
||||||
|
var asta []*cc.TranslationUnit
|
||||||
|
for _, src := range tus {
|
||||||
|
model, err := ccir.NewModel()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ast, err := cc.Parse(
|
||||||
|
fmt.Sprintf(`
|
||||||
|
%s
|
||||||
|
#define __arch__ %s
|
||||||
|
#define __os__ %s
|
||||||
|
#include <builtin.h>
|
||||||
|
%s
|
||||||
|
`, ndbg, runtime.GOARCH, runtime.GOOS, predef),
|
||||||
|
src,
|
||||||
|
model,
|
||||||
|
append([]cc.Opt{
|
||||||
|
cc.AllowCompatibleTypedefRedefinitions(),
|
||||||
|
cc.EnableImplicitFuncDef(),
|
||||||
|
cc.EnableNonConstStaticInitExpressions(),
|
||||||
|
cc.EnableWideBitFieldTypes(),
|
||||||
|
cc.ErrLimit(*errLimit),
|
||||||
|
cc.SysIncludePaths([]string{ccir.LibcIncludePath}),
|
||||||
|
}, opts...)...,
|
||||||
|
)
|
||||||
|
if s := b.Bytes(); len(s) != 0 {
|
||||||
|
log.Printf("\n%s", s)
|
||||||
|
b.Close()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(errStr(err))
|
||||||
|
}
|
||||||
|
|
||||||
|
asta = append(asta, ast)
|
||||||
|
objs, err := ccir.New(ast)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if *oLog {
|
||||||
|
for i, v := range objs {
|
||||||
|
switch x := v.(type) {
|
||||||
|
case *ir.DataDefinition:
|
||||||
|
fmt.Fprintf(&b, "# [%v]: %T %v %v\n", i, x, x.ObjectBase, x.Value)
|
||||||
|
case *ir.FunctionDefinition:
|
||||||
|
fmt.Fprintf(&b, "# [%v]: %T %v %v\n", i, x, x.ObjectBase, x.Arguments)
|
||||||
|
for i, v := range x.Body {
|
||||||
|
fmt.Fprintf(&b, "%#05x\t%v\n", i, v)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
log.Fatalf("[%v]: %T %v: %v", i, x, x, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i, v := range objs {
|
||||||
|
if err := v.Verify(); err != nil {
|
||||||
|
switch x := v.(type) {
|
||||||
|
case *ir.FunctionDefinition:
|
||||||
|
fmt.Fprintf(&b, "# [%v, err]: %T %v %v\n", i, x, x.ObjectBase, x.Arguments)
|
||||||
|
for i, v := range x.Body {
|
||||||
|
fmt.Fprintf(&b, "%#05x\t%v\n", i, v)
|
||||||
|
}
|
||||||
|
log.Fatalf("# [%v]: Verify (A): %v\n%s", i, err, b.Bytes())
|
||||||
|
default:
|
||||||
|
log.Fatalf("[%v]: %T %v: %v", i, x, x, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
build = append(build, objs)
|
||||||
|
}
|
||||||
|
|
||||||
|
linked, err := ir.LinkMain(build...)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("ir.LinkMain: %s\n%s", err, b.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range linked {
|
||||||
|
if err := v.Verify(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bin, err := virtual.LoadMain(linked)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return asta, bin
|
||||||
|
}
|
||||||
|
|
||||||
|
func macros(buf io.Writer, ast *cc.TranslationUnit) {
|
||||||
|
var a []string
|
||||||
|
for k, v := range ast.Macros {
|
||||||
|
if v.Value != nil && v.Type.Kind() != cc.Bool {
|
||||||
|
switch fn := v.DefTok.Position().Filename; {
|
||||||
|
case
|
||||||
|
fn == "builtin.h",
|
||||||
|
fn == "<predefine>",
|
||||||
|
strings.HasPrefix(fn, "predefined_"):
|
||||||
|
// ignore
|
||||||
|
default:
|
||||||
|
a = append(a, string(dict.S(k)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Strings(a)
|
||||||
|
for _, v := range a {
|
||||||
|
m := ast.Macros[dict.SID(v)]
|
||||||
|
if m.Value == nil {
|
||||||
|
log.Fatal("TODO")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch t := m.Type; t.Kind() {
|
||||||
|
case
|
||||||
|
cc.Int, cc.UInt, cc.Long, cc.ULong, cc.LongLong, cc.ULongLong,
|
||||||
|
cc.Float, cc.LongDouble, cc.Bool:
|
||||||
|
fmt.Fprintf(buf, "X%s = %v\n", v, m.Value)
|
||||||
|
case cc.Ptr:
|
||||||
|
switch t := t.Element(); t.Kind() {
|
||||||
|
case cc.Char:
|
||||||
|
fmt.Fprintf(buf, "X%s = %q\n", v, dict.S(int(m.Value.(cc.StringLitID))))
|
||||||
|
default:
|
||||||
|
log.Fatalf("%v", t.Kind())
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
log.Fatalf("%v", t.Kind())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a = a[:0]
|
||||||
|
for _, v := range ast.Declarations.Identifiers {
|
||||||
|
switch x := v.Node.(type) {
|
||||||
|
case *cc.DirectDeclarator:
|
||||||
|
d := x.TopDeclarator()
|
||||||
|
id, _ := d.Identifier()
|
||||||
|
if x.EnumVal == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
a = append(a, string(dict.S(id)))
|
||||||
|
default:
|
||||||
|
log.Fatalf("%T", x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Strings(a)
|
||||||
|
for _, v := range a {
|
||||||
|
dd := ast.Declarations.Identifiers[dict.SID(v)].Node.(*cc.DirectDeclarator)
|
||||||
|
fmt.Fprintf(buf, "X%s = %v\n", v, dd.EnumVal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
const repo = "sqlite.org/sqlite-amalgamation-3180000/"
|
||||||
|
|
||||||
|
log.SetFlags(log.Lshortfile | log.Lmicroseconds)
|
||||||
|
flag.Parse()
|
||||||
|
pth := findRepo(repo)
|
||||||
|
if pth == "" {
|
||||||
|
log.Fatalf("repository not found: %v", repo)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
asta, bin := build(
|
||||||
|
`
|
||||||
|
//#define SQLITE_DEBUG 1
|
||||||
|
//#define SQLITE_ENABLE_API_ARMOR 1
|
||||||
|
#define SQLITE_ENABLE_MEMSYS5 1
|
||||||
|
#define SQLITE_USE_URI 1
|
||||||
|
`,
|
||||||
|
[][]string{
|
||||||
|
{"main.c"},
|
||||||
|
{filepath.Join(pth, "sqlite3.c")},
|
||||||
|
},
|
||||||
|
cc.EnableAnonymousStructFields(),
|
||||||
|
cc.IncludePaths([]string{pth}),
|
||||||
|
)
|
||||||
|
|
||||||
|
var b0 bytes.Buffer
|
||||||
|
enc := gob.NewEncoder(&b0)
|
||||||
|
if err := enc.Encode(&bin); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var b1 bytes.Buffer
|
||||||
|
comp := gzip.NewWriter(&b1)
|
||||||
|
if _, err := comp.Write(b0.Bytes()); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := comp.Close(); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var b2 buffer.Bytes
|
||||||
|
lic, err := ioutil.ReadFile("SQLITE-LICENSE")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b2.WriteString(`// Code generated by running "go generate". DO NOT EDIT.
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
`)
|
||||||
|
b2.Write(lic)
|
||||||
|
b2.WriteString(`
|
||||||
|
*/
|
||||||
|
|
||||||
|
package bin
|
||||||
|
|
||||||
|
const (
|
||||||
|
`)
|
||||||
|
macros(&b2, asta[0])
|
||||||
|
b2.WriteString(`
|
||||||
|
Data = "`)
|
||||||
|
b := b1.Bytes()
|
||||||
|
for _, v := range b {
|
||||||
|
switch {
|
||||||
|
case v == '\\':
|
||||||
|
b2.WriteString(`\\`)
|
||||||
|
case v == '"':
|
||||||
|
b2.WriteString(`\"`)
|
||||||
|
case v < ' ', v >= 0x7f:
|
||||||
|
fmt.Fprintf(&b2, `\x%02x`, v)
|
||||||
|
default:
|
||||||
|
b2.WriteByte(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b2.WriteString(`"
|
||||||
|
)
|
||||||
|
`)
|
||||||
|
b3, err := format.Source(b2.Bytes())
|
||||||
|
if err != nil {
|
||||||
|
b3 = b
|
||||||
|
}
|
||||||
|
os.MkdirAll("internal/bin", 0775)
|
||||||
|
if err := ioutil.WriteFile(fmt.Sprintf("internal/bin/bin_%s_%s.go", runtime.GOOS, runtime.GOARCH), b3, 0664); err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("code %#08x, text %#08x, data %#08x, bss %#08x, pc2func %v, pc2line %v, symbols %v, gz %v\n",
|
||||||
|
len(bin.Code), len(bin.Text), len(bin.Data), bin.BSS, len(bin.Functions), len(bin.Lines), len(bin.Sym), b1.Len(),
|
||||||
|
)
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
44
main.c
44
main.c
@@ -1,30 +1,9 @@
|
|||||||
// +build ignore
|
// Copyright 2017 The Sqlite Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
// SQLite Is Public Domain
|
// SQLite Is Public Domain
|
||||||
//
|
|
||||||
// All of the code and documentation in SQLite has been dedicated to the public
|
// +build ignore
|
||||||
// domain by the authors. All code authors, and representatives of the
|
|
||||||
// companies they work for, have signed affidavits dedicating their
|
|
||||||
// contributions to the public domain and originals of those signed affidavits
|
|
||||||
// are stored in a firesafe at the main offices of Hwaci. Anyone is free to
|
|
||||||
// copy, modify, publish, use, compile, sell, or distribute the original SQLite
|
|
||||||
// code, either in source code form or as a compiled binary, for any purpose,
|
|
||||||
// commercial or non-commercial, and by any means.
|
|
||||||
//
|
|
||||||
// The previous paragraph applies to the deliverable code and documentation in
|
|
||||||
// SQLite - those parts of the SQLite library that you actually bundle and ship
|
|
||||||
// with a larger application. Some scripts used as part of the build process
|
|
||||||
// (for example the "configure" scripts generated by autoconf) might fall under
|
|
||||||
// other open-source licenses. Nothing from these build scripts ever reaches
|
|
||||||
// the final deliverable SQLite library, however, and so the licenses
|
|
||||||
// associated with those scripts should not be a factor in assessing your
|
|
||||||
// rights to copy and use the SQLite library.
|
|
||||||
//
|
|
||||||
// All of the deliverable code in SQLite has been written from scratch. No code
|
|
||||||
// has been taken from other projects or from the open internet. Every line of
|
|
||||||
// code can be traced back to its original author, and all of those authors
|
|
||||||
// have public domain dedications on file. So the SQLite code base is clean and
|
|
||||||
// is uncontaminated with licensed code from other projects.
|
|
||||||
|
|
||||||
#define minAlloc (2<<5)
|
#define minAlloc (2<<5)
|
||||||
|
|
||||||
@@ -33,16 +12,11 @@
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (argc != 2) {
|
init(-1);
|
||||||
return 1;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
int heapSize = 0;
|
|
||||||
char *p = argv[1];
|
|
||||||
for (; *p; p++) {
|
|
||||||
heapSize = 10 * heapSize + *p - '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
int init(int heapSize)
|
||||||
|
{
|
||||||
void *heap = malloc(heapSize);
|
void *heap = malloc(heapSize);
|
||||||
if (heap == 0) {
|
if (heap == 0) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@@ -10,6 +10,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"errors"
|
"errors"
|
||||||
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ping implements driver.Pinger
|
// Ping implements driver.Pinger
|
||||||
@@ -17,7 +18,7 @@ func (c *conn) Ping(ctx context.Context) error {
|
|||||||
c.Lock()
|
c.Lock()
|
||||||
defer c.Unlock()
|
defer c.Unlock()
|
||||||
|
|
||||||
if c.ppdb == 0 {
|
if uintptr(unsafe.Pointer(c.ppdb)) == 0 {
|
||||||
return errors.New("db is closed")
|
return errors.New("db is closed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1406
sqlite_windows.go
Normal file
1406
sqlite_windows.go
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user