gitlab.com/CoiaPrant/sqlite3@v1.19.1/generator.go (about)

     1  // Copyright 2017 The Sqlite 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  //go:build generator
     6  // +build generator
     7  
     8  package main
     9  
    10  import (
    11  	"archive/zip"
    12  	"bufio"
    13  	"flag"
    14  	"fmt"
    15  	"io"
    16  	"net/http"
    17  	"os"
    18  	"os/exec"
    19  	"path/filepath"
    20  	"runtime"
    21  	"strings"
    22  
    23  	"modernc.org/ccgo/v3/lib"
    24  )
    25  
    26  //	gcc
    27  //	-g
    28  //	-O2
    29  //	-DSQLITE_OS_UNIX=1
    30  //	-I.
    31  //	-I/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src
    32  //	-I/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/rtree
    33  //	-I/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/icu
    34  //	-I/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/fts3
    35  //	-I/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/async
    36  //	-I/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/session
    37  //	-I/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/userauth
    38  //	-D_HAVE_SQLITE_CONFIG_H
    39  //	-DBUILD_sqlite
    40  //	-DNDEBUG
    41  //	-I/usr/include/tcl8.6
    42  //	-DSQLITE_THREADSAFE=1
    43  //	-DSQLITE_HAVE_ZLIB=1
    44  //	-DSQLITE_NO_SYNC=1
    45  //	-DSQLITE_TEMP_STORE=1
    46  //	-DSQLITE_TEST=1
    47  //	-DSQLITE_CRASH_TEST=1
    48  //	-DTCLSH_INIT_PROC=sqlite3TestInit
    49  //	-DSQLITE_SERVER=1
    50  //	-DSQLITE_PRIVATE=
    51  //	-DSQLITE_CORE
    52  //	-DBUILD_sqlite
    53  //	-DSQLITE_SERIES_CONSTRAINT_VERIFY=1
    54  //	-DSQLITE_DEFAULT_PAGE_SIZE=1024
    55  //	-DSQLITE_ENABLE_STMTVTAB
    56  //	-DSQLITE_ENABLE_DBPAGE_VTAB
    57  //	-DSQLITE_ENABLE_BYTECODE_VTAB
    58  //	-DSQLITE_ENABLE_DESERIALIZE
    59  //	-o testfixture
    60  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test1.c
    61  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test2.c
    62  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test3.c
    63  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test4.c
    64  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test5.c
    65  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test6.c
    66  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test7.c
    67  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test8.c
    68  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test9.c
    69  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_autoext.c
    70  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_async.c
    71  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_backup.c
    72  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_bestindex.c
    73  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_blob.c
    74  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_btree.c
    75  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_config.c
    76  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_delete.c
    77  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_demovfs.c
    78  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_devsym.c
    79  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_fs.c
    80  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_func.c
    81  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_hexio.c
    82  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_init.c
    83  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_intarray.c
    84  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_journal.c
    85  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_malloc.c
    86  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_md5.c
    87  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_multiplex.c
    88  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_mutex.c
    89  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_onefile.c
    90  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_osinst.c
    91  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_pcache.c
    92  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_quota.c
    93  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_rtree.c
    94  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_schema.c
    95  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_server.c
    96  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_superlock.c
    97  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_syscall.c
    98  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_tclsh.c
    99  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_tclvar.c
   100  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_thread.c
   101  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_vdbecov.c
   102  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_vfs.c
   103  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_windirent.c
   104  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_window.c
   105  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/test_wsd.c
   106  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/fts3/fts3_term.c
   107  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/fts3/fts3_test.c
   108  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/session/test_session.c
   109  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/rbu/test_rbu.c
   110  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/expert/sqlite3expert.c
   111  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/expert/test_expert.c
   112  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/amatch.c
   113  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/carray.c
   114  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/closure.c
   115  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/csv.c
   116  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/decimal.c
   117  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/eval.c
   118  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/explain.c
   119  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/fileio.c
   120  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/fuzzer.c
   121  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/fts5/fts5_tcl.c
   122  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/fts5/fts5_test_mi.c
   123  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/fts5/fts5_test_tok.c
   124  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/ieee754.c
   125  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/mmapwarm.c
   126  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/nextchar.c
   127  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/normalize.c
   128  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/percentile.c
   129  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/prefixes.c
   130  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/regexp.c
   131  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/remember.c
   132  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/series.c
   133  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/spellfix.c
   134  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/totype.c
   135  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/unionvtab.c
   136  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/wholenumber.c
   137  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/misc/zipfile.c
   138  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/ext/userauth/userauth.c
   139  //	/home/jnml/src/gitlab.com/CoiaPrant/sqlite3/testdata/SQLite-3c5e63c2/src/tclsqlite.c
   140  //	sqlite3.c
   141  //	-L/usr/lib/x86_64-linux-gnu
   142  //	-ltcl8.6
   143  //	-ldl
   144  //	-lz
   145  //	-lpthread
   146  
   147  const (
   148  	volatiles = "-volatile=sqlite3_io_error_pending,sqlite3_open_file_count,sqlite3_pager_readdb_count,sqlite3_pager_writedb_count,sqlite3_pager_writej_count,sqlite3_search_count,sqlite3_sort_count,saved_cnt"
   149  )
   150  
   151  var (
   152  	configProduction = []string{
   153  		"-DHAVE_USLEEP",
   154  		"-DLONGDOUBLE_TYPE=double",
   155  		"-DSQLITE_CORE",
   156  		"-DSQLITE_ENABLE_COLUMN_METADATA",
   157  		"-DSQLITE_ENABLE_FTS5",
   158  		"-DSQLITE_ENABLE_GEOPOLY",
   159  		"-DSQLITE_ENABLE_MATH_FUNCTIONS",
   160  		"-DSQLITE_ENABLE_MEMORY_MANAGEMENT",
   161  		"-DSQLITE_ENABLE_OFFSET_SQL_FUNC",
   162  		"-DSQLITE_ENABLE_PREUPDATE_HOOK",
   163  		"-DSQLITE_ENABLE_RBU",
   164  		"-DSQLITE_ENABLE_RTREE",
   165  		"-DSQLITE_ENABLE_SESSION",
   166  		"-DSQLITE_ENABLE_SNAPSHOT",
   167  		"-DSQLITE_ENABLE_STAT4",
   168  		"-DSQLITE_ENABLE_UNLOCK_NOTIFY", // Adds sqlite3_unlock_notify().
   169  		"-DSQLITE_LIKE_DOESNT_MATCH_BLOBS",
   170  		"-DSQLITE_MUTEX_APPDEF=1",
   171  		"-DSQLITE_MUTEX_NOOP",
   172  		"-DSQLITE_SOUNDEX",
   173  		"-DSQLITE_THREADSAFE=1",
   174  		//DONT "-DNDEBUG", // To enable GO_GENERATE=-DSQLITE_DEBUG
   175  		//DONT "-DSQLITE_DQS=0", // testfixture
   176  		//DONT "-DSQLITE_NO_SYNC=1",
   177  		//DONT "-DSQLITE_OMIT_DECLTYPE", // testfixture
   178  		//DONT "-DSQLITE_OMIT_DEPRECATED", // mptest
   179  		//DONT "-DSQLITE_OMIT_LOAD_EXTENSION", // mptest
   180  		//DONT "-DSQLITE_OMIT_SHARED_CACHE",
   181  		//DONT "-DSQLITE_USE_ALLOCA",
   182  		//TODO "-DHAVE_MALLOC_USABLE_SIZE"
   183  		//TODO "-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1", //TODO report bug
   184  		//TODO "-DSQLITE_ENABLE_FTS3",
   185  		//TODO "-DSQLITE_ENABLE_FTS3_PARENTHESIS",
   186  		//TODO "-DSQLITE_ENABLE_FTS3_TOKENIZER",
   187  		//TODO "-DSQLITE_ENABLE_FTS4",
   188  		//TODO "-DSQLITE_ENABLE_ICU",
   189  		//TODO "-DSQLITE_MAX_EXPR_DEPTH=0", // bug reported https://sqlite.org/forum/forumpost/87b9262f66, fixed in https://sqlite.org/src/info/5f58dd3a19605b6f
   190  		//TODO "-DSQLITE_MAX_MMAP_SIZE=8589934592", // testfixture, bug reported https://sqlite.org/forum/forumpost/34380589f7, fixed in https://sqlite.org/src/info/d8e47382160e98be
   191  		//TODO- "-DSQLITE_DEBUG",
   192  		//TODO- "-DSQLITE_ENABLE_API_ARMOR",
   193  		//TODO- "-DSQLITE_MEMDEBUG",
   194  	}
   195  
   196  	configTest = []string{
   197  		"-DHAVE_USLEEP",
   198  		"-DLONGDOUBLE_TYPE=double",
   199  		"-DSQLITE_CKSUMVFS_STATIC",
   200  		"-DSQLITE_CORE",                   // testfixture
   201  		"-DSQLITE_DEFAULT_MEMSTATUS=0",    // bug reported https://sqlite.org/forum/info/d8dfd4771689be35, fixed in https://sqlite.org/src/info/3c5e63c22ffbfeb6
   202  		"-DSQLITE_DEFAULT_PAGE_SIZE=1024", // testfixture, hardcoded. See file_pages in autovacuum.test.
   203  		"-DSQLITE_ENABLE_BYTECODE_VTAB",   // testfixture
   204  		"-DSQLITE_ENABLE_COLUMN_METADATA",
   205  		"-DSQLITE_ENABLE_DBPAGE_VTAB", // testfixture
   206  		"-DSQLITE_ENABLE_DBSTAT_VTAB",
   207  		"-DSQLITE_ENABLE_DESERIALIZE", // testfixture
   208  		"-DSQLITE_ENABLE_EXPLAIN_COMMENTS",
   209  		"-DSQLITE_ENABLE_FTS5",
   210  		"-DSQLITE_ENABLE_GEOPOLY",
   211  		"-DSQLITE_ENABLE_MATH_FUNCTIONS",
   212  		"-DSQLITE_ENABLE_MEMORY_MANAGEMENT",
   213  		"-DSQLITE_ENABLE_OFFSET_SQL_FUNC",
   214  		"-DSQLITE_ENABLE_PREUPDATE_HOOK",
   215  		"-DSQLITE_ENABLE_RBU",
   216  		"-DSQLITE_ENABLE_RTREE",
   217  		"-DSQLITE_ENABLE_SESSION",
   218  		"-DSQLITE_ENABLE_SNAPSHOT",
   219  		"-DSQLITE_ENABLE_STAT4",
   220  		"-DSQLITE_ENABLE_STMTVTAB",      // testfixture
   221  		"-DSQLITE_ENABLE_UNLOCK_NOTIFY", // Adds sqlite3_unlock_notify().
   222  		"-DSQLITE_LIKE_DOESNT_MATCH_BLOBS",
   223  		"-DSQLITE_MUTEX_APPDEF=1",
   224  		"-DSQLITE_MUTEX_NOOP",
   225  		"-DSQLITE_SOUNDEX",
   226  		"-DSQLITE_TEMP_STORE=1", // testfixture
   227  		"-DSQLITE_TEST",
   228  		"-DSQLITE_THREADSAFE=1",
   229  		//DONT "-DNDEBUG", // To enable GO_GENERATE=-DSQLITE_DEBUG
   230  		//DONT "-DSQLITE_DQS=0", // testfixture
   231  		//DONT "-DSQLITE_NO_SYNC=1",
   232  		//DONT "-DSQLITE_OMIT_DECLTYPE", // testfixture
   233  		//DONT "-DSQLITE_OMIT_DEPRECATED", // mptest
   234  		//DONT "-DSQLITE_OMIT_LOAD_EXTENSION", // mptest
   235  		//DONT "-DSQLITE_OMIT_SHARED_CACHE",
   236  		//DONT "-DSQLITE_USE_ALLOCA",
   237  		//TODO "-DHAVE_MALLOC_USABLE_SIZE"
   238  		//TODO "-DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1", //TODO report bug
   239  		//TODO "-DSQLITE_ENABLE_FTS3",
   240  		//TODO "-DSQLITE_ENABLE_FTS3_PARENTHESIS",
   241  		//TODO "-DSQLITE_ENABLE_FTS3_TOKENIZER",
   242  		//TODO "-DSQLITE_ENABLE_FTS4",
   243  		//TODO "-DSQLITE_ENABLE_ICU",
   244  		//TODO "-DSQLITE_MAX_EXPR_DEPTH=0", // bug reported https://sqlite.org/forum/forumpost/87b9262f66, fixed in https://sqlite.org/src/info/5f58dd3a19605b6f
   245  		//TODO "-DSQLITE_MAX_MMAP_SIZE=8589934592", // testfixture, bug reported https://sqlite.org/forum/forumpost/34380589f7, fixed in https://sqlite.org/src/info/d8e47382160e98be
   246  		//TODO- "-DSQLITE_DEBUG",
   247  		//TODO- "-DSQLITE_ENABLE_API_ARMOR",
   248  		//TODO- "-DSQLITE_MEMDEBUG",
   249  	}
   250  
   251  	downloads = []struct {
   252  		dir, url string
   253  		sz       int
   254  		dev      bool
   255  	}{
   256  		{sqliteDir, "https://www.sqlite.org/2022/sqlite-amalgamation-3390300.zip", 2457, false},
   257  		{sqliteSrcDir, "https://www.sqlite.org/2022/sqlite-src-3390300.zip", 12814, false},
   258  	}
   259  
   260  	sqliteDir    = filepath.FromSlash("testdata/sqlite-amalgamation-3390300")
   261  	sqliteSrcDir = filepath.FromSlash("testdata/sqlite-src-3390300")
   262  )
   263  
   264  func download() {
   265  	tmp, err := os.MkdirTemp("", "")
   266  	if err != nil {
   267  		fmt.Fprintf(os.Stderr, "%s\n", err)
   268  		return
   269  	}
   270  
   271  	defer os.RemoveAll(tmp)
   272  
   273  	for _, v := range downloads {
   274  		dir := filepath.FromSlash(v.dir)
   275  		root := filepath.Dir(v.dir)
   276  		fi, err := os.Stat(dir)
   277  		switch {
   278  		case err == nil:
   279  			if !fi.IsDir() {
   280  				fmt.Fprintf(os.Stderr, "expected %s to be a directory\n", dir)
   281  			}
   282  			continue
   283  		default:
   284  			if !os.IsNotExist(err) {
   285  				fmt.Fprintf(os.Stderr, "%s", err)
   286  				continue
   287  			}
   288  		}
   289  
   290  		if err := func() error {
   291  			fmt.Printf("Downloading %v MB from %s\n", float64(v.sz)/1000, v.url)
   292  			resp, err := http.Get(v.url)
   293  			if err != nil {
   294  				return err
   295  			}
   296  
   297  			defer resp.Body.Close()
   298  
   299  			base := filepath.Base(v.url)
   300  			name := filepath.Join(tmp, base)
   301  			f, err := os.Create(name)
   302  			if err != nil {
   303  				return err
   304  			}
   305  
   306  			defer os.Remove(name)
   307  
   308  			n, err := io.Copy(f, resp.Body)
   309  			if err != nil {
   310  				return err
   311  			}
   312  
   313  			if _, err := f.Seek(0, io.SeekStart); err != nil {
   314  				return err
   315  			}
   316  
   317  			switch {
   318  			case strings.HasSuffix(base, ".zip"):
   319  				r, err := zip.NewReader(f, n)
   320  				if err != nil {
   321  					return err
   322  				}
   323  
   324  				for _, f := range r.File {
   325  					fi := f.FileInfo()
   326  					if fi.IsDir() {
   327  						if err := os.MkdirAll(filepath.Join(root, f.Name), 0770); err != nil {
   328  							return err
   329  						}
   330  
   331  						continue
   332  					}
   333  
   334  					if err := func() error {
   335  						rc, err := f.Open()
   336  						if err != nil {
   337  							return err
   338  						}
   339  
   340  						defer rc.Close()
   341  
   342  						file, err := os.OpenFile(filepath.Join(root, f.Name), os.O_CREATE|os.O_WRONLY, fi.Mode())
   343  						if err != nil {
   344  							return err
   345  						}
   346  
   347  						w := bufio.NewWriter(file)
   348  						if _, err = io.Copy(w, rc); err != nil {
   349  							return err
   350  						}
   351  
   352  						if err := w.Flush(); err != nil {
   353  							return err
   354  						}
   355  
   356  						return file.Close()
   357  					}(); err != nil {
   358  						return err
   359  					}
   360  				}
   361  				return nil
   362  			}
   363  			panic("internal error") //TODOOK
   364  		}(); err != nil {
   365  			fmt.Fprintln(os.Stderr, err)
   366  		}
   367  	}
   368  }
   369  
   370  func fail(s string, args ...interface{}) {
   371  	fmt.Fprintf(os.Stderr, s, args...)
   372  	os.Exit(1)
   373  }
   374  
   375  var (
   376  	oFullPathComments = flag.Bool("full-path-comments", false, "")
   377  )
   378  
   379  func main() {
   380  	flag.Parse()
   381  	fmt.Printf("Running on %s/%s.\n", runtime.GOOS, runtime.GOARCH)
   382  	env := os.Getenv("GO_GENERATE")
   383  	goarch := runtime.GOARCH
   384  	goos := runtime.GOOS
   385  	if s := os.Getenv("TARGET_GOOS"); s != "" {
   386  		goos = s
   387  	}
   388  	if s := os.Getenv("TARGET_GOARCH"); s != "" {
   389  		goarch = s
   390  	}
   391  	var more []string
   392  	if env != "" {
   393  		more = strings.Split(env, ",")
   394  	}
   395  	ndebug := []string{"-DNDEBUG"}
   396  	for _, v := range more {
   397  		if v == "-DSQLITE_DEBUG" {
   398  			ndebug = nil
   399  		}
   400  	}
   401  	more = append(more, ndebug...)
   402  	download()
   403  	switch goos {
   404  	case "linux", "freebsd", "openbsd":
   405  		configProduction = append(configProduction, "-DSQLITE_OS_UNIX=1")
   406  	case "netbsd":
   407  		configProduction = append(configProduction, []string{
   408  			"-DSQLITE_OS_UNIX=1",
   409  			"-D__libc_cond_broadcast=pthread_cond_broadcast",
   410  			"-D__libc_cond_destroy=pthread_cond_destroy",
   411  			"-D__libc_cond_init=pthread_cond_init",
   412  			"-D__libc_cond_signal=pthread_cond_signal",
   413  			"-D__libc_cond_wait=pthread_cond_wait",
   414  			"-D__libc_mutex_destroy=pthread_mutex_destroy",
   415  			"-D__libc_mutex_init=pthread_mutex_init",
   416  			"-D__libc_mutex_lock=pthread_mutex_lock",
   417  			"-D__libc_mutex_trylock=pthread_mutex_trylock",
   418  			"-D__libc_mutex_unlock=pthread_mutex_unlock",
   419  			"-D__libc_mutexattr_destroy=pthread_mutexattr_destroy",
   420  			"-D__libc_mutexattr_init=pthread_mutexattr_init",
   421  			"-D__libc_mutexattr_settype=pthread_mutexattr_settype",
   422  			"-D__libc_thr_yield=sched_yield",
   423  		}...)
   424  	case "darwin":
   425  		configProduction = append(configProduction,
   426  			"-DSQLITE_OS_UNIX=1",
   427  			"-DSQLITE_WITHOUT_ZONEMALLOC",
   428  		)
   429  		configTest = append(configTest,
   430  			"-DSQLITE_OS_UNIX=1",
   431  			"-DSQLITE_WITHOUT_ZONEMALLOC",
   432  		)
   433  	case "windows":
   434  		configProduction = append(configProduction,
   435  			"-DSQLITE_OS_WIN=1",
   436  			"-D_MSC_VER=1900",
   437  		)
   438  		configTest = append(configTest,
   439  			"-DSQLITE_OS_WIN=1",
   440  			"-D_MSC_VER=1900",
   441  		)
   442  	default:
   443  		fail("unknows/unsupported os: %s\n", goos)
   444  	}
   445  	makeSqliteProduction(goos, goarch, more)
   446  	makeSqliteTest(goos, goarch, more)
   447  	makeMpTest(goos, goarch, more)
   448  	makeSpeedTest(goos, goarch, more)
   449  	makeTestfixture(goos, goarch, more)
   450  	ccgo.MustCopyDir(true, "testdata/tcl", sqliteSrcDir+"/test", nil)
   451  	ccgo.MustCopyDir(true, "testdata/tcl", "testdata/overlay", nil)
   452  }
   453  
   454  func configure(goos, goarch string) {
   455  	wd, err := os.Getwd()
   456  	if err != nil {
   457  		fail("%s", err)
   458  	}
   459  
   460  	defer os.Chdir(wd)
   461  
   462  	if err := os.Chdir(sqliteSrcDir); err != nil {
   463  		fail("%s", err)
   464  	}
   465  
   466  	cmd := newCmd("make", "distclean")
   467  	cmd.Run()
   468  	var args []string
   469  	switch goos {
   470  	case "linux", "freebsd", "netbsd", "openbsd":
   471  		// nop
   472  	case "darwin":
   473  		args = append(args, "--with-tcl=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework")
   474  	case "windows":
   475  		switch goarch {
   476  		case "amd64":
   477  			args = append(args, "--host=x86_64-w64-mingw32")
   478  		case "386":
   479  			args = append(args, "--host=i686-w64-mingw32")
   480  		default:
   481  			fail("unknown/unsupported os/arch: %s/%s\n", goos, goarch)
   482  		}
   483  	default:
   484  		fail("unknown/unsupported os/arch: %s/%s\n", goos, goarch)
   485  	}
   486  	cmd = newCmd("./configure", args...)
   487  	if err = cmd.Run(); err != nil {
   488  		fail("%s\n", err)
   489  	}
   490  
   491  	cmd = newCmd("make", "parse.h", "opcodes.h")
   492  	if err = cmd.Run(); err != nil {
   493  		fail("%s\n", err)
   494  	}
   495  }
   496  
   497  func newCmd(bin string, args ...string) *exec.Cmd {
   498  	fmt.Printf("==== newCmd %s\n", bin)
   499  	for _, v := range args {
   500  		fmt.Printf("\t%v\n", v)
   501  	}
   502  	r := exec.Command(bin, args...)
   503  	r.Stdout = os.Stdout
   504  	r.Stderr = os.Stderr
   505  	return r
   506  }
   507  
   508  func makeTestfixture(goos, goarch string, more []string) {
   509  	dir := filepath.FromSlash(fmt.Sprintf("internal/testfixture"))
   510  	files := []string{
   511  		"ext/expert/sqlite3expert.c",
   512  		"ext/expert/test_expert.c",
   513  		"ext/fts3/fts3_term.c",
   514  		"ext/fts3/fts3_test.c",
   515  		"ext/fts5/fts5_tcl.c",
   516  		"ext/fts5/fts5_test_mi.c",
   517  		"ext/fts5/fts5_test_tok.c",
   518  		"ext/misc/appendvfs.c",
   519  		"ext/misc/amatch.c",
   520  		"ext/misc/carray.c",
   521  		"ext/misc/cksumvfs.c",
   522  		"ext/misc/closure.c",
   523  		"ext/misc/csv.c",
   524  		"ext/misc/decimal.c",
   525  		"ext/misc/eval.c",
   526  		"ext/misc/explain.c",
   527  		"ext/misc/fileio.c",
   528  		"ext/misc/fuzzer.c",
   529  		"ext/misc/ieee754.c",
   530  		"ext/misc/mmapwarm.c",
   531  		"ext/misc/nextchar.c",
   532  		"ext/misc/normalize.c",
   533  		"ext/misc/percentile.c",
   534  		"ext/misc/prefixes.c",
   535  		"ext/misc/qpvtab.c",
   536  		"ext/misc/regexp.c",
   537  		"ext/misc/remember.c",
   538  		"ext/misc/series.c",
   539  		"ext/misc/spellfix.c",
   540  		"ext/misc/totype.c",
   541  		"ext/misc/unionvtab.c",
   542  		"ext/misc/wholenumber.c",
   543  		"ext/rbu/test_rbu.c",
   544  		"ext/rtree/test_rtreedoc.c",
   545  		"ext/session/test_session.c",
   546  		"ext/userauth/userauth.c",
   547  		"src/tclsqlite.c",
   548  		"src/test1.c",
   549  		"src/test2.c",
   550  		"src/test3.c",
   551  		"src/test4.c",
   552  		"src/test5.c",
   553  		"src/test6.c",
   554  		"src/test7.c",
   555  		"src/test8.c",
   556  		"src/test9.c",
   557  		"src/test_async.c",
   558  		"src/test_autoext.c",
   559  		"src/test_backup.c",
   560  		"src/test_bestindex.c",
   561  		"src/test_blob.c",
   562  		"src/test_btree.c",
   563  		"src/test_config.c",
   564  		"src/test_delete.c",
   565  		"src/test_demovfs.c",
   566  		"src/test_devsym.c",
   567  		"src/test_fs.c",
   568  		"src/test_func.c",
   569  		"src/test_hexio.c",
   570  		"src/test_init.c",
   571  		"src/test_intarray.c",
   572  		"src/test_journal.c",
   573  		"src/test_malloc.c",
   574  		"src/test_md5.c",
   575  		"src/test_multiplex.c",
   576  		"src/test_mutex.c",
   577  		"src/test_onefile.c",
   578  		"src/test_osinst.c",
   579  		"src/test_pcache.c",
   580  		"src/test_quota.c",
   581  		"src/test_rtree.c",
   582  		"src/test_schema.c",
   583  		"src/test_server.c",
   584  		"src/test_superlock.c",
   585  		"src/test_syscall.c",
   586  		"src/test_tclsh.c",
   587  		"src/test_tclvar.c",
   588  		"src/test_thread.c",
   589  		"src/test_vdbecov.c",
   590  		"src/test_vfs.c",
   591  		"src/test_windirent.c",
   592  		"src/test_window.c",
   593  		"src/test_wsd.c",
   594  	}
   595  	for i, v := range files {
   596  		files[i] = filepath.Join(sqliteSrcDir, filepath.FromSlash(v))
   597  	}
   598  	configure(goos, goarch)
   599  
   600  	var defines, includes []string
   601  	switch goos {
   602  	case "freebsd", "openbsd":
   603  		includes = []string{"-I/usr/local/include/tcl8.6"}
   604  	case "linux":
   605  		includes = []string{"-I/usr/include/tcl8.6"}
   606  	case "windows":
   607  		includes = []string{"-I/usr/include/tcl8.6"}
   608  	case "netbsd":
   609  		includes = []string{"-I/usr/pkg/include"}
   610  		defines = []string{
   611  			"-D__libc_cond_broadcast=pthread_cond_broadcast",
   612  			"-D__libc_cond_destroy=pthread_cond_destroy",
   613  			"-D__libc_cond_init=pthread_cond_init",
   614  			"-D__libc_cond_signal=pthread_cond_signal",
   615  			"-D__libc_cond_wait=pthread_cond_wait",
   616  			"-D__libc_mutex_destroy=pthread_mutex_destroy",
   617  			"-D__libc_mutex_init=pthread_mutex_init",
   618  			"-D__libc_mutex_lock=pthread_mutex_lock",
   619  			"-D__libc_mutex_trylock=pthread_mutex_trylock",
   620  			"-D__libc_mutex_unlock=pthread_mutex_unlock",
   621  			"-D__libc_mutexattr_destroy=pthread_mutexattr_destroy",
   622  			"-D__libc_mutexattr_init=pthread_mutexattr_init",
   623  			"-D__libc_mutexattr_settype=pthread_mutexattr_settype",
   624  			"-D__libc_thr_yield=sched_yield",
   625  		}
   626  	}
   627  
   628  	args := join(
   629  		[]string{
   630  			"ccgo",
   631  			"-DSQLITE_OMIT_LOAD_EXTENSION",
   632  			"-DSQLITE_SERIES_CONSTRAINT_VERIFY=1",
   633  			"-DSQLITE_SERVER=1",
   634  			"-DTCLSH_INIT_PROC=sqlite3TestInit",
   635  			"-D_HAVE_SQLITE_CONFIG_H",
   636  		},
   637  		defines,
   638  		includes,
   639  		[]string{
   640  			"-export-defines", "",
   641  			"-export-fields", "F",
   642  			"-ignore-unsupported-alignment",
   643  			"-trace-translation-units",
   644  			volatiles,
   645  			"-lgitlab.com/CoiaPrant/sqlite3/libtest",
   646  			"-lmodernc.org/tcl/lib",
   647  			"-lmodernc.org/z/lib",
   648  			"-o", filepath.Join(dir, fmt.Sprintf("testfixture_%s_%s.go", goos, goarch)),
   649  			fmt.Sprintf("-I%s", filepath.Join(sqliteSrcDir, filepath.FromSlash("ext/async"))),
   650  			fmt.Sprintf("-I%s", filepath.Join(sqliteSrcDir, filepath.FromSlash("ext/fts3"))),
   651  			fmt.Sprintf("-I%s", filepath.Join(sqliteSrcDir, filepath.FromSlash("ext/icu"))),
   652  			fmt.Sprintf("-I%s", filepath.Join(sqliteSrcDir, filepath.FromSlash("ext/rtree"))),
   653  			fmt.Sprintf("-I%s", filepath.Join(sqliteSrcDir, filepath.FromSlash("ext/session"))),
   654  			fmt.Sprintf("-I%s", filepath.Join(sqliteSrcDir, filepath.FromSlash("ext/userauth"))),
   655  			fmt.Sprintf("-I%s", filepath.Join(sqliteSrcDir, filepath.FromSlash("src"))),
   656  			fmt.Sprintf("-I%s", sqliteDir),
   657  			fmt.Sprintf("-I%s", sqliteSrcDir),
   658  		},
   659  		otherOpts(),
   660  		files,
   661  		more,
   662  		configTest,
   663  	)
   664  	task := ccgo.NewTask(args, nil, nil)
   665  	if err := task.Main(); err != nil {
   666  		fail("%s\n", err)
   667  	}
   668  }
   669  
   670  func otherOpts() (r []string) {
   671  	if *oFullPathComments {
   672  		r = append(r, "-full-path-comments")
   673  	}
   674  	return r
   675  }
   676  
   677  func makeSpeedTest(goos, goarch string, more []string) {
   678  	task := ccgo.NewTask(
   679  		join(
   680  			[]string{
   681  				"ccgo",
   682  				"-export-defines", "",
   683  				"-ignore-unsupported-alignment",
   684  				"-o", filepath.FromSlash(fmt.Sprintf("speedtest1/main_%s_%s.go", goos, goarch)),
   685  				"-trace-translation-units",
   686  				filepath.Join(sqliteSrcDir, "test", "speedtest1.c"),
   687  				fmt.Sprintf("-I%s", sqliteDir),
   688  				"-l", "gitlab.com/CoiaPrant/sqlite3/lib",
   689  			},
   690  			otherOpts(),
   691  			more,
   692  			configProduction,
   693  		),
   694  		nil,
   695  		nil,
   696  	)
   697  	if err := task.Main(); err != nil {
   698  		fail("%s\n", err)
   699  	}
   700  }
   701  
   702  func makeMpTest(goos, goarch string, more []string) {
   703  	task := ccgo.NewTask(
   704  		join(
   705  			[]string{
   706  				"ccgo",
   707  				"-export-defines", "",
   708  				"-ignore-unsupported-alignment",
   709  				"-o", filepath.FromSlash(fmt.Sprintf("internal/mptest/main_%s_%s.go", goos, goarch)),
   710  				"-trace-translation-units",
   711  				// filepath.Join(sqliteSrcDir, "mptest", "mptest.c"),
   712  				filepath.Join("testdata", "mptest.c"),
   713  				fmt.Sprintf("-I%s", sqliteDir),
   714  				"-l", "gitlab.com/CoiaPrant/sqlite3/lib",
   715  			},
   716  			otherOpts(),
   717  			more,
   718  			configProduction,
   719  		),
   720  		nil,
   721  		nil,
   722  	)
   723  	if err := task.Main(); err != nil {
   724  		fail("%s\n", err)
   725  	}
   726  }
   727  
   728  func makeSqliteProduction(goos, goarch string, more []string) {
   729  	task := ccgo.NewTask(
   730  		join(
   731  			[]string{
   732  				"ccgo",
   733  				"-DSQLITE_PRIVATE=",
   734  				"-export-defines", "",
   735  				"-export-enums", "",
   736  				"-export-externs", "X",
   737  				"-export-fields", "F",
   738  				"-export-typedefs", "",
   739  				"-ignore-unsupported-alignment",
   740  				"-pkgname", "sqlite3",
   741  				"-o", filepath.FromSlash(fmt.Sprintf("lib/sqlite_%s_%s.go", goos, goarch)),
   742  				"-trace-translation-units",
   743  				filepath.Join(sqliteDir, "sqlite3.c"),
   744  			},
   745  			otherOpts(),
   746  			more,
   747  			configProduction,
   748  		),
   749  		nil,
   750  		nil,
   751  	)
   752  	if err := task.Main(); err != nil {
   753  		fail("%s\n", err)
   754  	}
   755  }
   756  
   757  func makeSqliteTest(goos, goarch string, more []string) {
   758  	task := ccgo.NewTask(
   759  		join(
   760  			[]string{
   761  				"ccgo",
   762  				"-DSQLITE_PRIVATE=",
   763  				"-export-defines", "",
   764  				"-export-enums", "",
   765  				"-export-externs", "X",
   766  				"-export-fields", "F",
   767  				"-export-typedefs", "",
   768  				"-ignore-unsupported-alignment",
   769  				"-pkgname", "sqlite3",
   770  				"-o", filepath.FromSlash(fmt.Sprintf("libtest/sqlite_%s_%s.go", goos, goarch)),
   771  				"-trace-translation-units",
   772  				volatiles,
   773  				filepath.Join(sqliteDir, "sqlite3.c"),
   774  			},
   775  			otherOpts(),
   776  			more,
   777  			configTest,
   778  		),
   779  		nil,
   780  		nil,
   781  	)
   782  	if err := task.Main(); err != nil {
   783  		fail("%s\n", err)
   784  	}
   785  }
   786  
   787  func join(a ...[]string) (r []string) {
   788  	n := 0
   789  	for _, v := range a {
   790  		n += len(v)
   791  	}
   792  	r = make([]string, 0, n)
   793  	for _, v := range a {
   794  		r = append(r, v...)
   795  	}
   796  	return r
   797  }