diff --git a/LICENSE.md b/LICENSE.md index 5382a66842..ebfc077603 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -19,7 +19,7 @@ that are public domain include the following: * All of the SQLite extension source code and test cases in the [ext/ directory](https://sqlite.org/src/tree/ext?type=tree&expand) * All code that ends up in the "sqlite3.c" and "sqlite3.h" build products - that actually implements the SQLite RDBMS. + that actually implement the SQLite RDBMS. * All of the code used to compile the [command-line interface](https://sqlite.org/cli.html) * All of the code used to build various utility programs such as diff --git a/Makefile.in b/Makefile.in index db7c8d5001..79154f3fed 100644 --- a/Makefile.in +++ b/Makefile.in @@ -4,9 +4,7 @@ # Makefile for SQLITE # # This makefile is intended to be configured automatically using the -# configure script. Hand editing may not work as expected because -# certain blocks are added or removed depending on configure-time -# information. +# configure script. # # The docs for many of its variables are in the primary static # makefile, main.mk (which this one includes at runtime). @@ -18,10 +16,6 @@ all: # Known TODOs/FIXMEs/TOIMPROVEs for the autosetup port, in no # particular order... # -# - libreadline detection and handling of its -I, -L, and -l flags. -# These can vary considerably across systems. e.g. some need -lncurses, -# and some don't know what an -lncurses is. -# # - TEA pieces. # # - Replace the autotools-specific distribution deliverable(s). @@ -34,13 +28,6 @@ all: # - This makefile should remain as POSIX-make-compatible as possible: # https://pubs.opengroup.org/onlinepubs/9799919799/utilities/make.html # -# - When using the X?=Y variable assignment formulation, please test -# the build with both GNU make and a POSIX make (e.g. BSD make, -# a.k.a. bmake). On at least one occassion, that formulation has led -# to inconsistent behavior between the two major make flavors when -# used with variable names which might sensibly be in the -# developer's environment (namely CC). -# # - The naming convention of some vars, using periods instead of # underscores, though unconventional, was selected for a couple of # reasons: 1) Personal taste (for which there is no accounting). 2) @@ -56,9 +43,6 @@ all: # TOP = @abs_top_srcdir@ # -# Some standard variables and programs -prefix ?= @prefix@ -# # Just testing some default dir expansions... # srcdir = @srcdir@ # builddir = @builddir@ @@ -67,6 +51,65 @@ prefix ?= @prefix@ # abs_top_builddir = @abs_top_builddir@ # +# +# Autotools-conventional vars which are used by package installation +# rules in main.mk. +# +# Autosetup allows the various XYZdir vars to be overridden at +# configure-time with, e.g. --libdir=X and --mandir=Y. However, +# defining them at configure-time, instead of at make-time, leads to +# later awkwardness: +# +# $ ./configure --prefix=/usr +# $ make prefix=/bar +# +# In that invocation, libdir will be /usr/foo, not /bar/foo as it +# normally should, unless the user _also_ passes libdir=... to make. +# +# In 99%+ of use cases, setting prefix=X has the desired effect of +# calculating conventional defaults for various other dirs, like +# $prefix/lib, $prefix/include, etc. If, however, we export those at +# configure-time, the passing prefix=... to make will update only +# $prefix and none of its derived dirs. +# +# Because it is more important (for our use cases) that these vars be +# overridable via a make invocation than a configure invocation, and +# they conventionally derive from $(prefix) in all but the most exotic +# of use cases, we do not export the configure-defined overrides of +# those vars to this makefile. Instead, we export only $prefix and +# its derived vars are set to their conventional default values in +# main.mk, which users can then override at make-time as needed. +# Overriding $prefix via make will also calculate any derived vars, as +# one would expect, unless each is specifically overridden. +# +# For completeness's sake, the aforementioned conventional vars which +# are relevant to our installation rules are: +# +# datadir = $(prefix)/share +# mandir = $(datadir)/man +# includedir = $(prefix)/include +# exec_prefix = $(prefix) +# bindir = $(exec_prefix)/bin +# libdir = $(exec_prefix)/lib +# +# Our builds do not require any of their relatives: +# +# sbindir = $(exec_prefix)/sbin +# sysconfdir = /etc +# sharedstatedir = $(prefix)/com +# localstatedir = /var +# runstatedir = /run +# infodir = $(datadir)/info +# libexecdir = $(exec_prefix)/libexec +# +prefix = @prefix@ +datadir = @datadir@ +mandir = @mandir@ +includedir = @includedir@ +exec_prefix = @exec_prefix@ +bindir = @bindir@ +libdir = @libdir@ + INSTALL = @BIN_INSTALL@ AR = @AR@ AR.flags = cr # TODO? Add a configure test to determine this? @@ -94,7 +137,7 @@ LDFLAGS.dlopen = @LDFLAGS_DLOPEN@ LDFLAGS.readline = @LDFLAGS_READLINE@ CFLAGS.readline = @CFLAGS_READLINE@ LDFLAGS.icu = @LDFLAGS_ICU@ - +LDFLAGS.soname.libsqlite3 = @LDFLAGS_SONAME_LIBSQLITE3@ ENABLE_SHARED = @ENABLE_SHARED@ ENABLE_STATIC = @ENABLE_STATIC@ HAVE_WASI_SDK = @HAVE_WASI_SDK@ @@ -115,23 +158,12 @@ T.cc.sqlite += -I$(prefix)/include # # main.mk will fill out T.cc.sqlite with some flags common to all builds. -#XX#CFLAGS.readline += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@ -#XX#CFLAGS.readline += -DHAVE_LINENOISE=@TARGET_HAVE_LINENOISE@ -#XX# -#XX## The library that programs using readline() must link against. -#XX## -#XX#LIBREADLINE = @TARGET_READLINE_LIBS@ -#XX# -#XX## Should the database engine be compiled threadsafe -#XX## -#XX#T.cc += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@ - # -# $(JIMSH) and $(CFLAGS.JIMSH) are documented in main.mk. $(JIMSH) +# $(JIMSH) and $(CFLAGS.jimsh) are documented in main.mk. $(JIMSH) # must start with a path component so that it can be invoked as a # shell command. # -CFLAGS.JIMSH = @CFLAGS_JIMSH@ +CFLAGS.jimsh = @CFLAGS_JIMSH@ JIMSH = ./jimsh$(TEXE) # @@ -312,16 +344,20 @@ misspell: ./custom.rws has_tclsh84 # perform cleanup known to be relevant to (only) the autosetup-driven # build. # -clean-autosetup: - -gmake -C ext/wasm distclean 2>/dev/null || true -clean: clean-autosetup +#clean-autosetup: +# -if [ -f ext/wasm/GNUmakefile ]; then \ +# gmake --no-print-directory --ignore-errors -C ext/wasm clean; \ +# fi >/dev/null 2>&1; true +#clean: clean-autosetup distclean-autosetup: clean rm -f sqlite_cfg.h config.log config.status config.defines.* Makefile sqlite3.pc rm -f $(TOP)/tool/emcc.sh rm -f libsqlite3*$(T.dll) rm -f jimsh0* - -gmake -C ext/wasm distclean 2>/dev/null; true +# -if [ -f ext/wasm/GNUmakefile ]; then \ +# gmake --no-print-directory --ignore-errors -C ext/wasm distclean; \ +# fi >/dev/null 2>&1; true distclean: distclean-autosetup # diff --git a/auto.def b/auto.def index 46a0721731..88c08bef09 100644 --- a/auto.def +++ b/auto.def @@ -1,4 +1,4 @@ -#/usr/bin/tclsh +#/do/not/tclsh # ^^^ help out editors which guess this file's content type. # # This is the main autosetup-compatible configure script for the @@ -169,7 +169,7 @@ set flags { # --with-readline-ldflags with-readline-lib: with-readline-ldflags:=auto - => {Readline LDFLAGS, e.g. -lreadline -lncurses} + => {Readline LDFLAGS, e.g. -lreadline -lncurses} # --with-readline-inc is a backwards-compatible alias for # --with-readline-cflags. with-readline-inc: @@ -178,7 +178,7 @@ set flags { with-readline-header:PATH => {Full path to readline.h, from which --with-readline-cflags will be derived} with-linenoise:DIR => {Source directory for linenoise.c and linenoise.h} - editline=0 => {BSD editline support} + editline=0 => {Enable BSD editline support} # # with-icu-ldflags:LDFLAGS @@ -189,7 +189,7 @@ set flags { # with-wasi-sdk:=/opt/wasi-sdk => {Top-most dir of the wasi-sdk for a WASI build} - with-emsdk:DIR => {Top-most dir of the Emscripten SDK installation} + with-emsdk:=auto => {Top-most dir of the Emscripten SDK installation. Default = EMSDK env var.} # # test-status => {Enable status of tests} @@ -197,7 +197,6 @@ set flags { linemacros => {Enable #line macros in the amalgamation} dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)} # - } if {"" ne $DUMP_DEFINES_JSON} { lappend flags \ @@ -205,7 +204,7 @@ if {"" ne $DUMP_DEFINES_JSON} { => {Include lower-case defines (primarily system paths) in $DUMP_DEFINES_JSON} } -options [subst $flags] +options [subst -nobackslashes -nocommands $flags] unset flags # @@ -218,35 +217,39 @@ proj-xfer-options-aliases { } set srcdir $::autosetup(srcdir) -set top_srcdir [get-define abs_top_srcdir] -set PACKAGE_VERSION [readfile $srcdir/VERSION] +set PACKAGE_VERSION [proj-file-content -trim $srcdir/VERSION] define PACKAGE_NAME "sqlite" define PACKAGE_URL {https://sqlite.org} define PACKAGE_VERSION $PACKAGE_VERSION define PACKAGE_STRING "[get-define PACKAGE_NAME] $PACKAGE_VERSION" define PACKAGE_BUGREPORT [get-define PACKAGE_URL]/forum -msg-result "srcdir = $srcdir" -msg-result "top_srcdir = $top_srcdir" +msg-result "Source dir = $srcdir" +msg-result "Build dir = $::autosetup(builddir)" msg-result "Configuring SQLite version $PACKAGE_VERSION" -# -# SQLITE_AUTORECONFIG contains make target rules for re-running the -# configure script with the same arguments it was initially invoked -# with. This can be used to automatically reconfigure -# -define-append SQLITE_AUTORECONFIG cd '$::autosetup(builddir)' && '$top_srcdir/configure' -#{*}$::autosetup(argv) breaks with --flag='val with spaces', so... -foreach arg $::autosetup(argv) { - define-append SQLITE_AUTORECONFIG '$arg' +if {1} { + # + # SQLITE_AUTORECONFIG contains make target rules for re-running the + # configure script with the same arguments it was initially invoked + # with. This can be used to automatically reconfigure + # + proc squote {arg} { + # Wrap $arg in single-quotes if it looks like it might need that + # to avoid mis-handling as a shell argument. We assume that $arg + # will never contain any single-quote characters. + if {[string match {*[ &;$*"]*} $arg]} { return '$arg' } + return $arg + } + define-append SQLITE_AUTORECONFIG cd [squote $::autosetup(builddir)] && [squote $srcdir/configure] + #{*}$::autosetup(argv) breaks with --flag='val with spaces', so... + foreach arg $::autosetup(argv) { + define-append SQLITE_AUTORECONFIG [squote $arg] + } + rename squote "" } # Are we cross-compiling? set isCrossCompiling [proj-is-cross-compiling] -if {![file exists sqlite3.pc.in]} { - msg-result "This appears to be an out-of-tree build." -} - -cc-check-tools ld ar define OPT_FEATURE_FLAGS {} ; # -DSQLITE_OMIT/ENABLE flags. define OPT_SHELL {} ; # CFLAGS for the sqlite3 CLI app @@ -296,6 +299,7 @@ if {".exe" eq [get-define TARGET_EXEEXT]} { ######### # Programs needed +cc-check-tools ld ar ; # must come before sqlite-check-wasi-sdk if {"" eq [proj-bin-define install]} { proj-warn "Cannot find install binary, so 'make install' will not work." } @@ -307,13 +311,8 @@ if {"" eq [proj-bin-define install]} { # compiling binaries for the target system (CC a.k.a. $(T.cc)). # Normally they're the same, but they will differ when # cross-compiling. -set defaultCFlags {-g -O2} -if {[file exists .default-CFLAGS]} { - set defaultCFlags [proj-file-content -trim .default-CFLAGS] -} -define CFLAGS [get-env CFLAGS $defaultCFlags] -unset defaultCFlags -define BUILD_CFLAGS [get-env BUILD_CFLAGS {-g}] +define CFLAGS [proj-get-env CFLAGS {-g -O2}] +define BUILD_CFLAGS [proj-get-env BUILD_CFLAGS {-g}] ######################################################################## # Handle --with-wasi-sdk=DIR @@ -411,7 +410,13 @@ if {[cc-check-includes zlib.h] && [proj-check-function-in-lib deflate z]} { define LDFLAGS_ZLIB "" } -proj-check-rpath; # Determine proper rpath-handling flags. +proj-check-rpath ; # Determine proper rpath-handling flag +if {0 && [proj-check-soname libsqlite3.so.3]} { + # It's not yet clear whether we gain anything from setting -soname + define LDFLAGS_SONAME_LIBSQLITE3 [get-define LDFLAGS_SONAME_PREFIX]libsqlite3.so.3 +} else { + define LDFLAGS_SONAME_LIBSQLITE3 "" +} proj-define-if-opt-truthy shared ENABLE_SHARED "Build shared library?" @@ -480,7 +485,7 @@ proc sqlite-check-tcl {} { return } # TODO: document the steps this is taking. - global top_srcdir + global srcdir msg-result "Checking for a suitable tcl... " proj-assert {proj-opt-truthy tcl} set use_tcl 1 @@ -507,7 +512,7 @@ proc sqlite-check-tcl {} { define TCLSH_CMD $with_tclsh #msg-result "Using tclsh: $with_tclsh" } - if {[catch {exec $with_tclsh $top_srcdir/tool/find_tclconfig.tcl} result] == 0} { + if {[catch {exec $with_tclsh $srcdir/tool/find_tclconfig.tcl} result] == 0} { set with_tcl $result } if {"" ne $with_tcl && [file isdir $with_tcl]} { @@ -573,7 +578,7 @@ proc sqlite-check-tcl {} { # Export a subset of tclConfig.sh to the current TCL-space. If the # config is not available, this emits empty-string entries for the # various options we're interested in. - eval [exec "${top_srcdir}/tool/tclConfigShToTcl.sh" "$cfg"] + eval [exec "${srcdir}/tool/tclConfigShToTcl.sh" "$cfg"] if {"" eq $with_tclsh && $cfg ne ""} { proj-assert {expr {"" ne [get-define TCL_EXEC_PREFIX]}} @@ -646,8 +651,8 @@ sqlite-check-tcl # in-tree (it's part of autosetup) unless --with-tclsh=X is used, in # which case prefix X. # -# Returns the name of the TCL it selects. Fails fatally if it cannot -# detect a TCL appropriate for code generation. +# Returns the human-readable name of the TCL it selects. Fails fatally +# if it cannot detect a TCL appropriate for code generation. # # Defines: # @@ -655,10 +660,11 @@ sqlite-check-tcl # to an unexpanded makefile var name. # # - CFLAGS_JIMSH = any flags needed for buildng a BTCLSH-compatible -# jimsh. +# jimsh. The defaults may be pass on to configure as +# CFLAGS_JIMSH=... proc sqlite-determine-codegen-tcl {} { msg-result "Checking for TCL to use for code generation... " - define CFLAGS_JIMSH {} + define CFLAGS_JIMSH [proj-get-env CFLAGS_JIMSH {-O1}] set cgtcl [opt-val with-tclsh jimsh] set flagsToRestore {CC CFLAGS CPPFLAGS LDFLAGS LINKFLAGS LIBS CROSS} define-push $flagsToRestore { @@ -943,6 +949,9 @@ proc sqlite-check-line-editing {} { # If we found a library, configure the build to use it... if {"" ne $rlLib} { if {"editline" eq $editLibName && "HAVE_READLINE" eq $editLibDef} { + # Alert the user that, despite outward appearances, we won't be + # linking to the GPL'd libreadline. Presumably that distinction is + # significant for those using --editline. proj-indented-notice { NOTE: the local libedit but uses so we will compile with -DHAVE_READLINE=1 but will link with @@ -1194,6 +1203,18 @@ if {0 && "" ne [get-define CFLAGS_JIMSH]} { define-append CFLAGS_JIMSH -DHAVE_LONG_LONG; # SQLite relies on long long, so we know it's available }; # JimTCL + +######################################################################## +# "Re-export" the autoconf-conventional --XYZdir flags into something +# which is more easily overridable from a make invocation. See the docs +# for [proj-remap-autoconf-dir-vars] for the explanation of why. +# +# We do this late in the config process, immediately before we export +# the Makefile and other generated files, so that configure tests +# which may make use of the autotools-conventional flags +# (e.g. [proj-check-rpath]) may do so before we "mangle" them here. +proj-remap-autoconf-dir-vars + ######################################################################## # Generate the output files. # @@ -1214,44 +1235,37 @@ if {0} { -none * proj-touch sqlite_cfg.h ; # help avoid frequent unnecessary @SQLITE_AUTORECONFIG@ } -#TODO proj-make-from-dot-in ext/wasm/GNUmakefile - -if {"" ne $DUMP_DEFINES_JSON} { - ######################################################################## - # Dump config-defines.json... - # Demonstrate (mis?)handling of spaces in JSON-export array values: - # define-append OPT_FOO.list {"-DFOO=bar baz" -DBAR="baz barre"} - define OPT_FEATURE_FLAGS.list [get-define OPT_FEATURE_FLAGS] - define OPT_SHELL.list [get-define OPT_SHELL] - set dumpDefsOpt { - -bare {SIZEOF_* HAVE_DECL_*} - -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTORECONFIG TARGET_* USE_GCOV TCL_*} - -array {*.list} - -auto {OPT_* PACKAGE_* HAVE_*} - } - if {[opt-bool defines-json-include-lowercase]} { - lappend dumpDefsOpt -none {lib_*} ; # remnants from proj-check-function-in-lib and friends - lappend dumpDefsOpt -auto {[a-z]*} - } - lappend dumpDefsOpt -none * - proj-dump-defs-json $DUMP_DEFINES_JSON {*}$dumpDefsOpt - undefine OPT_FEATURE_FLAGS.list - undefine OPT_SHELL.list -} ######################################################################## # Some build-dev/debug-only output proj-if-opt-truthy dump-defines { - msg-result "--dump-defines is creating $::DUMP_DEFINES_TXT" make-config-header $::DUMP_DEFINES_TXT \ -bare {SQLITE_OS* SQLITE_DEBUG USE_*} \ -str {BIN_* CC LD AR LDFLAG* OPT_*} \ -auto {*} # achtung: ^^^^ whichever SQLITE_OS_foo flag which is set to 0 will # get _undefined_ here unless it's part of the -bare set. - if {0} { - foreach x [all-defines] { - puts "\t$x" + if {"" ne $DUMP_DEFINES_JSON} { + msg-result "--dump-defines is creating $::DUMP_DEFINES_JSON" + ######################################################################## + # Dump config-defines.json... + # Demonstrate (mis?)handling of spaces in JSON-export array values: + # define-append OPT_FOO.list {"-DFOO=bar baz" -DBAR="baz barre"} + define OPT_FEATURE_FLAGS.list [get-define OPT_FEATURE_FLAGS] + define OPT_SHELL.list [get-define OPT_SHELL] + set dumpDefsOpt { + -bare {SIZEOF_* HAVE_DECL_*} + -none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTORECONFIG TARGET_* USE_GCOV TCL_*} + -array {*.list} + -auto {OPT_* PACKAGE_* HAVE_*} } + if {[opt-bool defines-json-include-lowercase]} { + lappend dumpDefsOpt -none {lib_*} ; # remnants from proj-check-function-in-lib and friends + lappend dumpDefsOpt -auto {[a-z]*} + } + lappend dumpDefsOpt -none * + proj-dump-defs-json $DUMP_DEFINES_JSON {*}$dumpDefsOpt + undefine OPT_FEATURE_FLAGS.list + undefine OPT_SHELL.list } } diff --git a/autosetup/README.md b/autosetup/README.md new file mode 100644 index 0000000000..8f0f5601e7 --- /dev/null +++ b/autosetup/README.md @@ -0,0 +1,291 @@ +Maintaining Autosetup in the SQLite Tree +======================================================================== + +This document provides some tips and reminders for the SQLite +developers regarding using and maintaining the [Autosetup][]-based +build infrastructure. It is not an [Autosetup][] reference. + +**Table of Contents**: + +- [Autosetup API Reference](#apiref) +- [API Tips](#apitips) +- [Ensuring TCL Compatibility](#tclcompat) +- [Design Conventions](#conventions) + - Symbolic Names of Feature Flags + - Do Not Update Global Shared State +- [Updating Autosetup](#updating) + +------------------------------------------------------------------------ + + +Autosetup API Reference +======================================================================== + +The Autosetup API is quite extensive and can be read either in +the [files in the `autosetup` dir](/dir/autosetup) or using: + +> +``` +$ ./configure --reference | less +``` + +That will include any docs from any TCL files in the `./autosetup` dir +which contain certain (simple) markup defined by autosetup. + +This project's own autosetup-related APIs are in [proj.tcl][] or +[auto.def][]. The former contains helper APIs which are, more or +less, portable across projects (that file is re-used as-is in other +projects) and all have a `proj-` name prefix. The latter is the main +configure script driver and contains related functions which are +specific to this tree. + + + +Autosetup API Tips +======================================================================== + +This section briefly covers only APIs which are frequently useful in +day-to-day maintenance and might not be immediately recognized as such +obvious from a casual perusal of `auto.def`. Their complete docs can be +found in [proj.tcl][]. + +In (mostly) alphabetical order: + +- **`get-env VAR ?default?`**\ + Will fetch an "environment variable" + from the first of either: (A) a KEY=VALUE passed to the configure + script or (B) the system's environment variables. Not to be confused + with `getenv`, which only does the latter and is rarely, if ever, + useful in this tree. + - **`proj-get-env VAR ?default?`**\ + Works like `get-env` but will, if that function finds no match, + look for a file named `./.env-$VAR` and, if found, return its + trimmed contents. This can be used, e.g., to set a developer's + local preferences for the default `CFLAGS`. + +- **`proj-define-if-opt-truthy flag defineName checkingMsg ?yesVal=1? ?noVal=0?`**\ + Defines `defineName` to either `yesVal` or `noVal`, depending on + whether `--flag` is truthy or not. + +- **`proj-if-opt-truthy flag thenScript ?elseScript?`**\ + Evals `thenScript` if the given `--flag` is truthy, else it + evals the optional `elseScript`. + +- **`proj-indented-notice ?-error? msg`**\ + Breaks its `msg` argument into lines, trims them, and emits them + with consistent indentation. If the `-error` flag is used, it then + exits with a non-0 result code. This will stick out starkly from + normal output and is intended to be used only for important notices. + +- **`proj-opt-truthy flag`**\ + Returns 1 if `--flag`'s value is "truthy," i.e. one of (1, on, + enabled, yes). + +- **`proj-opt-was-provided FLAG`**\ + Returns 1 if `--FLAG` was explicitly provided to configure, + else 0. This distinction can be used to determine, e.g., whether + `--with-readline` was provided or whether we're searching for + readline by default. In the former case, failure to find it should + be treated as fatal. + +- **`proj-val-truthy value`**\ + Returns 1 if `$value` is "truthy," i.e. one of (1, on, enabled, + yes). + +- **`sqlite-add-feature-flag ?-shell? FLAG...`**\ + Adds the given feature flag to the CFLAGS which are specific to building + the library. It's intended to be passed one or more `-DSQLITE_ENABLE_...`, + or similar, flags. If the `-shell` flag is used then it also passes + its arguments to `sqlite-add-shell-opt`. This is a no-op if `FLAG` + is not provided or is empty. + +- **`sqlite-add-shell-opt FLAG...`**\ + The shell-specific counterpart of `sqlite-add-feature-flag`. + + +Ensuring TCL Compatibility +======================================================================== + +It is important that any TCL files used by the configure process +remain compatible with both [JimTCL][] and the canonical TCL. Though +JimTCL has outstanding compatibility with canonical TCL, it does have +a few corners with incompatibilities, e.g. regular expressions. If a +script runs in JimTCL without using any JimTCL-specific features, then +it's a certainty that it will run in canonical TCL as well. The +opposite, however, is not _always_ the case. + +When [`./configure`](/file/configure) is run, it goes through a +bootstrapping process to find a suitable TCL with which to run the +autosetup framework. The first step involves [finding or building a +TCL shell](/file/autosetup/autosetup-find-tclsh). That will first +search for an available `tclsh` (under several common names, +e.g. `tclsh8.6`) before falling back to compiling the copy of +`jimsh0.c` included in the source tree. i.e. it will prefer to use a +system-installed TCL for running the configure script. Once it finds +(or builds) a TCL shell, it then runs [a sanity test to ensure that +the shell is suitable](/file/autosetup/autosetup-test-tclsh) before +using it to run the main autosetup app. + +There are two simple ways to ensure that running of the configure +process uses JimTCL instead of the canonical `tclsh`, and either +approach provides equally high assurances about configure script +compatibility across TCL implementations: + +1. Build on a system with no `tclsh` installed in the `$PATH`. In that + case, the configure process will fall back to building the in-tree + copy of JimTCL. + +2. Manually build `./jimsh0` in the top of the checkout with:\ + `cc -o jimsh0 autosetup/jimsh0.c`\ + With that in place, the configure script will prefer to use that + before looking for a system-level `tclsh`. Be aware, though, that + `make distclean` will remove that file. + +**Note that `jimsh0` is distinctly different** from the `jimsh` which +gets built for code-generation purposes. The latter requires +non-default build flags to enable features which are +platform-dependent, most notably to make its `[file normalize]` work. +This means, for example, that the configure script and its utility +APIs must not use `[file normalize]`, but autosetup provides a TCL +implementation of `[file-normalize]` (note the dash) for portable use +in the configure script. + + + +Design Conventions +======================================================================== + +This section describes the motivations for the most glaring of the +build's design decisions, in particular how they deviate from +historical, or even widely-conventional, practices. + +Symbolic Names of Feature Flags +------------------------------------------------------------------------ + +Historically, the project's makefile has exclusively used +`UPPER_UNDERSCORE` form for makefile variables. This build, however, +primarily uses `X.y` format, where `X` is often a category label, +e.g. `CFLAGS` and `y` is the specific instance of that category, +e.g. `CFLAGS.readline`. + +When the configure script exports flags for consumption by filtered +files, e.g. [Makefile.in][] and the generated +`sqlite_cfg.h`, it does so in the more conventional `X_Y` form because +those flags get exported as as C `#define`s to `sqlite_cfg.h`, where +dots are not permitted. + +The `X.y` convention is used in the makefiles primarily because the +person who did the initial port finds that considerably easier on the +eyes and fingers. In practice, the `X_Y` form of such exports is used +exactly once in [Makefile.in][], where it's translated into into `X.y` +form for consumption by [Makefile.in][] and [main.mk][]. For example: + +> +``` +LDFLAGS.shobj = @SHOBJ_LDFLAGS@ +LDFLAGS.zlib = @LDFLAGS_ZLIB@ +LDFLAGS.math = @LDFLAGS_MATH@ +``` + +(That first one is defined by autosetup, and thus applies "LDFLAGS" as +the suffix rather than the prefix. Which is more legible is a matter +of taste, for which there is no accounting.) + + +Do Not Update Global Shared State +------------------------------------------------------------------------ + +In both the legacy Autotools-driven build and in common Autosetup +usage, feature tests performed by the configure script may amend +global flags such as `LIBS`, `LDFLAGS`, and `CFLAGS`[^as-cflags]. That's +appropriate for a makefile which builds a single deliverable, but less +so for makefiles which produce multiple deliverables. Drawbacks of +that approach include: + +- It's unlikely that every single deliverable will require the same + core set of those flags. +- It can be difficult to determine the origin of any given change to + that global state because those changes are hidden behind voodoo performed + outside the immediate visibility of the configure script's + maintainer. +- It can force the maintainers of the configure script to place tests + in a specific order so that the resulting flags get applied at + the correct time and/or in the correct order.\ + (A real-life example: before the approach described below was taken + to collecting build-time flags, the test for `-rpath` had to come + _after_ the test for zlib because the results of the `-rpath` test + implicitly modified global state which broke the zlib feature + test. Because the feature tests no longer (intentionally) modify + global state, that is not an issue.) + +In this build, cases where feature tests modify global state in such a +way that it may impact later feature tests are either (A) very +intentionally defined to do so (e.g. the `--with-wasi-sdk` flag has +invasive side-effects) or (B) are oversights (i.e. bugs). + +This tree's [configure script][auto.def], [utility APIs][proj.tcl], +[Makefile.in][], and [main.mk][] therefore strive to separate the +results of any given feature test into its own well-defined +variables. For example: + +- The linker flags for zlib are exported from the configure script as + `LDFLAGS_ZLIB`, which [Makefile.in][] and [main.mk][] then expose as + `LDFLAGS.zlib`. +- `CFLAGS_READLINE` (a.k.a. `CFLAGS.readline`) contains the `CFLAGS` + needed for including `libreadline`, `libedit`, or `linenoise`, and + `LDFLAGS_READLINE` (a.k.a. `LDFLAGS.readline`) is its link-time + counterpart. + +It is then up to the Makefile to apply and order the flags however is +appropriate. + +At the end of the configure script, the global `CFLAGS` _ideally_ +holds only flags which are either relevant to all targets or, failing +that, will have no unintended side-effects on any targets. That said: +clients frequently pass custom `CFLAGS` to `./configure` or `make` to +set library-level feature toggles, e.g. `-DSQLITE_OMIT_FOO`, in which +case there is no practical way to avoid "polluting" the builds of +arbitrary makefile targets with those. _C'est la vie._ + + +[^as-cflags]: But see this article for a detailed discussion of how + autosetup currently deals specifically with CFLAGS: + + + + +Updating Autosetup +======================================================================== + +Updating autosetup is, more often than not, painless. It requires having +a checked-out copy of [the autosetup git repository][autosetup-git]: + +> +``` +$ git clone https://github.com/msteveb/autosetup +$ cd autosetup +# Or, if it's already checked out: +$ git pull +``` + +Then, from the top-most directory of an SQLite checkout: + +> +``` +$ /path/to/autosetup-checkout/autosetup --install . +$ fossil status # show the modified files +``` + +Unless the upgrade made any incompatible changes (which is exceedingly +rare), that's all there is to it. Check over the diff, test the +configure process, and check it in. + + + +[Autosetup]: https://msteveb.github.io/autosetup/ +[auto.def]: /file/auto.def +[autosetup-git]: https://github.com/msteveb/autosetup +[proj.tcl]: /file/autosetup/proj.tcl +[Makefile.in]: /file/Makefile.in +[main.mk]: /file/main.mk +[JimTCL]: https://jim.tcl.tk diff --git a/autosetup/autosetup-find-tclsh b/autosetup/autosetup-find-tclsh index 3b661d26ae..2b2006241c 100755 --- a/autosetup/autosetup-find-tclsh +++ b/autosetup/autosetup-find-tclsh @@ -5,12 +5,12 @@ # If an argument is given, use that as the test instead of autosetup-test-tclsh d="`dirname "$0"`" for tclsh in ./jimsh0 $autosetup_tclsh jimsh tclsh tclsh8.5 tclsh8.6 tclsh8.7; do - { $tclsh "$d/${1-autosetup-test-tclsh}"; } 2>/dev/null && exit 0 + { $tclsh "$d/${1-autosetup-test-tclsh}"; } 2>/dev/null && exit 0 done echo 1>&2 "No installed jimsh or tclsh, building local bootstrap jimsh0" for cc in ${CC_FOR_BUILD:-cc} gcc; do - { $cc -o jimsh0 "$d/jimsh0.c"; } >/dev/null 2>&1 || continue - ./jimsh0 "$d/${1-autosetup-test-tclsh}" && exit 0 + { $cc -o jimsh0 "$d/jimsh0.c"; } >/dev/null 2>&1 || continue + ./jimsh0 "$d/${1-autosetup-test-tclsh}" && exit 0 done echo 1>&2 "No working C compiler found. Tried ${CC_FOR_BUILD:-cc} and gcc." echo false diff --git a/autosetup/cc.tcl b/autosetup/cc.tcl index 5e724d9b78..05c1b1cf40 100644 --- a/autosetup/cc.tcl +++ b/autosetup/cc.tcl @@ -677,80 +677,82 @@ proc calc-define-output-type {name spec} { return "" } -# Initialise some values from the environment or commandline or default settings -foreach i {LDFLAGS LIBS CPPFLAGS LINKFLAGS CFLAGS} { - lassign $i var default - define $var [get-env $var $default] -} +proc cc-init {} { + global autosetup -if {[env-is-set CC]} { - # Set by the user, so don't try anything else - set try [list [get-env CC ""]] -} else { - # Try some reasonable options - set try [list [get-define cross]cc [get-define cross]gcc] -} -define CC [find-an-executable {*}$try] -if {[get-define CC] eq ""} { - user-error "Could not find a C compiler. Tried: [join $try ", "]" -} - -define CPP [get-env CPP "[get-define CC] -E"] - -# XXX: Could avoid looking for a C++ compiler until requested -# If CXX isn't found, it is set to the empty string. -if {[env-is-set CXX]} { - define CXX [find-an-executable -required [get-env CXX ""]] -} else { - define CXX [find-an-executable [get-define cross]c++ [get-define cross]g++] -} - -# CXXFLAGS default to CFLAGS if not specified -define CXXFLAGS [get-env CXXFLAGS [get-define CFLAGS]] - -# May need a CC_FOR_BUILD, so look for one -define CC_FOR_BUILD [find-an-executable [get-env CC_FOR_BUILD ""] cc gcc false] - -if {[get-define CC] eq ""} { - user-error "Could not find a C compiler. Tried: [join $try ", "]" -} - -# These start empty and never come from the user or environment -define AS_CFLAGS "" -define AS_CPPFLAGS "" -define AS_CXXFLAGS "" - -define CCACHE [find-an-executable [get-env CCACHE ccache]] - -# If any of these are set in the environment, propagate them to the AUTOREMAKE commandline -foreach i {CC CXX CCACHE CPP CFLAGS CXXFLAGS CXXFLAGS LDFLAGS LIBS CROSS CPPFLAGS LINKFLAGS CC_FOR_BUILD LD} { - if {[env-is-set $i]} { - # Note: If the variable is set on the command line, get-env will return that value - # so the command line will continue to override the environment - define-append-argv AUTOREMAKE $i=[get-env $i ""] + # Initialise some values from the environment or commandline or default settings + foreach i {LDFLAGS LIBS CPPFLAGS LINKFLAGS CFLAGS} { + lassign $i var default + define $var [get-env $var $default] } -} -# Initial cctest settings -cc-store-settings {-cflags {} -includes {} -declare {} -link 0 -lang c -libs {} -code {} -nooutput 0} -set autosetup(cc-include-deps) {} + if {[env-is-set CC]} { + # Set by the user, so don't try anything else + set try [list [get-env CC ""]] + } else { + # Try some reasonable options + set try [list [get-define cross]cc [get-define cross]gcc] + } + define CC [find-an-executable {*}$try] + if {[get-define CC] eq ""} { + user-error "Could not find a C compiler. Tried: [join $try ", "]" + } -msg-result "C compiler...[get-define CCACHE] [get-define CC] [get-define CFLAGS] [get-define CPPFLAGS]" -if {[get-define CXX] ne "false"} { - msg-result "C++ compiler...[get-define CCACHE] [get-define CXX] [get-define CXXFLAGS] [get-define CPPFLAGS]" -} -msg-result "Build C compiler...[get-define CC_FOR_BUILD]" + define CPP [get-env CPP "[get-define CC] -E"] -# On Darwin, we prefer to use -g0 to avoid creating .dSYM directories -# but some compilers may not support it, so test here. -switch -glob -- [get-define host] { - *-*-darwin* { - if {[cctest -cflags {-g0}]} { - define cc-default-debug -g0 + # XXX: Could avoid looking for a C++ compiler until requested + # If CXX isn't found, it is set to the empty string. + if {[env-is-set CXX]} { + define CXX [find-an-executable -required [get-env CXX ""]] + } else { + define CXX [find-an-executable [get-define cross]c++ [get-define cross]g++] + } + + # CXXFLAGS default to CFLAGS if not specified + define CXXFLAGS [get-env CXXFLAGS [get-define CFLAGS]] + + # May need a CC_FOR_BUILD, so look for one + define CC_FOR_BUILD [find-an-executable [get-env CC_FOR_BUILD ""] cc gcc false] + + # These start empty and never come from the user or environment + define AS_CFLAGS "" + define AS_CPPFLAGS "" + define AS_CXXFLAGS "" + + define CCACHE [find-an-executable [get-env CCACHE ccache]] + + # If any of these are set in the environment, propagate them to the AUTOREMAKE commandline + foreach i {CC CXX CCACHE CPP CFLAGS CXXFLAGS CXXFLAGS LDFLAGS LIBS CROSS CPPFLAGS LINKFLAGS CC_FOR_BUILD LD} { + if {[env-is-set $i]} { + # Note: If the variable is set on the command line, get-env will return that value + # so the command line will continue to override the environment + define-append-argv AUTOREMAKE $i=[get-env $i ""] } } + + # Initial cctest settings + cc-store-settings {-cflags {} -includes {} -declare {} -link 0 -lang c -libs {} -code {} -nooutput 0} + set autosetup(cc-include-deps) {} + + msg-result "C compiler...[get-define CCACHE] [get-define CC] [get-define CFLAGS] [get-define CPPFLAGS]" + if {[get-define CXX] ne "false"} { + msg-result "C++ compiler...[get-define CCACHE] [get-define CXX] [get-define CXXFLAGS] [get-define CPPFLAGS]" + } + msg-result "Build C compiler...[get-define CC_FOR_BUILD]" + + # On Darwin, we prefer to use -g0 to avoid creating .dSYM directories + # but some compilers may not support it, so test here. + switch -glob -- [get-define host] { + *-*-darwin* { + if {[cctest -cflags {-g0}]} { + define cc-default-debug -g0 + } + } + } + + if {![cc-check-includes stdlib.h]} { + user-error "Compiler does not work. See config.log" + } } -if {![cc-check-includes stdlib.h]} { - user-error "Compiler does not work. See config.log" -} +cc-init diff --git a/autosetup/jimsh0.c b/autosetup/jimsh0.c index fb4e8b806d..84db85a207 100644 --- a/autosetup/jimsh0.c +++ b/autosetup/jimsh0.c @@ -1293,8 +1293,14 @@ int Jim_initjimshInit(Jim_Interp *interp) " if {[string match \"*/*\" $jim::argv0]} {\n" " set jim::exe [file join [pwd] $jim::argv0]\n" " } else {\n" -" foreach path [split [env PATH \"\"] $tcl_platform(pathSeparator)] {\n" -" set exec [file join [pwd] [string map {\\\\ /} $path] $jim::argv0]\n" +" set jim::argv0 [file tail $jim::argv0]\n" +" set path [split [env PATH \"\"] $tcl_platform(pathSeparator)]\n" +" if {$tcl_platform(platform) eq \"windows\"} {\n" +"\n" +" set path [lmap p [list \"\" {*}$path] { string map {\\\\ /} $p }]\n" +" }\n" +" foreach p $path {\n" +" set exec [file join [pwd] $p $jim::argv0]\n" " if {[file executable $exec]} {\n" " set jim::exe $exec\n" " break\n" @@ -19286,7 +19292,7 @@ static int Jim_StringCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *a JIM_DEF_SUBCMD("trim", "string ?trimchars?", 1, 2), JIM_DEF_SUBCMD("trimleft", "string ?trimchars?", 1, 2), JIM_DEF_SUBCMD("trimright", "string ?trimchars?", 1, 2), - { } + { NULL } }; const jim_subcmd_type *ct = Jim_ParseSubCmd(interp, cmds, argc, argv); if (!ct) { @@ -20179,7 +20185,7 @@ static int Jim_DictCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg JIM_DEF_SUBCMD("for", "vars dictionary script", 3, 3), JIM_DEF_SUBCMD("replace", "dictionary ?key value ...?", 1, -1), JIM_DEF_SUBCMD("update", "varName ?arg ...? script", 2, -1), - { } + { NULL } }; const jim_subcmd_type *ct = Jim_ParseSubCmd(interp, cmds, argc, argv); if (!ct) { @@ -20388,7 +20394,7 @@ static int Jim_InfoCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *arg JIM_DEF_SUBCMD("statics", "procname", 1, 1), JIM_DEF_SUBCMD("vars", "?pattern?", 0, 1), JIM_DEF_SUBCMD("version", NULL, 0, 0), - { } + { NULL } }; const jim_subcmd_type *ct; #ifdef jim_ext_namespace diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 537b281dde..5f44cf72cb 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -47,15 +47,26 @@ # updating global state via feature tests. ######################################################################## +# ----- @module proj.tcl ----- +# @section Project Helper APIs + ######################################################################## # $proj_ is an internal-use-only array for storing whatever generic # internal stuff we need stored. array set proj_ {} set proj_(isatty) [isatty? stdout] +######################################################################## +# @proj-warn msg +# +# Emits a warning message to stderr. proc proj-warn {msg} { puts stderr [proj-bold "WARNING: $msg"] } +######################################################################## +# @proj-error msg +# +# Emits an error message to stderr and exits with non-0. proc proj-fatal {msg} { show-notices puts stderr [proj-bold "ERROR: $msg"] @@ -63,6 +74,8 @@ proc proj-fatal {msg} { } ######################################################################## +# @proj-assert script +# # Kind of like a C assert if uplevel (eval) of $script is false, # triggers a fatal error. proc proj-assert {script} { @@ -75,6 +88,8 @@ proc proj-assert {script} { } ######################################################################## +# @proj-bold str +# # If this function believes that the current console might support # ANSI escape sequences then this returns $str wrapped in a sequence # to bold that text, else it returns $str as-is. @@ -86,6 +101,8 @@ proc proj-bold {str} { } ######################################################################## +# @proj-indented-notice ?-error? msg +# # Takes a multi-line message and emits it with consistent indentation # using [user-notice] (which means its rendering will (A) go to stderr # and (B) be delayed until the next time autosetup goes to output a @@ -109,6 +126,8 @@ proc proj-indented-notice {args} { } ######################################################################## +# @proj-is-cross-compiling +# # Returns 1 if cross-compiling, else 0. proc proj-is-cross-compiling {} { return [expr {[get-define host] ne [get-define build]}] @@ -150,9 +169,12 @@ proc proj-strip-hash-comments_ {val} { } ######################################################################## -# A proxy for cc-check-function-in-lib which "undoes" any changes that -# routine makes to the LIBS define. Returns the result of -# cc-check-function-in-lib. +# @proj-check-function-in-lib +# +# A proxy for cc-check-function-in-lib which does not make any global +# changes to the LIBS define. Returns the result of +# cc-check-function-in-lib (i.e. true or false). The resulting linker +# flags are stored in ${lib_${function}}. proc proj-check-function-in-lib {function libs {otherlibs {}}} { set found 0 define-push {LIBS} { @@ -162,6 +184,8 @@ proc proj-check-function-in-lib {function libs {otherlibs {}}} { } ######################################################################## +# @proj-search-for-header-dir ?-dirs LIST? ?-subdirs LIST? header +# # Searches for $header in a combination of dirs and subdirs, specified # by the -dirs {LIST} and -subdirs {LIST} flags (each of which have # sane defaults). Returns either the first matching dir or an empty @@ -193,7 +217,7 @@ proc proj-search-for-header-dir {header args} { } ######################################################################## -# Usage: proj-find-executable-path ?-v? binaryName +# @proj-find-executable-path ?-v? binaryName # # Works similarly to autosetup's [find-executable-path $binName] but: # @@ -220,6 +244,8 @@ proc proj-find-executable-path {args} { } ######################################################################## +# @proj-bin-define binName ?defName? +# # Uses [proj-find-executable-path $binName] to (verbosely) search for # a binary, sets a define (see below) to the result, and returns the # result (an empty string if not found). @@ -237,7 +263,7 @@ proc proj-bin-define {binName {defName {}}} { } ######################################################################## -# Usage: proj-first-bin-of bin... +# @proj-first-bin-of bin... # # Looks for the first binary found of the names passed to this # function. If a match is found, the full path to that binary is @@ -262,6 +288,8 @@ proc proj-first-bin-of {args} { } ######################################################################## +# @proj-opt-was-provided key +# # Returns 1 if the user specifically provided the given configure # flag, else 0. This can be used to distinguish between options which # have a default value and those which were explicitly provided by the @@ -281,6 +309,8 @@ proc proj-opt-was-provided {key} { } ######################################################################## +# @proj-opt-set flag ?val? +# # Force-set autosetup option $flag to $val. The value can be fetched # later with [opt-val], [opt-bool], and friends. # @@ -297,6 +327,8 @@ proc proj-opt-set {flag {val 1}} { } ######################################################################## +# @proj-val-truthy val +# # Returns 1 if $val appears to be a truthy value, else returns # 0. Truthy values are any of {1 on enabled yes} proc proj-val-truthy {val} { @@ -304,6 +336,8 @@ proc proj-val-truthy {val} { } ######################################################################## +# @proj-opt-truthy flag +# # Returns 1 if [opt-val $flag] appears to be a truthy value or # [opt-bool $flag] is true. See proj-val-truthy. proc proj-opt-truthy {flag} { @@ -317,6 +351,8 @@ proc proj-opt-truthy {flag} { } ######################################################################## +# @proj-if-opt-truthy boolFlag thenScript ?elseScript? +# # If [proj-opt-truthy $flag] is true, eval $then, else eval $else. proc proj-if-opt-truthy {boolFlag thenScript {elseScript {}}} { if {[proj-opt-truthy $boolFlag]} { @@ -327,6 +363,8 @@ proc proj-if-opt-truthy {boolFlag thenScript {elseScript {}}} { } ######################################################################## +# @proj-define-if-opt-truthy flag def ?msg? ?iftrue? ?iffalse? +# # If [proj-opt-truthy $flag] then [define $def $iftrue] else [define # $def $iffalse]. If $msg is not empty, output [msg-checking $msg] and # a [msg-results ...] which corresponds to the result. Returns 1 if @@ -354,7 +392,7 @@ proc proj-define-if-opt-truthy {flag def {msg ""} {iftrue 1} {iffalse 0}} { } ######################################################################## -# Args: [-v] optName defName {descr {}} +# @proj-opt-define-bool ?-v? optName defName ?descr? # # Checks [proj-opt-truthy $optName] and calls [define $defName X] # where X is 0 for false and 1 for true. descr is an optional @@ -392,6 +430,8 @@ proc proj-opt-define-bool {args} { } ######################################################################## +# @proj-check-module-loader +# # Check for module-loading APIs (libdl/libltdl)... # # Looks for libltdl or dlopen(), the latter either in -ldl or built in @@ -455,6 +495,8 @@ proc proj-check-module-loader {} { } ######################################################################## +# @proj-no-check-module-loader +# # Sets all flags which would be set by proj-check-module-loader to # empty/falsy values, as if those checks had failed to find a module # loader. Intended to be called in place of that function when @@ -466,6 +508,8 @@ proc proj-no-check-module-loader {} { } ######################################################################## +# @proj-file-conent ?-trim? filename +# # Opens the given file, reads all of its content, and returns it. If # the first arg is -trim, the contents of the file named by the second # argument are trimmed before returning them. @@ -484,6 +528,8 @@ proc proj-file-content {args} { } ######################################################################## +# @proj-file-conent filename +# # Returns the contents of the given file as an array of lines, with # the EOL stripped from each input line. proc proj-file-content-list {fname} { @@ -497,6 +543,8 @@ proc proj-file-content-list {fname} { } ######################################################################## +# @proj-check-compile-commands ?configFlag? +# # Checks the compiler for compile_commands.json support. If passed an # argument it is assumed to be the name of an autosetup boolean config # which controls whether to run/skip this check. @@ -506,9 +554,9 @@ proc proj-file-content-list {fname} { # # This test has a long history of false positive results because of # compilers reacting differently to the -MJ flag. -proc proj-check-compile-commands {{configOpt {}}} { +proc proj-check-compile-commands {{configFlag {}}} { msg-checking "compile_commands.json support... " - if {"" ne $configOpt && ![proj-opt-truthy $configOpt]} { + if {"" ne $configFlag && ![proj-opt-truthy $configFlag]} { msg-result "explicitly disabled" define MAKE_COMPILATION_DB no return 0 @@ -529,15 +577,15 @@ proc proj-check-compile-commands {{configOpt {}}} { } ######################################################################## +# @proj-touch filename +# # Runs the 'touch' command on one or more files, ignoring any errors. proc proj-touch {filename} { catch { exec touch {*}$filename } } ######################################################################## -# Usage: -# -# proj-make-from-dot-in ?-touch? filename(s)... +# @proj-make-from-dot-in ?-touch? filename... # # Uses [make-template] to create makefile(-like) file(s) $filename # from $filename.in but explicitly makes the output read-only, to @@ -569,6 +617,8 @@ proc proj-make-from-dot-in {args} { } ######################################################################## +# @proj-check-profile-flag ?flagname? +# # Checks for the boolean configure option named by $flagname. If set, # it checks if $CC seems to refer to gcc. If it does (or appears to) # then it defines CC_PROFILE_FLAG to "-pg" and returns 1, else it @@ -599,6 +649,8 @@ proc proj-check-profile-flag {{flagname profile}} { } ######################################################################## +# @proj-looks-like-windows ?key? +# # Returns 1 if this appears to be a Windows environment (MinGw, # Cygwin, MSys), else returns 0. The optional argument is the name of # an autosetup define which contains platform name info, defaulting to @@ -610,7 +662,7 @@ proc proj-check-profile-flag {{flagname profile}} { proc proj-looks-like-windows {{key host}} { global autosetup switch -glob -- [get-define $key] { - *-*-ming* - *-*-cygwin - *-*-msys { + *-*-ming* - *-*-cygwin - *-*-msys - *windows* { return 1 } } @@ -626,13 +678,12 @@ proc proj-looks-like-windows {{key host}} { } ######################################################################## +# @proj-looks-like-mac ?key? +# # Looks at either the 'host' (==compilation target platform) or # 'build' (==the being-built-on platform) define value and returns if # if that value seems to indicate that it represents a Mac platform, # else returns 0. -# -# TODO: have someone verify whether this is correct for the -# non-Linux/BSD platforms. proc proj-looks-like-mac {{key host}} { switch -glob -- [get-define $key] { *apple* { @@ -645,6 +696,8 @@ proc proj-looks-like-mac {{key host}} { } ######################################################################## +# @proj-exe-extension +# # Checks autosetup's "host" and "build" defines to see if the build # host and target are Windows-esque (Cygwin, MinGW, MSys). If the # build environment is then BUILD_EXEEXT is [define]'d to ".exe", else @@ -664,14 +717,13 @@ proc proj-exe-extension {} { } ######################################################################## +# @proj-dll-extension +# # Works like proj-exe-extension except that it defines BUILD_DLLEXT # and TARGET_DLLEXT to one of (.so, ,dll, .dylib). # # Trivia: for .dylib files, the linker needs the -dynamiclib flag # instead of -shared. -# -# TODO: have someone verify whether this is correct for the -# non-Linux/BSD platforms. proc proj-dll-extension {} { proc inner {key} { switch -glob -- [get-define $key] { @@ -691,6 +743,8 @@ proc proj-dll-extension {} { } ######################################################################## +# @proj-lib-extension +# # Static-library counterpart of proj-dll-extension. Defines # BUILD_LIBEXT and TARGET_LIBEXT to the conventional static library # extension for the being-built-on resp. the target platform. @@ -710,6 +764,8 @@ proc proj-lib-extension {} { } ######################################################################## +# @proj-file-extensions +# # Calls all of the proj-*-extension functions. proc proj-file-extensions {} { proj-exe-extension @@ -718,6 +774,8 @@ proc proj-file-extensions {} { } ######################################################################## +# @proj-affirm-files-exist ?-v? filename... +# # Expects a list of file names. If any one of them does not exist in # the filesystem, it fails fatally with an informative message. # Returns the last file name it checks. If the first argument is -v @@ -741,32 +799,46 @@ proc proj-affirm-files-exist {args} { } ######################################################################## +# @proj-check-emsdk +# # Emscripten is used for doing in-tree builds of web-based WASM stuff, # as opposed to WASI-based WASM or WASM binaries we import from other # places. This is only set up for Unix-style OSes and is untested -# anywhere but Linux. +# anywhere but Linux. Requires that the --with-emsdk flag be +# registered with autosetup. +# +# It looks for the SDK in the location specified by --with-emsdk. +# Values of "" or "auto" mean to check for the environment var EMSDK +# (which gets set by the emsdk_env.sh script from the SDK) or that +# same var passed to configure. +# +# If the given directory is found, it expects to find emsdk_env.sh in +# that directory, as well as the emcc compiler somewhere under there. +# +# If the --with-emsdk flag is explicitly provided and the SDK is not +# found then a fatal error is generated, otherwise failure to find the +# SDK is not fatal. # # Defines the following: # -# - EMSDK_HOME = top dir of the emsdk or "". It looks for -# --with-emsdk=DIR or the $EMSDK environment variable. -# - EMSDK_ENV = path to EMSDK_HOME/emsdk_env.sh or "" +# - EMSDK_HOME = top dir of the emsdk or "". +# - EMSDK_ENV_SH = path to EMSDK_HOME/emsdk_env.sh or "" # - BIN_EMCC = $EMSDK_HOME/upstream/emscripten/emcc or "" # - HAVE_EMSDK = 0 or 1 (this function's return value) # -# Returns 1 if EMSDK_ENV is found, else 0. If EMSDK_HOME is not empty +# Returns 1 if EMSDK_ENV_SH is found, else 0. If EMSDK_HOME is not empty # but BIN_EMCC is then emcc was not found in the EMSDK_HOME, in which -# case we have to rely on the fact that sourcing $EMSDK_ENV from a +# case we have to rely on the fact that sourcing $EMSDK_ENV_SH from a # shell will add emcc to the $PATH. proc proj-check-emsdk {} { set emsdkHome [opt-val with-emsdk] define EMSDK_HOME "" - define EMSDK_ENV "" + define EMSDK_ENV_SH "" define BIN_EMCC "" + set hadValue [llength $emsdkHome] msg-checking "Emscripten SDK? " - if {$emsdkHome eq ""} { - # Fall back to checking the environment. $EMSDK gets set by - # sourcing emsdk_env.sh. + if {$emsdkHome in {"" "auto"}} { + # Check the environment. $EMSDK gets set by sourcing emsdk_env.sh. set emsdkHome [get-env EMSDK ""] } set rc 0 @@ -775,7 +847,7 @@ proc proj-check-emsdk {} { set emsdkEnv "$emsdkHome/emsdk_env.sh" if {[file exists $emsdkEnv]} { msg-result "$emsdkHome" - define EMSDK_ENV $emsdkEnv + define EMSDK_ENV_SH $emsdkEnv set rc 1 set emcc "$emsdkHome/upstream/emscripten/emcc" if {[file exists $emcc]} { @@ -787,21 +859,37 @@ proc proj-check-emsdk {} { } else { msg-result "not found" } + if {$hadValue && 0 == $rc} { + # Fail if it was explicitly requested but not found + proj-fatal "Cannot find the Emscripten SDK" + } define HAVE_EMSDK $rc return $rc } ######################################################################## +# @proj-check-rpath +# # Tries various approaches to handling the -rpath link-time # flag. Defines LDFLAGS_RPATH to that/those flag(s) or an empty # string. Returns 1 if it finds an option, else 0. # +# By default, the rpath is set to $prefix/lib. However, if either of +# --exec-prefix=... or --libdir=... are explicitly passed to +# configure then [get-define libdir] is used (noting that it derives +# from exec-prefix by default). +# # Achtung: we have seen platforms which report that a given option # checked here will work but then fails at build-time, and the current # order of checks reflects that. proc proj-check-rpath {} { set rc 1 - set lp "[get-define prefix]/lib" + if {[proj-opt-was-provided libdir] + || [proj-opt-was-provided exec-prefix]} { + set lp "[get-define libdir]" + } else { + set lp "[get-define prefix]/lib" + } # If we _don't_ use cc-with {} here (to avoid updating the global # CFLAGS or LIBS or whatever it is that cc-check-flags updates) then # downstream tests may fail because the resulting rpath gets @@ -823,6 +911,31 @@ proc proj-check-rpath {} { return $rc } +######################################################################## +# @proj-check-soname ?libname? +# +# Checks whether CC supports the -Wl,soname,lib... flag. If so, it +# returns 1 and defines LDFLAGS_SONAME_PREFIX to the flag's prefix, to +# which the client would need to append "libwhatever.N". If not, it +# returns 0 and defines LDFLAGS_SONAME_PREFIX to an empty string. +# +# The libname argument is only for purposes of running the flag +# compatibility test, and is not included in the resulting +# LDFLAGS_SONAME_PREFIX. It is provided so that clients may +# potentially avoid some end-user confusion by using their own lib's +# name here (which shows up in the "checking..." output). +proc proj-check-soname {{libname "libfoo.so.0"}} { + cc-with {} { + if {[cc-check-flags "-Wl,-soname,${libname}"]} { + define LDFLAGS_SONAME_PREFIX "-Wl,-soname," + return 1 + } else { + define LDFLAGS_SONAME_PREFIX "" + return 0 + } + } +} + ######################################################################## # Internal helper for proj-dump-defs-json. Expects to be passed a # [define] name and the variadic $args which are passed to @@ -842,7 +955,9 @@ proc proj-defs-type_ {name spec} { ######################################################################## # Internal helper for proj-defs-format_: returns a JSON-ish quoted -# form of the given (JSON) string-type values. +# form of the given string-type values. It only performs the most +# basic of escaping. The input must not contain any control +# characters. proc proj-quote-str_ {value} { return \"[string map [list \\ \\\\ \" \\\"] $value]\" } @@ -939,8 +1054,10 @@ proc proj-dump-defs-json {file args} { } ######################################################################## -# Expects a list of pairs of configure flags with the given names to -# have been registered with autosetup, in this form: +# @proj-xfer-option-aliases map +# +# Expects a list of pairs of configure flags which have been +# registered with autosetup, in this form: # # { alias1 => canonical1 # aliasN => canonicalN ... } @@ -951,7 +1068,7 @@ proc proj-dump-defs-json {file args} { # # Comment lines are permitted in the input. # -# For each pair ALIAS and CANONICAL, if --ALIAS is provided but +# For each pair of ALIAS and CANONICAL, if --ALIAS is provided but # --CANONICAL is not, the value of the former is copied to the # latter. If --ALIAS is not provided, this is a no-op. If both have # explicitly been provided a fatal usage error is triggered. @@ -962,10 +1079,10 @@ proc proj-dump-defs-json {file args} { # --canonical and a user passes --alias=X, [opt-val canonical] returns # no value. i.e. the script must check both [opt-val alias] and # [opt-val canonical]. The intent here is that this function be -# passed such mappings immediately after [options] is called, -# to carry over any values from hidden aliases into their canonical -# names, so that in the above example [opt-value canonical] will -# return X if --alias=X is passed in. +# passed such mappings immediately after [options] is called, to carry +# over any values from hidden aliases into their canonical names, such +# that [opt-value canonical] will return X if --alias=X is passed to +# configure. proc proj-xfer-options-aliases {mapping} { foreach {hidden - canonical} [proj-strip-hash-comments_ $mapping] { if {[proj-opt-was-provided $hidden]} { @@ -993,17 +1110,19 @@ proc proj-xfer-options-aliases {mapping} { # # Sidebar: if we do this before the cc package is installed, it gets # reverted by that package. Ergo, the cc package init will tell the -# user "Build C compiler...cc" shortly before we tell them: +# user "Build C compiler...cc" shortly before we tell them otherwise. proc proj-redefine-cc-for-build {} { if {![proj-is-cross-compiling] - && "nope" eq [get-env CC_FOR_BUILD "nope"] - && [get-define CC] ne [get-define CC_FOR_BUILD]} { + && [get-define CC] ne [get-define CC_FOR_BUILD] + && "nope" eq [get-env CC_FOR_BUILD "nope"]} { user-notice "Re-defining CC_FOR_BUILD to CC=[get-define CC]. To avoid this, explicitly pass CC_FOR_BUILD=..." define CC_FOR_BUILD [get-define CC] } } ######################################################################## +# @proj-which-linenoise headerFile +# # Attempts to determine whether the given linenoise header file is of # the "antirez" or "msteveb" flavor. It returns 2 for msteveb, else 1 # (it does not validate that the header otherwise contains the @@ -1016,3 +1135,105 @@ proc proj-which-linenoise {dotH} { return 1 } } + +######################################################################## +# @proj-remap-autoconf-dir-vars +# +# "Re-map" the autoconf-conventional --XYZdir flags into something +# which is more easily overridable from a make invocation. +# +# Based off of notes in . +# +# Consider: +# +# $ ./configure --prefix=/foo +# $ make install prefix=/blah +# +# In that make invocation, $(libdir) would, at make-time, normally be +# hard-coded to /foo/lib, rather than /blah/lib. That happens because +# the autosetup exports conventional $prefix-based values for the +# numerious autoconfig-compatible XYZdir vars at configure-time. What +# we would normally want, however, is that --libdir derives from the +# make-time $(prefix). The distinction between configure-time and +# make-time is the significant factor there. +# +# This function attempts to reconcile those vars in such a way that +# they will derive, at make-time, from $(prefix) in a conventional +# manner unless they are explicitly overridden at configure-time, in +# which case those overrides takes precedence. +# +# Each --XYZdir flag which is explicitly passed to configure is +# exported as-is, as are those which default to some top-level system +# directory, e.g. /etc or /var. All which derive from either $prefix +# or $exec_prefix are exported in the form of a Makefile var +# reference, e.g. libdir=${exec_prefix}/lib. Ergo, if +# --exec-prefix=FOO is passed to configure, libdir will still derive, +# at make-time, from whatever exec_prefix is passed to make, and will +# use FOO if exec_prefix is not overridden. Without this +# post-processing, libdir would be cemented in as FOO/lib at +# configure-time, so would be tedious to override properly via a make +# invocation. +# +proc proj-remap-autoconf-dir-vars {} { + set prefix [get-define prefix] + set exec_prefix [get-define exec_prefix $prefix] + # Note that the ${...} here refers to make-side var derefs, not + # TCL-side vars. They must be formulated such that they are legal + # for use in (A) makefiles, (B) pkgconfig files, and (C) TCL's + # [subst] command. i.e. they must use the form ${X}. + foreach {flag makeVar makeDeref} { + exec-prefix exec_prefix ${prefix} + datadir datadir ${prefix}/share + mandir mandir ${datadir}/man + includedir includedir ${prefix}/include + bindir bindir ${exec_prefix}/bin + libdir libdir ${exec_prefix}/lib + sbindir sbindir ${exec_prefix}/sbin + sysconfdir sysconfdir /etc + sharedstatedir sharedstatedir ${prefix}/com + localstatedir localstatedir /var + runstatedir runstatedir /run + infodir infodir ${datadir}/info + libexecdir libexecdir ${exec_prefix}/libexec + } { + if {[proj-opt-was-provided $flag]} { + define $makeVar [join [opt-val $flag]] + } else { + define $makeVar [join $makeDeref] + } + # Maintenance reminder: the [join] call is to avoid {braces} + # around the output when someone passes in, + # e.g. --libdir=\${prefix}/foo/bar. The Debian package build + # script does that. + } +} + +######################################################################## +# @proj-env-file flag ?default? +# +# If a file named .env-$flag exists, this function returns a +# trimmed copy of its contents, else it returns $dflt. The intended +# usage is that things like developer-specific CFLAGS preferences can +# be stored in .env-CFLAGS. +proc proj-env-file {flag {dflt ""}} { + set fn ".env-${flag}" + if {[file readable $fn]} { + return [proj-file-content -trim $fn] + } + return $dflt +} + +######################################################################## +# @proj-get-env var ?default? +# +# Extracts the value of "environment" variable $var from the first of +# the following places where it's defined: +# +# - Passed to configure as $var=... +# - Exists as an environment variable +# - A file named .env-$var (see [proj-env-file]) +# +# If none of those are set, $dflt is returned. +proc proj-get-env {var {dflt ""}} { + return [get-env $var [proj-env-file $var $dflt]] +} diff --git a/autosetup/system.tcl b/autosetup/system.tcl index f23781b5da..05d378afdd 100644 --- a/autosetup/system.tcl +++ b/autosetup/system.tcl @@ -55,6 +55,8 @@ options { program-prefix: program-suffix: program-transform-name: + x-includes: + x-libraries: } # @check-feature name { script } @@ -318,95 +320,101 @@ proc make-template {template {out {}}} { } } -# build/host tuples and cross-compilation prefix -opt-str build build "" -define build_alias $build -if {$build eq ""} { - define build [config_guess] -} else { - define build [config_sub $build] -} +proc system-init {} { + global autosetup -opt-str host host "" -define host_alias $host -if {$host eq ""} { - define host [get-define build] - set cross "" -} else { - define host [config_sub $host] - set cross $host- -} -define cross [get-env CROSS $cross] - -# build/host _cpu, _vendor and _os -foreach type {build host} { - set v [get-define $type] - if {![regexp {^([^-]+)-([^-]+)-(.*)$} $v -> cpu vendor os]} { - user-error "Invalid canonical $type: $v" + # build/host tuples and cross-compilation prefix + opt-str build build "" + define build_alias $build + if {$build eq ""} { + define build [config_guess] + } else { + define build [config_sub $build] } - define ${type}_cpu $cpu - define ${type}_vendor $vendor - define ${type}_os $os -} -opt-str prefix prefix /usr/local - -# These are for compatibility with autoconf -define target [get-define host] -define prefix $prefix -define builddir $autosetup(builddir) -define srcdir $autosetup(srcdir) -define top_srcdir $autosetup(srcdir) -define abs_top_srcdir [file-normalize $autosetup(srcdir)] -define abs_top_builddir [file-normalize $autosetup(builddir)] - -# autoconf supports all of these -define exec_prefix [opt-str exec-prefix exec_prefix $prefix] -foreach {name defpath} { - bindir /bin - sbindir /sbin - libexecdir /libexec - libdir /lib -} { - define $name [opt-str $name o $exec_prefix$defpath] -} -foreach {name defpath} { - datadir /share - sharedstatedir /com - infodir /share/info - mandir /share/man - includedir /include -} { - define $name [opt-str $name o $prefix$defpath] -} -if {$prefix ne {/usr}} { - opt-str sysconfdir sysconfdir $prefix/etc -} else { - opt-str sysconfdir sysconfdir /etc -} -define sysconfdir $sysconfdir - -define localstatedir [opt-str localstatedir o /var] -define runstatedir [opt-str runstatedir o /run] - -define SHELL [get-env SHELL [find-an-executable sh bash ksh]] - -# These could be used to generate Makefiles following some automake conventions -define AM_SILENT_RULES [opt-bool silent-rules] -define AM_MAINTAINER_MODE [opt-bool maintainer-mode] -define AM_DEPENDENCY_TRACKING [opt-bool dependency-tracking] - -# Windows vs. non-Windows -switch -glob -- [get-define host] { - *-*-ming* - *-*-cygwin - *-*-msys { - define-feature windows - define EXEEXT .exe + opt-str host host "" + define host_alias $host + if {$host eq ""} { + define host [get-define build] + set cross "" + } else { + define host [config_sub $host] + set cross $host- } - default { - define EXEEXT "" + define cross [get-env CROSS $cross] + + # build/host _cpu, _vendor and _os + foreach type {build host} { + set v [get-define $type] + if {![regexp {^([^-]+)-([^-]+)-(.*)$} $v -> cpu vendor os]} { + user-error "Invalid canonical $type: $v" + } + define ${type}_cpu $cpu + define ${type}_vendor $vendor + define ${type}_os $os } + + opt-str prefix prefix /usr/local + + # These are for compatibility with autoconf + define target [get-define host] + define prefix $prefix + define builddir $autosetup(builddir) + define srcdir $autosetup(srcdir) + define top_srcdir $autosetup(srcdir) + define abs_top_srcdir [file-normalize $autosetup(srcdir)] + define abs_top_builddir [file-normalize $autosetup(builddir)] + + # autoconf supports all of these + define exec_prefix [opt-str exec-prefix exec_prefix $prefix] + foreach {name defpath} { + bindir /bin + sbindir /sbin + libexecdir /libexec + libdir /lib + } { + define $name [opt-str $name o $exec_prefix$defpath] + } + foreach {name defpath} { + datadir /share + sharedstatedir /com + infodir /share/info + mandir /share/man + includedir /include + } { + define $name [opt-str $name o $prefix$defpath] + } + if {$prefix ne {/usr}} { + opt-str sysconfdir sysconfdir $prefix/etc + } else { + opt-str sysconfdir sysconfdir /etc + } + define sysconfdir $sysconfdir + + define localstatedir [opt-str localstatedir o /var] + define runstatedir [opt-str runstatedir o /run] + + define SHELL [get-env SHELL [find-an-executable sh bash ksh]] + + # These could be used to generate Makefiles following some automake conventions + define AM_SILENT_RULES [opt-bool silent-rules] + define AM_MAINTAINER_MODE [opt-bool maintainer-mode] + define AM_DEPENDENCY_TRACKING [opt-bool dependency-tracking] + + # Windows vs. non-Windows + switch -glob -- [get-define host] { + *-*-ming* - *-*-cygwin - *-*-msys { + define-feature windows + define EXEEXT .exe + } + default { + define EXEEXT "" + } + } + + # Display + msg-result "Host System...[get-define host]" + msg-result "Build System...[get-define build]" } -# Display -msg-result "Host System...[get-define host]" -msg-result "Build System...[get-define build]" +system-init diff --git a/ext/fts5/fts5_tcl.c b/ext/fts5/fts5_tcl.c index dd2ed82c9e..247b4f0e90 100644 --- a/ext/fts5/fts5_tcl.c +++ b/ext/fts5/fts5_tcl.c @@ -1642,7 +1642,7 @@ void f5tStrFunc(sqlite3_context *pCtx, int nArg, sqlite3_value **apArg){ const char *zText = 0; assert( nArg==1 ); - zText = sqlite3_value_text(apArg[0]); + zText = (const char*)sqlite3_value_text(apArg[0]); if( zText ){ sqlite3_int64 nText = strlen(zText); char *zCopy = (char*)ckalloc(nText+8); @@ -1670,7 +1670,6 @@ static int SQLITE_TCLAPI f5tRegisterStr( Tcl_Obj *CONST objv[] ){ sqlite3 *db = 0; - int rc; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "DB"); diff --git a/ext/icu/icu.c b/ext/icu/icu.c index 69867bfa83..50110072b5 100644 --- a/ext/icu/icu.c +++ b/ext/icu/icu.c @@ -571,7 +571,7 @@ int sqlite3IcuInit(sqlite3 *db){ return rc; } -#if !SQLITE_CORE +#ifndef SQLITE_CORE #ifdef _WIN32 __declspec(dllexport) #endif diff --git a/ext/misc/percentile.c b/ext/misc/percentile.c index 1c6191d42e..06865185df 100644 --- a/ext/misc/percentile.c +++ b/ext/misc/percentile.c @@ -484,10 +484,10 @@ int sqlite3_percentile_init( ){ int rc = SQLITE_OK; unsigned int i; -#if defined(SQLITE3_H) || defined(SQLITE_STATIC_PERCENTILE) - (void)pApi; /* Unused parameter */ -#else +#ifdef SQLITE3EXT_H SQLITE_EXTENSION_INIT2(pApi); +#else + (void)pApi; /* Unused parameter */ #endif (void)pzErrMsg; /* Unused parameter */ for(i=0; iiColumniColumn==SERIES_COLUMN_VALUE ){ + if( pConstraint->iColumn==SERIES_COLUMN_VALUE && pConstraint->usable ){ switch( op ){ case SQLITE_INDEX_CONSTRAINT_EQ: case SQLITE_INDEX_CONSTRAINT_IS: { diff --git a/ext/misc/sqlite3_stdio.c b/ext/misc/sqlite3_stdio.c index 5bb26084c2..729504629b 100644 --- a/ext/misc/sqlite3_stdio.c +++ b/ext/misc/sqlite3_stdio.c @@ -96,8 +96,8 @@ FILE *sqlite3_fopen(const char *zFilename, const char *zMode){ sz1 = (int)strlen(zFilename); sz2 = (int)strlen(zMode); - b1 = malloc( (sz1+1)*sizeof(b1[0]) ); - b2 = malloc( (sz2+1)*sizeof(b1[0]) ); + b1 = sqlite3_malloc( (sz1+1)*sizeof(b1[0]) ); + b2 = sqlite3_malloc( (sz2+1)*sizeof(b1[0]) ); if( b1 && b2 ){ sz1 = MultiByteToWideChar(CP_UTF8, 0, zFilename, sz1, b1, sz1); b1[sz1] = 0; @@ -105,8 +105,8 @@ FILE *sqlite3_fopen(const char *zFilename, const char *zMode){ b2[sz2] = 0; fp = _wfopen(b1, b2); } - free(b1); - free(b2); + sqlite3_free(b1); + sqlite3_free(b2); simBinaryOther = 0; return fp; } @@ -122,8 +122,8 @@ FILE *sqlite3_popen(const char *zCommand, const char *zMode){ sz1 = (int)strlen(zCommand); sz2 = (int)strlen(zMode); - b1 = malloc( (sz1+1)*sizeof(b1[0]) ); - b2 = malloc( (sz2+1)*sizeof(b1[0]) ); + b1 = sqlite3_malloc( (sz1+1)*sizeof(b1[0]) ); + b2 = sqlite3_malloc( (sz2+1)*sizeof(b1[0]) ); if( b1 && b2 ){ sz1 = MultiByteToWideChar(CP_UTF8, 0, zCommand, sz1, b1, sz1); b1[sz1] = 0; @@ -131,8 +131,8 @@ FILE *sqlite3_popen(const char *zCommand, const char *zMode){ b2[sz2] = 0; fp = _wpopen(b1, b2); } - free(b1); - free(b2); + sqlite3_free(b1); + sqlite3_free(b2); return fp; } @@ -146,7 +146,7 @@ char *sqlite3_fgets(char *buf, int sz, FILE *in){ ** that into UTF-8. Otherwise, non-ASCII characters all get translated ** into '?'. */ - wchar_t *b1 = malloc( sz*sizeof(wchar_t) ); + wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) ); if( b1==0 ) return 0; _setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT); if( fgetws(b1, sz/4, in)==0 ){ @@ -212,7 +212,7 @@ int sqlite3_fputs(const char *z, FILE *out){ ** use O_U8TEXT for everything in text mode. */ int sz = (int)strlen(z); - wchar_t *b1 = malloc( (sz+1)*sizeof(wchar_t) ); + wchar_t *b1 = sqlite3_malloc( (sz+1)*sizeof(wchar_t) ); if( b1==0 ) return 0; sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz); b1[sz] = 0; diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 299b5b54b9..6efa20d162 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -4449,7 +4449,7 @@ int sqlite3_rtree_query_callback( ); } -#if !SQLITE_CORE +#ifndef SQLITE_CORE #ifdef _WIN32 __declspec(dllexport) #endif diff --git a/ext/rtree/rtreecheck.test b/ext/rtree/rtreecheck.test index 7a98f9bf4e..d2c521cb8f 100644 --- a/ext/rtree/rtreecheck.test +++ b/ext/rtree/rtreecheck.test @@ -198,7 +198,7 @@ if {[permutation]=="inmemory_journal"} { } else { do_catchsql_test 6.1 { SELECT ( 'elvis' IN(SELECT rtreecheck('t1')) ) FROM (SELECT 1) GROUP BY 1; - } {1 {database table is locked}} + } {0 0} } finish_test diff --git a/ext/session/sessionblob.test b/ext/session/sessionblob.test new file mode 100644 index 0000000000..ed7ec67b48 --- /dev/null +++ b/ext/session/sessionblob.test @@ -0,0 +1,55 @@ +# 2024 November 04 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +if {$::tcl_platform(pointerSize)<8} { + finish_test + return +} + +set testprefix sessionblob + +forcedelete test.db2 +sqlite3 db2 test.db2 + +set NBLOB 2000000 + +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + INSERT INTO t1 VALUES(123, zeroblob($NBLOB)); +} + +do_test 1.1 { + sqlite3session S db main + S attach t1 +} {} + +set b2 [string repeat x 1000] +do_test 1.2 { + set ::blob [db incrblob t1 b 123] + for {set ii 0} {$ii < $NBLOB} {incr ii [string length $b2]} { + seek $::blob $ii + puts -nonewline $::blob $b2 + } + close $::blob +} {} + +S delete + +finish_test + diff --git a/ext/wasm/fiddle.make b/ext/wasm/fiddle.make index df5c7ab7b7..2a43959e2b 100644 --- a/ext/wasm/fiddle.make +++ b/ext/wasm/fiddle.make @@ -46,6 +46,8 @@ fiddle.emcc-flags = \ $(SQLITE_OPT.full-featured) \ $(SQLITE_OPT.common) \ $(SHELL_OPT) \ + -UHAVE_READLINE -UHAVE_EDITLINE -UHAVE_LINENOISE \ + -USQLITE_HAVE_ZLIB \ -USQLITE_WASM_BARE_BONES \ -DSQLITE_SHELL_FIDDLE diff --git a/main.mk b/main.mk index 47806990e9..d4cfb3b5e7 100644 --- a/main.mk +++ b/main.mk @@ -119,14 +119,32 @@ JIMSH ?= ./jimsh$(T.exe) B.tclsh ?= $(JIMSH) # -# Various system-level directories, mostly needed for installation and -# for finding system-level dependencies. +# Autotools-conventional vars which are (in this tree) used only by +# package installation rules. # -# Aside from ${prefix}, we do not need to (and intentionally do not) -# export any of the dozen-ish shorthand ${XYZdir} vars the autotools -# conventionally defines. +# The following ${XYZdir} vars are provided for the sake of clients +# who expect to be able to override these using autotools-conventional +# dir name vars. In this build they apply only to installation-related +# rules. # -prefix ?= /usr/local +prefix ?= /usr/local +datadir ?= $(prefix)/share +mandir ?= $(datadir)/man +includedir ?= $(prefix)/include +exec_prefix ?= $(prefix) +bindir ?= $(exec_prefix)/bin +libdir ?= $(exec_prefix)/lib +# This makefile does not use any of: +# sbindir ?= $(exec_prefix)/sbin +# sysconfdir ?= /etc +# sharedstatedir ?= $(prefix)/com +# localstatedir ?= /var +# runstatedir ?= /run +# infodir ?= $(datadir)/info +# libexecdir ?= $(exec_prefix)/libexec +### end of autotools-compatible install dir vars + + # # $(LDFLAGS.{feature}) and $(CFLAGS.{feature}) = # @@ -144,10 +162,11 @@ LDFLAGS.pthread ?= -lpthread LDFLAGS.dlopen ?= -ldl LDFLAGS.shobj ?= -shared LDFLAGS.icu ?= # -licui18n -licuuc -licudata +LDFLAGS.soname.libsqlite3 ?= # libreadline (or a workalike): # To activate readline in the shell: SHELL_OPT = -DHAVE_READLINE=1 -LDFLAGS.readline ?= -lreadline # these vary wildly across platforms -CFLAGS.readline ?= -I$(prefix)/include/readline +LDFLAGS.readline ?= -lreadline # these vary across platforms +CFLAGS.readline ?= -I$(prefix)/include # ^^^ When using linenoise instead of readline, do something like: # SHELL_OPT += -DHAVE_LINENOISE=1 # CFLAGS.readline = -I$(HOME)/linenoise $(HOME)/linenoise/linenoise.c @@ -355,11 +374,11 @@ LDFLAGS.libsqlite3 = \ # moral of this story is that spaces in installation paths will break # the install process. # -install-dir.bin = $(DESTDIR)$(prefix)/bin -install-dir.lib = $(DESTDIR)$(prefix)/lib -install-dir.include = $(DESTDIR)$(prefix)/include -install-dir.pkgconfig = $(DESTDIR)$(prefix)/lib/pkgconfig -install-dir.man1 = $(DESTDIR)$(prefix)/share/man/man1 +install-dir.bin = $(DESTDIR)$(bindir) +install-dir.lib = $(DESTDIR)$(libdir) +install-dir.include = $(DESTDIR)$(includedir) +install-dir.pkgconfig = $(DESTDIR)$(libdir)/pkgconfig +install-dir.man1 = $(DESTDIR)$(mandir)/man1 install-dir.all = $(install-dir.bin) $(install-dir.include) \ $(install-dir.lib) $(install-dir.man1) \ $(install-dir.pkgconfig) @@ -1332,7 +1351,7 @@ all: lib # Dynamic libsqlite3 # $(libsqlite3.SO): $(LIBOBJ) - $(T.link.shared) -o $@ $(LIBOBJ) $(LDFLAGS.libsqlite3) + $(T.link.shared) -o $@ $(LIBOBJ) $(LDFLAGS.soname.libsqlite3) $(LDFLAGS.libsqlite3) $(libsqlite3.SO)-1: $(libsqlite3.SO) $(libsqlite3.SO)-0 $(libsqlite3.SO)-: so: $(libsqlite3.SO)-$(ENABLE_SHARED) @@ -1346,6 +1365,38 @@ all: so # - libsqlite3.so.3 =symlink-> libsqlite3.so.$(PACKAGE_VERSION) # - libsqlite3.so =symlink-> libsqlite3.so.3 # +# Regarding the historcal installation name of libsqlite3.so.0.8.6: +# +# Historically libtool installed the library like so: +# +# libsqlite3.so -> libsqlite3.so.0.8.6 +# libsqlite3.so.0 -> libsqlite3.so.0.8.6 +# libsqlite3.so.0.8.6 +# +# The historical SQLite build always used a version number of 0.8.6 +# for reasons lost to history but having something to do with libtool +# (which is no longer used in this tree). In order to retain filename +# compatibility for systems which have libraries installed using those +# conventions: +# +# 1) If libsqlite3.so.0 is found in the target installation directory +# then it and libsqlite3.so.0.8.6 are re-linked to point to the +# newer-style names. We cannot retain both the old and new +# installation because they both share the high-level name +# $(libsqlite3.SO). The down-side of this is that it may well upset +# packaging tools when we replace libsqlite3.so (from a legacy +# package) with a new symlink. +# +# 2) If INSTALL_SO_086_LINKS=1 and point (1) does not apply then links +# to the legacy-style names are created. The primary intent of this +# is to enable chains of operations such as the hypothetical (apt +# remove sqlite3-3.47.0 && apt install sqlite3-3.48.0). In such +# cases, condition (1) would never trigger but applications might +# still expect to see the legacy file names. +# +# In either case, libsqlite3.la, if found, is deleted because it would +# contain stale state, refering to non-libtool-generated libraries. +# install-so-1: $(install-dir.lib) $(libsqlite3.SO) $(INSTALL) $(libsqlite3.SO) "$(install-dir.lib)" @echo "Setting up SO symlinks..."; \ @@ -1354,7 +1405,20 @@ install-so-1: $(install-dir.lib) $(libsqlite3.SO) mv $(libsqlite3.SO) $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \ ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).3 || exit $$?; \ ln -s $(libsqlite3.SO).3 $(libsqlite3.SO) || exit $$?; \ - ls -la $(libsqlite3.SO) $(libsqlite3.SO).3* + ls -la $(libsqlite3.SO) $(libsqlite3.SO).3*; \ + if [ -e $(libsqlite3.SO).0 ]; then \ + echo "ACHTUNG: legacy libtool-compatible install found. Re-linking it..."; \ + rm -f libsqlite3.la $(libsqlite3.SO).0* || exit $$?; \ + ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0 || exit $$?; \ + ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \ + ls -la $(libsqlite3.SO).0*; \ + elif [ x1 = "x$(INSTALL_SO_086_LINKS)" ]; then \ + echo "ACHTUNG: installing legacy libtool-style links because INSTALL_SO_086_LINKS=1"; \ + rm -f libsqlite3.la $(libsqlite3.SO).0* || exit $$?; \ + ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0 || exit $$?; \ + ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \ + ls -la $(libsqlite3.SO).0*; \ + fi install-so-0 install-so-: install-so: install-so-$(ENABLE_SHARED) install: install-so @@ -1705,9 +1769,9 @@ rollback-test$(T.exe): $(TOP)/tool/rollback-test.c sqlite3.o $(T.link) -o $@ $(TOP)/tool/rollback-test.c sqlite3.o $(LDFLAGS.libsqlite3) xbin: rollback-test$(T.exe) -atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.o +atrc$(T.exe): $(TOP)/test/atrc.c sqlite3.o $(T.link) -o $@ $(TOP)/test/atrc.c sqlite3.o $(LDFLAGS.libsqlite3) -xbin: atrc$(TEXX) +xbin: atrc$(T.exe) LogEst$(T.exe): $(TOP)/tool/logest.c sqlite3.h $(T.link) -I. -o $@ $(TOP)/tool/logest.c @@ -1731,9 +1795,12 @@ kvtest$(T.exe): $(TOP)/test/kvtest.c sqlite3.c $(T.link) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(LDFLAGS.libsqlite3) xbin: kvtest$(T.exe) -#rbu$(T.exe): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o -# $(T.link) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.o $(LDFLAGS.libsqlite3) -#xbin: rbu$(T.exe) +# +# rbu$(T.exe) requires building with -DSQLITE_ENABLE_RBU, which +# specifically does not have an --enable-rbu flag in the configure +# script. +rbu$(T.exe): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o + $(T.link) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.o $(LDFLAGS.libsqlite3) loadfts$(T.exe): $(TOP)/tool/loadfts.c $(libsqlite3.LIB) $(T.link) $(TOP)/tool/loadfts.c $(libsqlite3.LIB) -o $@ $(LDFLAGS.libsqlite3) @@ -1768,20 +1835,9 @@ tool-zip: testfixture$(T.exe) sqlite3$(T.exe) sqldiff$(T.exe) \ clean-tool-zip: rm -f sqlite-tools-*.zip clean: clean-tool-zip -#XX# TODO: adapt the autoconf amalgamation for autosetup -#XX# -#XX## Build the amalgamation-autoconf package. The amalamgation-tarball target builds -#XX## a tarball named for the version number. Ex: sqlite-autoconf-3110000.tar.gz. -#XX## The snapshot-tarball target builds a tarball named by the SHA1 hash -#XX## -#XX#amalgamation-tarball: sqlite3.c sqlite3rc.h -#XX# TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --normal -#XX# -#XX#snapshot-tarball: sqlite3.c sqlite3rc.h -#XX# TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot -#XX# -# The next two rules are used to support the "threadtest" target. Building +# +# The next few rules are used to support the "threadtest" target. Building # threadtest runs a few thread-safety tests that are implemented in C. This # target is invoked by the releasetest.tcl script. # @@ -1817,8 +1873,8 @@ sqlite3$(T.exe)-1: sqlite3$(T.exe)-0 sqlite3$(T.exe)-: sqlite3$(T.exe) all: sqlite3$(T.exe)-$(HAVE_WASI_SDK) -install-shell-0: sqlite3$(TEXT) $(install-dir.bin) - $(INSTALL) -s sqlite3$(TEXT) "$(install-dir.bin)" +install-shell-0: sqlite3$(T.exe) $(install-dir.bin) + $(INSTALL) -s sqlite3$(T.exe) "$(install-dir.bin)" install-shell-1 install-shell-: install: install-shell-$(HAVE_WASI_SDK) @@ -1826,7 +1882,7 @@ sqldiff$(T.exe): $(TOP)/tool/sqldiff.c $(TOP)/ext/misc/sqlite3_stdio.h sqlite3.o $(T.link) -o $@ $(TOP)/tool/sqldiff.c sqlite3.o $(LDFLAGS.libsqlite3) install-diff: sqldiff$(T.exe) $(install-dir.bin) - $(INSTALL) -s sqldiff$(TEXT) "$(install-dir.bin)" + $(INSTALL) -s sqldiff$(T.exe) "$(install-dir.bin)" #install: install-diff dbhash$(T.exe): $(TOP)/tool/dbhash.c sqlite3.o sqlite3.h @@ -1849,7 +1905,7 @@ sqlite3_rsync$(T.exe): $(RSYNC_SRC) xbin: sqlite3_rsync$(T.exe) install-rsync: sqlite3_rsync$(T.exe) $(install-dir.bin) - $(INSTALL) sqlite3_rsync$(TEXT) "$(install-dir.bin)" + $(INSTALL) sqlite3_rsync$(T.exe) "$(install-dir.bin)" #install: install-rsync install-man1: $(install-dir.man1) diff --git a/manifest b/manifest index d34164b757..69261eb226 100644 --- a/manifest +++ b/manifest @@ -1,9 +1,9 @@ -C Add\stests\sfor\sxInstToken()\sand\sprefix\squeries\swith\svarious\sfts5\sconfigurations. -D 2024-11-06T16:20:16.715 +C Merge\slatest\strunk\schanges\sinto\sthis\sbranch. +D 2024-11-06T17:31:48.766 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea -F LICENSE.md c5b4009dca54d127d2d6033c22fd9cc34f53bedb6ef12c7cbaa468381c74ab28 -F Makefile.in 3a98abc984222a31c8597a0cd516c8dd9b72554d784a87c915d2e586db4ddb18 +F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d +F Makefile.in 3a54957d16c3f4666922f170a19b4b51dc13be039c29394dd38caa95ade5d731 F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0 F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312 F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159 @@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 -F auto.def 9cf971c8877aa7b999c3b3b41fe802feea49a50ea98afc0f9964cfc5cc69057b +F auto.def 05eedbf203a070fc84d9d26071f7ddf2a30f2118ab0204db46e91dbfec8a50b8 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac @@ -37,20 +37,21 @@ F autoconf/tea/win/rules.vc 94a18c3e453535459b4a643983acca52fb8756e79055bd2ad4b0 F autoconf/tea/win/targets.vc 96a25a1fa6e9e9cfb348fd3760a5395b4ce8acafc8ed10f0412937ec200d5dbd F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4 F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e +F autosetup/README.md 78f434bc13029a7ddf4d62fb0c82216f1dceaee448239022a1ce49230925b4c9 F autosetup/autosetup 9416ffdcdd6e2dbf7f6d1e5c890078518930f8af7722a950eacc28c7f151d2d6 x F autosetup/autosetup-config.guess dfa101c5e8220e864d5e9c72a85e87110df60260d36cb951ad0a85d6d9eaa463 x F autosetup/autosetup-config.sub a38fb074d0dece01cf919e9fb534a26011608aa8fa606490864295328526cd73 x -F autosetup/autosetup-find-tclsh 38dc4ac03c061d5ee53ecd1ec2fc3d5f0bbf4e84a7123d3160e01d26b5858f36 x +F autosetup/autosetup-find-tclsh 25905f6c302959db80c2951aa267b4411c5645b598ce761cfc24a166141e2c4c x F autosetup/autosetup-test-tclsh 749d20defee533a3842139df47d700fc7a334a5da7bdbd444ae5331744b06c5f F autosetup/cc-db.tcl 6e0ed90146197a5a05b245e649975c07c548e30926b218ca3e1d4dc034b10a7b F autosetup/cc-lib.tcl 493c5935b5dd3bf9bd4eca89b07c8b1b1a9356d61783035144e21795facf7360 F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1de1e5460d78 -F autosetup/cc.tcl 7e2fe943ae9d45cf39e9f5b05b6230df8e719415edea5af06c30eb68680bde14 +F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e45f F autosetup/default.auto 5cdf016de2140e50f1db190a02039dc42fb390af1dda4cc4853e3042a9ef0e82 -F autosetup/jimsh0.c 27ea5f221359ef6c58780fc6c185aadbf8d3bee9a021331a3e5de0eba0dc6de6 +F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14 F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba -F autosetup/proj.tcl 68362ca12e1a32fe73ece32b59a8e8e02a3983295f2dd82c9c4700507bade02c -F autosetup/system.tcl 3a39d6e0b3bfba526fd39afe07c1d0d325e5a31925013a1ba7c671e1128e31bb +F autosetup/proj.tcl 504fb46e15a0c6b4b161484a0a24f62b9c165fb901d189c0e523d9a93f1b24c2 +F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9 F autosetup/tmake.auto eaebc74ad538dfdd3c817c27eefc31930c20510c4f3a3704071f6cb0629ed71f F autosetup/tmake.tcl a275793ec1b6f8708179af0acef1f6f10d46c2920739743f7a8720c6d700c7a9 F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x @@ -115,7 +116,7 @@ F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a F ext/fts5/fts5_index.c 2cef40d6fdd761229dd4127e0b1ddcb61dfd6a4ac7e73653b7fddbe0075e50be F ext/fts5/fts5_main.c b2ec6bf97fc378906c0e78c61f10ca8e64f15e03237f2521f7d81736983be378 F ext/fts5/fts5_storage.c 337b05e4c66fc822d031e264d65bde807ec2fab08665ca2cc8aaf9c5fa06792c -F ext/fts5/fts5_tcl.c 5b16a249962809b2aaaab964bf58838ea72f30b8b12373cafe612f8cc71e2a40 +F ext/fts5/fts5_tcl.c aee6ae6d0c6968564c392bf0d09aaabb4d8bea9ca69fd224dc9b44243324acbf F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b F ext/fts5/fts5_tokenize.c 033e2e43b8e852c0ef6cecc611266d61e2346e52ec7dcfb76a428fe56a07efa9 @@ -273,7 +274,7 @@ F ext/fts5/tool/loadfts5.tcl 95b03429ee6b138645703c6ca192c3ac96eaf093 F ext/fts5/tool/mkfts5c.tcl 135b9e160f8e10211c10c5873d5e8c3eaebd3da9ec56a12ae4db157d4738ffe4 F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9 -F ext/icu/icu.c 3add8197e0a86c1761771a39500ebae749438bcf1836160b407a56b4eaa8721c +F ext/icu/icu.c 9837f4611915baad1edbe38222f3ee7d1b5e118ab16fec9ba603720f72c78b2a F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8 F ext/intck/intck1.test f3a3cba14b6aeff145ffa5515546dd22f7510dad91512e519f43b92b56514012 F ext/intck/intck2.test d2457c7e5e5b688046d15ebe08a1e1427cc5e7a6dc8d6af215f42e8bcaf67304 @@ -428,7 +429,7 @@ F ext/misc/nextchar.c 7877914c2a80c2f181dd04c3dbef550dfb54c93495dc03da2403b5dd58 F ext/misc/noop.c f1a21cc9b7a4e667e5c8458d80ba680b8bd4315a003f256006046879f679c5a0 F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d09ea61f F ext/misc/pcachetrace.c f4227ce03fb16aa8d6f321b72dd051097419d7a028a9853af048bee7645cb405 -F ext/misc/percentile.c 42eb041edab407e512aaa087f99ed9287fe0b3224f7a6d194456c00fc1454312 +F ext/misc/percentile.c 82531c62cd015b9cdca95ad6bb10c3a907ceb570d21ebd4fb7d634c809cfb089 F ext/misc/prefixes.c 82645f79229877afab08c8b08ca1e7fa31921280906b90a61c294e4f540cd2a6 F ext/misc/qpvtab.c fc189e127f68f791af90a487f4460ec91539a716daf45a0c357e963fd47cc06c F ext/misc/randomjson.c ef835fc64289e76ac4873b85fe12f9463a036168d7683cf2b773e36e6262c4ed @@ -436,13 +437,13 @@ F ext/misc/regexp.c 4bdd0045912f81c84908bd535ec5ad3b1c8540b4287c70ab840709636240 F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 -F ext/misc/series.c ea604a16f9c5f7e09ccff3f18d94f2c3a6fa24ca08856156823d981873b8143c +F ext/misc/series.c cbdda2e2eb8159a1331974d246984c6e2693c6ea93930e6165046c8dbb8db0e9 F ext/misc/sha1.c cb5002148c2661b5946f34561701e9105e9d339b713ec8ac057fd888b196dcb9 F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b430e8c F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 F ext/misc/spellfix.c bcc42ef3fd29429bc01a83e751332b8d4690e65d45008449bdffe7656371487f F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634 -F ext/misc/sqlite3_stdio.c 73192f75e1e89722fbdf209056a562ca2a35df3c9e998f9270331e03cb621e7a +F ext/misc/sqlite3_stdio.c c34b4aba8aec6c1ca7058a7a6319a37ab629135091600aee202390a8cd20e842 F ext/misc/sqlite3_stdio.h f05eaf5e0258f0573910324a789a9586fc360a57678c57a6d63cfaa2245b6176 F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321 F ext/misc/stmtrand.c 59cffa5d8e158943ff1ce078956d8e208e8c04e67307e8f249dece2436dcb7fc @@ -537,7 +538,7 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c3350 F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 F ext/rtree/geopoly.c 0dd4775e896cee6067979d67aff7c998e75c2c9d9cd8d62a1a790c09cde7adca -F ext/rtree/rtree.c b6133dba5ae331fa6c1fc34df6aa623eba951b05ac35116f954a0bf7ab550436 +F ext/rtree/rtree.c e002d8c58bf128d812db662ecc72b61c00ff14408ec807e103d5312a6d29817a F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412 F ext/rtree/rtree1.test e0608db762b2aadca0ecb6f97396cf66244490adc3ba88f2a292b27be3e1da3e F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d @@ -560,7 +561,7 @@ F ext/rtree/rtreeI.test 608e77f7fde9be5a12eae316baef640fffaafcfa90a3d67443e78123 F ext/rtree/rtreeJ.test 93227ccd4d6c328f5ac46a902b8880041509dd2d68f6ce71560f0d8ab5bb507a F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 F ext/rtree/rtree_util.tcl 202ca70df1f0645ef9d5a2170e62d378a28098d9407f0569e85c9c1cf1bd020a -F ext/rtree/rtreecheck.test 934546ad9b563e090ee0c5cbdc69ad014189ad76e5df7320526797a9a345661f +F ext/rtree/rtreecheck.test 84eedb43b25b3edf591125266d0bb1cebdfcdcc9c4a56b27d85bcb63c7dd7558 F ext/rtree/rtreecirc.test aec664eb21ae943aeb344191407afff5d392d3ae9d12b9a112ced0d9c5de298e F ext/rtree/rtreeconnect.test 225ad3fcb483d36cbee423a25052a6bbae762c9576ae9268332360c68c170d3d F ext/rtree/rtreedoc.test d633982d61542f3bc0a0a2df0382a02cc699ac56cbda01130cde6da44a228490 @@ -597,6 +598,7 @@ F ext/session/session_speed_test.c dcf0ef58d76b70c8fbd9eab3be77cf9deb8bc1638fed8 F ext/session/sessionalter.test e852acb3d2357aac7d0b920a2109da758c4331bfdf85b41d39aa3a8c18914f65 F ext/session/sessionat.test 00c8badb35e43a2f12a716d2734a44d614ff62361979b6b85419035bc04b45ee F ext/session/sessionbig.test 47c381e7acfabeef17d98519a3080d69151723354d220afa2053852182ca7adf +F ext/session/sessionblob.test 87faf667870b72f08e91969abd9f52a383ab7b514506ee194d64a39d8faff00a F ext/session/sessionchange.test 77c4702050f24270b58070e2cf01c95c3d232a3ef164b70f31974b386ce69903 F ext/session/sessionconflict.test 8b8cbd98548e2e636ddc17d0986276f60e833fb865617dd4f88ea5bbe3a16b96 F ext/session/sessiondiff.test e89f7aedcdd89e5ebac3a455224eb553a171e9586fc3e1e6a7b3388d2648ba8d @@ -669,7 +671,7 @@ F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2 F ext/wasm/demo-worker1.js 836bece8615b17b1b572584f7b15912236a5947fe8c68b98d2737d7e287447ef F ext/wasm/dist.make 653e212c1e84aa3be168d62a10616ccea45ee9585b0192745d2706707a5248ce F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f -F ext/wasm/fiddle.make ec2353f0eddade864f67b993376a0949e27b72465c24b1970940e48b70bc2df1 +F ext/wasm/fiddle.make d4969f0322a582c57a22ce3541f10a5b09a609d14eab32891f613f43b3c14d8b F ext/wasm/fiddle/fiddle-worker.js 850e66fce39b89d59e161d1abac43a181a4caa89ddeea162765d660277cd84ce F ext/wasm/fiddle/fiddle.js b444a5646a9aac9f3fc06c53d78af5e1912eb235d69a8e6010723e4eb0e9d4a1 F ext/wasm/fiddle/index.html c79b1741cbeba78f88af0a84cf5ec7de87a909a6a8d10a369b1f4824c66c2088 @@ -699,7 +701,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk 741ad81800eb48eeb09c9093fc7436aef9d635aaca7376faec3ed088173066fe +F main.mk c1a91dc50ffc1cb828b85d767d02d80d9eabeb0ef47e77e57bd72617749c5dbf F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -708,7 +710,7 @@ F mptest/mptest.c aa41ace6dbc5050d76b02548d3521e6bbccae4f0 F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc -F sqlite3.pc.in 2d5c88643679fc199dafc9afb6ea8868ea3192d941c2e57dbe06395149d892ba +F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03 F sqlite_cfg.h.in be1d075cf77134d53fdf5cc2c0919842e7e02a648c66a56e735af25ccdcaff91 F src/alter.c aa93e37e4a36a0525bbb2a2aeda20d2018f0aa995542c7dc658e031375e3f532 F src/analyze.c 9a8b67239d899ac12289db5db3f5bfe7f7a0ad1277f80f87ead1d048085876eb @@ -762,24 +764,24 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06 F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 -F src/os_unix.c 0ad4e0885294b3a0e135a18533590ec9ad91ffe82f6a08e55b40babd51772928 +F src/os_unix.c c84a3add1e480499261a41d77d3f87d18f27aaebec6376655c177a3886a5b67c F src/os_win.c 69fa1aaff68270423c85cff4327ba17ef99a1eb017e1a2bfb97416d9b8398b05 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 9656ad4e8331efb8a4f94f7a0c6440b98caea073950a367ea0c728a53b8e62c9 F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a -F src/parse.y a7a8d42eeff01d267444ddb476029b0b1726fb70ae3d77984140f17ad02e2d61 +F src/parse.y 8ec56598aa0df92428627502267d0d1c9778cc27308f8ffd31dfb2d017a8755f F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 49516ad7718a3626f28f710fa7448ef1fce3c07fd169acbb4817341950264319 F src/pragma.c a2ec3657a953fa7dea7c1e680e4358b6ce6ae570b6c5234e0f5ef219d308d223 F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 -F src/prepare.c 3ba0ad907b7773ed642f66cea8a2c9c8edc18841aa1050b6218dbb3479e86225 +F src/prepare.c 1832be043fce7d489959aae6f994c452d023914714c4d5457beaed51c0f3d126 F src/printf.c 6a87534ebfb9e5346011191b1f3a7ebc457f5938c7e4feeea478ecf53f6a41b2 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe -F src/shell.c.in 4eb010971da0a4b103af5853152e9c95b991174df75528fda6f333037f0007a0 +F src/shell.c.in bb8ca98e903ea1dc60cee7e0a82017879662a2e4ce1f43889da87e8d4d774a5d F src/sqlite.h.in 599203aa6cf3a662f879e7581f4b7f2678738c0b7c71ddda3c0cb5c59867c399 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 @@ -789,7 +791,7 @@ F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/tclsqlite.c ff2dc3ec1bd318ee7a45d6b246a367703d5fb2a4c8da99d675ee7eb987b3a153 F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395 -F src/test1.c 9df74d1d8c0513b0f906942d004b7d7aff5c6f47320a921a0b890748bac0e34d +F src/test1.c 2d507751bfb4aa254dc22588ef1e3c5c5cfcb2e636d0e6e1fa0bbd307669c2a8 F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3 F src/test3.c e7573aa0f78ee4e070a4bc8c3493941c1aa64d5c66d4825c74c0f055451f432b F src/test4.c 13e57ae7ec7a959ee180970aef09deed141252fe9bb07c61054f0dfa4f1dfd5d @@ -849,9 +851,9 @@ F src/util.c ceebf912f673247e305f16f97f0bb7285fca1d37413b79680714a553a9021d33 F src/vacuum.c b763b6457bd058d2072ef9364832351fd8d11e8abf70cbb349657360f7d55c40 F src/vdbe.c 8a6eb02823b424b273614bae41579392a5c495424592b60423dd2c443a583df0 F src/vdbe.h c2549a215898a390de6669cfa32adba56f0d7e17ba5a7f7b14506d6fd5f0c36a -F src/vdbeInt.h af7d7e8291edd0b19f2cd698e60e4d4031078f9a2f2328ac8f0b7efb134f8a1d -F src/vdbeapi.c 53c7e26a2c0821a892b20eee2cde4656e31998212f3d515576c780dfaa45fd17 -F src/vdbeaux.c f06f011e4fac948941ea821ac365a9f1c163ef473e63756d6e499a37c6bda9ef +F src/vdbeInt.h 2da01c73e8e3736a9015d5b04aa04d209bc9023d279d237d4d409205e921ea1e +F src/vdbeapi.c 6353de05e8e78e497ccb33381ba5662ccc11c0339e5b1455faff01b6dacc3075 +F src/vdbeaux.c f0706ad786b8a6c5bc7ea622f3916c2ba2b883abc872d0b4911c4f021945c0e5 F src/vdbeblob.c 255be187436da38b01f276c02e6a08103489bbe2a7c6c21537b7aecbe0e1f797 F src/vdbemem.c df568ef0187e4be2788c35174f6d9b8566ab9475f9aff2d73907ed05aa5684b2 F src/vdbesort.c d0a3c7056c081703c8b6d91ad60f17da5e062a5c64bf568ed0fa1b5f4cae311f @@ -1121,7 +1123,7 @@ F test/e_walauto.test 248af31e73c98df23476a22bdb815524c9dc3ba8 F test/e_walckpt.test 28c371a6bb5e5fe7f31679c1df1763a19d19e8a0 F test/e_walhook.test 01b494287ba9e60b70f6ebf3c6c62e0ffe01788e344a4846b08e5de0b344cb66 F test/emptytable.test a38110becbdfa6325cd65cb588dca658cd885f62 -F test/enc.test 9a7be5479da985381d740b15f432800f65e2c87029ee57a318f42cb2eb43763a +F test/enc.test b5503a87b31cea8a5084c6e447383f9ca08933bd2f29d97b6b6201081b2343eb F test/enc2.test 848bf05f15b011719f478dddb7b5e9aea35e39e457493cba4c4eef75d849a5ec F test/enc3.test 55ef64416d72975c66167310a51dc9fc544ba3ae4858b8d5ab22f4cb6500b087 F test/enc4.test c8f1ce3618508fd0909945beb8b8831feef2c020 @@ -1458,7 +1460,7 @@ F test/misc1.test e3e36262aff1bd9b8b9bf1eeb3af04adb3fc1e23f0a92dbff708bba9e939ac F test/misc2.test a1a3573cc02662becd967766021d6f16c54684d56df5f227481c7ef0d9df0bd0 F test/misc3.test 651b88bca19b8ff6a7b6af73dae00c3fd5b3ea5bee0c0d1d91abd4c4b4748718 F test/misc4.test 10cd6addb2fa9093df4751a1b92b50440175dd5468a6ec84d0386e78f087db0e -F test/misc5.test 027cf0ac10314ea534173f335a33bb4059907ddabbac2c16786766d6f26c8923 +F test/misc5.test 02fcaf4d42405be02ec975e946270a50b0282dac98c78303ade0d1392839d2b8 F test/misc6.test 953cc693924d88e6117aeba16f46f0bf5abede91 F test/misc7.test d912f3d45c2989191b797504a220ca225d6be80b21acad22ba0d35f4a9ee4579 F test/misc8.test 08d2380bc435486b12161521f225043ac2be26f02471c2c1ea4cac0b1548edbd @@ -1708,7 +1710,7 @@ F test/sync.test 89539f4973c010eda5638407e71ca7fddbcd8e0594f4c9980229f804d433309 F test/sync2.test 8f9f7d4f6d5be8ca8941a8dadcc4299e558cb6a1ff653a9469146c7a76ef2039 F test/syscall.test a067468b43b8cb2305e9f9fe414e5f40c875bb5d2cba5f00b8154396e95fcf37 F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 -F test/tabfunc01.test 6002a5f37b76355f173c75c2b3b03173b19d6a8b078c5baaa4c78bbcd0fa6323 +F test/tabfunc01.test 7be82bd50c7ede7f01b2dd17cd1b84f352c516078222d0b067d858f081e3f9a7 F test/table.test 7862a00b58b5541511a26757ea9c5c7c3f8298766e98aa099deec703d9c0a8e0 F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 @@ -1721,7 +1723,7 @@ F test/temptable2.test 76821347810ecc88203e6ef0dd6897b6036ac788e9dd3e6b04fd4d163 F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/tester.tcl 7b44f1a9b9a2de8112695b908afc21dd9a68cd2d44e84b73f1b27b53492c0d59 -F test/testrunner.tcl 3c6acf0eecd2b5459082639183f2b4f667aa0b74ddab24e4d37295112c7a5325 x +F test/testrunner.tcl c40d5700578f8c9d00e0e15f105f645c471bc2c48eb8b013bd2953400f2c6bf0 x F test/testrunner_data.tcl ba4aeea28aa03cfa6fe7e57782ddecb7a7b91c3a0b3251583cb4f0ee002de6a6 F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 @@ -2116,7 +2118,7 @@ F tool/custom.txt 24ed55e71c5edae0067ba159bbf09240d58b160331f7716e95816cd3aa0ba5 F tool/dbhash.c 5da0c61032d23d74f2ab84ffc5740f0e8abec94f2c45c0b4306be7eb3ae96df0 F tool/dbtotxt.c ca48d34eaca6d6b6e4bd6a7be2b72caf34475869054240244c60fa7e69a518d6 F tool/dbtotxt.md c9a57af8739957ef36d2cfad5c4b1443ff3688ed33e4901ee200c8b651f43f3c -F tool/emcc.sh.in 5a3534af8d437747cf4141abaab3db558756f4a1ac8f3ebf28a16ffa26209921 +F tool/emcc.sh.in 1f3226166bad1765c0bf42fac3d29037704c2078eb22562f9ddfbe73bff023b0 F tool/enlargedb.c 3e8b2612b985cfa7e3e8800031ee191b43ae80de96abb5abbd5eada62651ee21 F tool/extract-sqlite3h.tcl 069ceab0cee26cba99952bfa08c0b23e35941c837acabe143f0c355d96c9e2eb x F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 @@ -2200,8 +2202,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 46929ae92b26f02bc70de9931b21a8a7cf9a2453d5fb07f68b712f62e28e9152 -R a22fb948708e266e2094d3645362e84e +P 9cc04331a01760189d88697233009dbe8a60eda589792ad01b56300499e9f54d 5495b12569c318d5020b4b5a625a392ef8e777b81c0200624fbbc2a6b5eddef9 +R 43b03038eb634e877d13ab18dcd80180 U dan -Z 3041da3c7f9ea1d87e0998786f60280f +Z 70a74ef30cc348badfc60dd108f53b23 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 20c99b7fae..b5f3f21ebe 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9cc04331a01760189d88697233009dbe8a60eda589792ad01b56300499e9f54d +edb842349320eda9550bdfcd5a327949c5512e02f4b993782587b2131a425746 diff --git a/sqlite3.pc.in b/sqlite3.pc.in index 97f3c1a60d..a9f941b1e4 100644 --- a/sqlite3.pc.in +++ b/sqlite3.pc.in @@ -9,5 +9,5 @@ Name: SQLite Description: SQL database engine Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lsqlite3 -Libs.private: @LDFLAGS_MATH@ @LDFLAGS_ICU@ +Libs.private: @LDFLAGS_MATH@ @LDFLAGS_ZLIB@ @LDFLAGS_ICU@ Cflags: -I${includedir} diff --git a/src/os_unix.c b/src/os_unix.c index c13c5cece0..8cc1886745 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -213,7 +213,7 @@ # endif #else /* !SQLITE_WASI */ # ifndef HAVE_FCHMOD -# define HAVE_FCHMOD +# define HAVE_FCHMOD 1 # endif #endif /* SQLITE_WASI */ diff --git a/src/parse.y b/src/parse.y index a6a5e046db..8fdea9bfa3 100644 --- a/src/parse.y +++ b/src/parse.y @@ -499,7 +499,11 @@ cmd ::= DROP VIEW ifexists(E) fullname(X). { // cmd ::= select(X). { SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0}; - sqlite3Select(pParse, X, &dest); + if( (pParse->db->mDbFlags & DBFLAG_EncodingFixed)!=0 + || sqlite3ReadSchema(pParse)==SQLITE_OK + ){ + sqlite3Select(pParse, X, &dest); + } sqlite3SelectDelete(pParse->db, X); } diff --git a/src/prepare.c b/src/prepare.c index 7aa1e1a022..de364f925b 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -306,14 +306,7 @@ int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){ #else encoding = SQLITE_UTF8; #endif - if( db->nVdbeActive>0 && encoding!=ENC(db) - && (db->mDbFlags & DBFLAG_Vacuum)==0 - ){ - rc = SQLITE_LOCKED; - goto initone_error_out; - }else{ - sqlite3SetTextEncoding(db, encoding); - } + sqlite3SetTextEncoding(db, encoding); }else{ /* If opening an attached database, the encoding much match ENC(db) */ if( (meta[BTREE_TEXT_ENCODING-1] & 3)!=ENC(db) ){ diff --git a/src/shell.c.in b/src/shell.c.in index cdd09becf0..180768b7fb 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -2037,8 +2037,8 @@ const char *zSkipValidUtf8(const char *z, int nAccept, long ccm){ const char *pcLimit = (nAccept>=0)? z+nAccept : 0; assert(z!=0); while( (pcLimit)? (zpUnpacked==0 ){ - u32 nRec; - u8 *aRec; - - assert( p->pCsr->eCurType==CURTYPE_BTREE ); - nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); - aRec = sqlite3DbMallocRaw(db, nRec); - if( !aRec ) goto preupdate_old_out; - rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); - if( rc==SQLITE_OK ){ - p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); - if( !p->pUnpacked ) rc = SQLITE_NOMEM; - } - if( rc!=SQLITE_OK ){ - sqlite3DbFree(db, aRec); - goto preupdate_old_out; - } - p->aRecord = aRec; - } - - pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; if( iIdx==p->pTab->iPKey ){ + *ppValue = pMem = &p->oldipk; sqlite3VdbeMemSetInt64(pMem, p->iKey1); - }else if( iIdx>=p->pUnpacked->nField ){ - /* This occurs when the table has been extended using ALTER TABLE - ** ADD COLUMN. The value to return is the default value of the column. */ - Column *pCol = &p->pTab->aCol[iIdx]; - if( pCol->iDflt>0 ){ - if( p->apDflt==0 ){ - int nByte = sizeof(sqlite3_value*)*p->pTab->nCol; - p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte); - if( p->apDflt==0 ) goto preupdate_old_out; + }else{ + + /* If the old.* record has not yet been loaded into memory, do so now. */ + if( p->pUnpacked==0 ){ + u32 nRec; + u8 *aRec; + + assert( p->pCsr->eCurType==CURTYPE_BTREE ); + nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); + aRec = sqlite3DbMallocRaw(db, nRec); + if( !aRec ) goto preupdate_old_out; + rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); + if( rc==SQLITE_OK ){ + p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); + if( !p->pUnpacked ) rc = SQLITE_NOMEM; } - if( p->apDflt[iIdx]==0 ){ - sqlite3_value *pVal = 0; - Expr *pDflt; - assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) ); - pDflt = p->pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; - rc = sqlite3ValueFromExpr(db, pDflt, ENC(db), pCol->affinity, &pVal); - if( rc==SQLITE_OK && pVal==0 ){ - rc = SQLITE_CORRUPT_BKPT; - } - p->apDflt[iIdx] = pVal; + if( rc!=SQLITE_OK ){ + sqlite3DbFree(db, aRec); + goto preupdate_old_out; } - *ppValue = p->apDflt[iIdx]; - }else{ - *ppValue = (sqlite3_value *)columnNullValue(); + p->aRecord = aRec; } - }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ - if( pMem->flags & (MEM_Int|MEM_IntReal) ){ - testcase( pMem->flags & MEM_Int ); - testcase( pMem->flags & MEM_IntReal ); - sqlite3VdbeMemRealify(pMem); + + pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; + if( iIdx>=p->pUnpacked->nField ){ + /* This occurs when the table has been extended using ALTER TABLE + ** ADD COLUMN. The value to return is the default value of the column. */ + Column *pCol = &p->pTab->aCol[iIdx]; + if( pCol->iDflt>0 ){ + if( p->apDflt==0 ){ + int nByte = sizeof(sqlite3_value*)*p->pTab->nCol; + p->apDflt = (sqlite3_value**)sqlite3DbMallocZero(db, nByte); + if( p->apDflt==0 ) goto preupdate_old_out; + } + if( p->apDflt[iIdx]==0 ){ + sqlite3_value *pVal = 0; + Expr *pDflt; + assert( p->pTab!=0 && IsOrdinaryTable(p->pTab) ); + pDflt = p->pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; + rc = sqlite3ValueFromExpr(db, pDflt, ENC(db), pCol->affinity, &pVal); + if( rc==SQLITE_OK && pVal==0 ){ + rc = SQLITE_CORRUPT_BKPT; + } + p->apDflt[iIdx] = pVal; + } + *ppValue = p->apDflt[iIdx]; + }else{ + *ppValue = (sqlite3_value *)columnNullValue(); + } + }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ + if( pMem->flags & (MEM_Int|MEM_IntReal) ){ + testcase( pMem->flags & MEM_Int ); + testcase( pMem->flags & MEM_IntReal ); + sqlite3VdbeMemRealify(pMem); + } } } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 8120536b98..4414f7a2ec 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -5529,6 +5529,7 @@ void sqlite3VdbePreUpdateHook( sqlite3DbFree(db, preupdate.aRecord); vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pUnpacked); vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pNewUnpacked); + sqlite3VdbeMemRelease(&preupdate.oldipk); if( preupdate.aNew ){ int i; for(i=0; inField; i++){ diff --git a/test/enc.test b/test/enc.test index ffe24164bd..0aec224e2d 100644 --- a/test/enc.test +++ b/test/enc.test @@ -249,4 +249,33 @@ do_execsql_test enc-12.10 { SELECT * FROM t1; } {d e f xxx yyy zzz} + +# 2024-11-04 +# https://sqlite.org/forum/forumpost/bc75a4d20b756044 +# +# Ensure the database encoding is detected in a timely manner, +# and before we get too far along in generating and running +# bytecode. +# +# See also check-in https://sqlite.org/src/info/a02da71f3a. +# +db close +forcedelete utf16.db +sqlite3 db utf16.db +db eval {PRAGMA encoding=UTF16; CREATE TABLE t2(y); INSERT INTO t2 VALUES('utf16');} +db close +sqlite3 db utf16.db +do_test enc-13.1 { + db eval {PRAGMA function_list} {db eval {SELECT * FROM sqlite_schema}} +} {} +ifcapable rtree { + db eval {CREATE VIRTUAL TABLE t3 USING rtree(id,x1,x2)} + db close + sqlite3 db utf16.db + do_execsql_test enc-13.2 { + WITH t1(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM t1 WHERE x<3) + SELECT rtreecheck('t3') FROM t1; + } {ok ok ok} +} + finish_test diff --git a/test/misc5.test b/test/misc5.test index 84aa9586d3..43ee2781a1 100644 --- a/test/misc5.test +++ b/test/misc5.test @@ -523,6 +523,7 @@ if {[permutation] == ""} { CREATE TABLE t1(a,b,c); } } {1 {file is not a database}} + reset_db } # Ticket #1371. Allow floating point numbers of the form .N or N. diff --git a/test/tabfunc01.test b/test/tabfunc01.test index 8c24198e1d..b6797171e0 100644 --- a/test/tabfunc01.test +++ b/test/tabfunc01.test @@ -348,6 +348,29 @@ do_execsql_test tabfunc01-920 { ) LIMIT -1 OFFSET 0; } {1 2 3 4 5 6 7 8 9 10 101 102 103 104} +#------------------------------------------------------------------------- +# Forum post https://sqlite.org/forum/forumpost/e7c3ae1215 +# +foreach {tn where res} { + 1000 "where value = 2" 2 + 1010 "where value in (2)" 2 + 1020 "where value in (select 2)" 2 + 1030 "where value = 2 OR value = 4" {2 4} + 1040 "where value in (2, 4)" {2 4} +} { + do_execsql_test $tn " + SELECT value FROM generate_series(1, 5) $where + " $res +} + +do_execsql_test 1100 { + select 1 as c_0 + from + generate_series(1, 1) as ref_3 + where (ref_3.value) in (select 1); +} {1} + + # Free up memory allocations intarray_addr diff --git a/test/testrunner.tcl b/test/testrunner.tcl index 66fa1058bb..889bfeaffd 100755 --- a/test/testrunner.tcl +++ b/test/testrunner.tcl @@ -547,12 +547,15 @@ proc show_status {db cls} { set srcdir [file dirname [file dirname $TRG(info_script)]] set line "Running: $S(running) (max: $nJob)" - if {$S(running)>0 && $fin>10 && [string length $line]<69} { + if {$S(running)>0 && $fin>10} { set tmleft [expr {($tm/$fin)*($totalw-$fin)}] if {$tmleft<0.02*$tm} { set tmleft [expr {$tm*0.02}] } - append line " ETC [elapsetime $tmleft]" + set etc " ETC [elapsetime $tmleft]" + if {[string length $line]+[string length $etc]<80} { + append line $etc + } } puts [format %-79.79s $line] if {$S(running)>0} { @@ -1369,10 +1372,7 @@ proc script_input_ready {fd iJob jobid} { set state "done" set rc [catch { close $fd } msg] if {$rc} { - if {[info exists TRG(reportlength)]} { - puts -nonewline "[string repeat " " $TRG(reportlength)]\r" - } - puts "FAILED: $job(displayname) ($iJob)" + puts [format %-79.79s "FAILED: $job(displayname) ($iJob)"] set state "failed" if {$TRG(stopOnError)} { puts "OUTPUT: $O($iJob)" @@ -1523,22 +1523,16 @@ proc progress_report {} { lappend text "r$v(running,$j)" } } + set report "[elapsetime $tmms] [join $text { }]" if {$wdone>0} { set tmleft [expr {($tmms/$wdone)*($wtotal-$wdone)}] - append text " ETC [elapsetime $tmleft]" - } - - if {[info exists TRG(reportlength)]} { - puts -nonewline "[string repeat " " $TRG(reportlength)]\r" - } - set report "[elapsetime $tmms] [join $text { }]" - set TRG(reportlength) [string length $report] - if {[string length $report]<100} { - puts -nonewline "$report\r" - flush stdout - } else { - puts $report + set etc " ETC [elapsetime $tmleft]" + if {[string length $report]+[string length $etc]<80} { + append report $etc + } } + puts -nonewline [format %-79.79s $report]\r + flush stdout } after $TRG(reporttime) progress_report } diff --git a/tool/emcc.sh.in b/tool/emcc.sh.in index fb849545f8..1263e1b0ea 100644 --- a/tool/emcc.sh.in +++ b/tool/emcc.sh.in @@ -10,10 +10,10 @@ # script, if needed. ######################################################################## # EMSDK_HOME comes from the configure --with-emsdk=/dir flag. -# EMSDK_ENV is ${thatDir}/emsdk_env.sh and is also set by the +# EMSDK_ENV_SH is ${thatDir}/emsdk_env.sh and is also set by the # configure process. EMSDK_HOME="@EMSDK_HOME@" -EMSDK_ENV="@EMSDK_ENV@" +EMSDK_ENV_SH="@EMSDK_ENV_SH@" emcc="@BIN_EMCC@" if [ x = "x${emcc}" ]; then @@ -22,41 +22,43 @@ fi if [ x = "x${emcc}" ]; then # If emcc is not found in the path, try to find it via an emsdk - # installation. The SDK variant is the official installation - # style supported by the Emscripten folks, but emcc is also - # available via package managers on some OSes. + # installation. The SDK variant is the official installation style + # supported by the Emscripten project, but emcc is also available + # via package managers on some OSes. if [ x = "x${EMSDK_HOME}" ]; then echo "EMSDK_HOME is not set. Pass --with-emsdk=/path/to/emsdk" \ "to the configure script." 1>&2 exit 1 fi - if [ x = "x${EMSDK_ENV}" ]; then + if [ x = "x${EMSDK_ENV_SH}" ]; then if [ -f "${EMSDK_HOME}/emsdk_env.sh" ]; then - EMSDK_ENV="${EMSDK_HOME}/emsdk_env.sh" + EMSDK_ENV_SH="${EMSDK_HOME}/emsdk_env.sh" else - echo "EMSDK_ENV is not set. Expecting configure script to set it." 1>&2 + echo "EMSDK_ENV_SH is not set. Expecting configure script to set it." 1>&2 exit 2 fi fi - if [ ! -f "${EMSDK_ENV}" ]; then - echo "emsdk_env script not found: $EMSDK_ENV" 1>&2 + if [ ! -f "${EMSDK_ENV_SH}" ]; then + echo "emsdk_env script not found: $EMSDK_ENV_SH" 1>&2 exit 3 fi # $EMSDK is part of the state set by emsdk_env.sh. if [ x = "x${EMSDK}" ]; then - source "${EMSDK_ENV}" >/dev/null 2>&1 || { - # ^^^ unfortunately outputs lots of noise to stderr + EMSDK_QUIET=1 + export EMSDK_QUIET + # ^^^ Squelches informational output from ${EMSDK_ENV_SH}. + source "${EMSDK_ENV_SH}" || { rc=$? - echo "Error sourcing ${EMSDK_ENV}" + echo "Error sourcing ${EMSDK_ENV_SH}" exit $rc } fi emcc=`which emcc 2>/dev/null` if [ x = "x${emcc}" ]; then - echo "emcc not found in PATH. Normally that's set up by ${EMSDK_ENV}." 1>&2 + echo "emcc not found in PATH. Normally that's set up by ${EMSDK_ENV_SH}." 1>&2 exit 4 fi fi