Compare commits

..

1 Commits

Author SHA1 Message Date
drh e8f850e7bd Attempt to improvement performance of multiple OP_Columns that occur in a row.
Minimal improvement for a lot of complexity and risk.

FossilOrigin-Name: 53478f29347c7f17d46ec2a1e7c390c9be9e9fc32f31da77a4ba7a9d67440a8e
2025-02-11 16:00:52 +00:00
403 changed files with 13241 additions and 10904 deletions
-1
View File
@@ -1 +0,0 @@
*.db
+22 -24
View File
@@ -79,7 +79,7 @@ libdir = @libdir@
INSTALL = @BIN_INSTALL@
AR = @AR@
AR.flags = cr
AR.flags = cr # TODO? Add a configure test to determine this?
CC = @CC@
B.cc = @CC_FOR_BUILD@ @BUILD_CFLAGS@
T.cc = $(CC)
@@ -118,33 +118,27 @@ LDFLAGS.dlopen = @LDFLAGS_DLOPEN@
LDFLAGS.readline = @LDFLAGS_READLINE@
CFLAGS.readline = @CFLAGS_READLINE@
LDFLAGS.icu = @LDFLAGS_ICU@
LDFLAGS.rt = @LDFLAGS_RT@
CFLAGS.icu = @CFLAGS_ICU@
LDFLAGS.libsqlite3.soname = @LDFLAGS_LIBSQLITE3_SONAME@
# soname: see https://sqlite.org/src/forumpost/5a3b44f510df8ded
LDFLAGS.libsqlite3.os-specific = \
@LDFLAGS_MAC_CVERSION@ @LDFLAGS_MAC_INSTALL_NAME@ @LDFLAGS_OUT_IMPLIB@
LDFLAGS.libsqlite3.os-specific = @LDFLAGS_MAC_CVERSION@ @LDFLAGS_OUT_IMPLIB@
# os-specific: see
# - https://sqlite.org/forum/forumpost/9dfd5b8fd525a5d7
# - https://sqlite.org/forum/forumpost/0c7fc097b2
# - https://sqlite.org/forum/forumpost/5651662b8875ec0a
libsqlite3.DLL.basename = @SQLITE_DLL_BASENAME@
# DLL.basename: see https://sqlite.org/forum/forumpost/828fdfe904
libsqlite3.out.implib = @SQLITE_OUT_IMPLIB@
# libsqlite3.out.implib => the output filename part of LDFLAGS_OUT_IMPLIB.
ENABLE_LIB_SHARED = @ENABLE_LIB_SHARED@
ENABLE_LIB_STATIC = @ENABLE_LIB_STATIC@
ENABLE_SHARED = @ENABLE_SHARED@
ENABLE_STATIC = @ENABLE_STATIC@
HAVE_WASI_SDK = @HAVE_WASI_SDK@
libsqlite3.DLL.install-rules = @SQLITE_DLL_INSTALL_RULES@
# -fsanitize flags for the fuzzcheck-asap app
CFLAGS.fuzzcheck-asan.fsanitize = @CFLAGS_ASAN_FSANITIZE@
T.cc.sqlite = $(T.cc) @TARGET_DEBUG@
#
# Intended to either be empty or be set to -g -DSQLITE_DEBUG=1.
# Define -D_HAVE_SQLITE_CONFIG_H so that the code knows it
# can include the generated sqlite_cfg.h.
#
T.cc.TARGET_DEBUG = @TARGET_DEBUG@
# main.mk will fill out T.cc.sqlite with additional flags common to
# all builds.
#
T.cc.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite
#
# $(JIMSH) and $(CFLAGS.jimsh) are documented in main.mk. $(JIMSH)
@@ -152,7 +146,7 @@ T.cc.TARGET_DEBUG = @TARGET_DEBUG@
# shell command.
#
CFLAGS.jimsh = @CFLAGS_JIMSH@
JIMSH = ./jimsh$(T.exe)
JIMSH = ./jimsh$(TEXE)
#
# $(B.tclsh) is documented in main.mk.
@@ -243,8 +237,8 @@ TSTRNNR_OPTS = @TSTRNNR_OPTS@
CFLAGS.gcov1 = -DSQLITE_COVERAGE_TEST=1 -fprofile-arcs -ftest-coverage
LDFLAGS.gcov1 = -lgcov
USE_GCOV = @USE_GCOV@
T.compile.gcov = $(CFLAGS.gcov$(USE_GCOV))
T.link.gcov = $(LDFLAGS.gcov$(USE_GCOV))
T.compile.extras = $(CFLAGS.gcov$(USE_GCOV))
T.link.extras = $(LDFLAGS.gcov$(USE_GCOV))
#
# Vars with the AS_ prefix are specifically related to AutoSetup.
@@ -261,9 +255,6 @@ AS_AUTORECONFIG = @SQLITE_AUTORECONFIG@
USE_AMALGAMATION ?= @USE_AMALGAMATION@
LINK_TOOLS_DYNAMICALLY ?= @LINK_TOOLS_DYNAMICALLY@
AMALGAMATION_GEN_FLAGS ?= --linemacros=@AMALGAMATION_LINE_MACROS@
EXTRA_SRC ?= @AMALGAMATION_EXTRA_SRC@
STATIC_TCLSQLITE3 = @STATIC_TCLSQLITE3@
STATIC_CLI_SHELL = @STATIC_CLI_SHELL@
#
# CFLAGS for sqlite3$(T.exe)
@@ -325,7 +316,13 @@ misspell: ./custom.rws has_tclsh84
# perform cleanup known to be relevant to (only) the autosetup-driven
# build.
#
distclean-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)
@@ -339,4 +336,5 @@ distclean: distclean-autosetup
version-info$(T.exe): $(TOP)/tool/version-info.c Makefile sqlite3.h
$(T.link) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c
IS_CROSS_COMPILING = @IS_CROSS_COMPILING@
include $(TOP)/main.mk
+7 -30
View File
@@ -294,12 +294,6 @@ SESSION = 0
RBU = 0
!ENDIF
# Set this to non-0 to enable support for blocking locks.
#
!IFNDEF SETLK_TIMEOUT
SETLK_TIMEOUT = 0
!ENDIF
# Set the source code file to be used by executables and libraries when
# they need the amalgamation.
#
@@ -456,10 +450,6 @@ EXT_FEATURE_FLAGS =
!ENDIF
!ENDIF
!IF $(SETLK_TIMEOUT)!=0
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SETLK_TIMEOUT
!ENDIF
###############################################################################
############################### END OF OPTIONS ################################
###############################################################################
@@ -1406,7 +1396,7 @@ SRC00 = \
$(TOP)\src\build.c \
$(TOP)\src\callback.c \
$(TOP)\src\complete.c \
ctime.c \
$(TOP)\src\ctime.c \
$(TOP)\src\date.c \
$(TOP)\src\dbpage.c \
$(TOP)\src\dbstat.c \
@@ -1505,7 +1495,7 @@ SRC04 = \
SRC05 = \
$(TOP)\src\pager.h \
$(TOP)\src\pcache.h \
pragma.h \
$(TOP)\src\pragma.h \
$(TOP)\src\sqlite.h.in \
$(TOP)\src\sqlite3ext.h \
$(TOP)\src\sqliteInt.h \
@@ -1708,7 +1698,7 @@ HDR = \
$(TOP)\src\pager.h \
$(TOP)\src\pcache.h \
parse.h \
pragma.h \
$(TOP)\src\pragma.h \
$(SQLITE3H) \
sqlite3ext.h \
$(TOP)\src\sqliteInt.h \
@@ -2109,11 +2099,8 @@ callback.lo: $(TOP)\src\callback.c $(HDR)
complete.lo: $(TOP)\src\complete.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\complete.c
ctime.c: $(TOP)\tool\mkctimec.tcl $(JIM_TCLSH)
$(JIM_TCLSH) $(TOP)\tool\mkctimec.tcl
ctime.lo: ctime.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c ctime.c
ctime.lo: $(TOP)\src\ctime.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\ctime.c
date.lo: $(TOP)\src\date.c $(HDR)
$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\date.c
@@ -2346,9 +2333,6 @@ parse.c: $(TOP)\src\parse.y lemon.exe
copy /B parse.y +,,
.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) -S parse.y
pragma.h: $(TOP)\tool\mkpragmatab.tcl $(JIM_TCLSH)
$(JIM_TCLSH) $(TOP)\tool\mkpragmatab.tcl
$(SQLITE3H): $(TOP)\src\sqlite.h.in $(TOP)\manifest mksourceid.exe $(TOP)\VERSION $(JIM_TCLSH)
$(JIM_TCLSH) $(TOP)\tool\mksqlite3h.tcl "$(TOP:\=/)" -o $(SQLITE3H) $(MKSQLITE3H_ARGS)
@@ -2593,11 +2577,6 @@ testfixture.exe: $(TESTFIXTURE_SRC) $(TESTFIXTURE_DEP) $(SQLITE3H) $(LIBRESOBJS)
$(TESTFIXTURE_SRC) \
/link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
# A small helper for manually running individual tests
tf.bat: testfixture.exe Makefile.msc
echo @set PATH=$(LIBTCLPATH);%PATH% > $@
echo .\testfixture.exe %* >> $@
extensiontest: testfixture.exe testloadext.dll
@set PATH=$(LIBTCLPATH);$(PATH)
.\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS)
@@ -2833,7 +2812,7 @@ moreclean: clean
clean:
del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
del /Q *.bsc *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
del /Q sqlite3.def tclsqlite3.def ctime.c pragma.h 2>NUL
del /Q sqlite3.def tclsqlite3.def 2>NUL
del /Q $(SQLITE3EXE) $(SQLITE3DLL) Replace.exe 2>NUL
# <<mark>>
del /Q $(SQLITE3TCLDLL) pkgIndex.tcl 2>NUL
@@ -2849,9 +2828,7 @@ clean:
del /Q lsm.dll lsmtest.exe 2>NUL
del /Q atrc.exe changesetfuzz.exe dbtotxt.exe index_usage.exe 2>NUL
del /Q testloadext.dll 2>NUL
del /Q testfixture.exe test.db tf.bat 2>NUL
del /Q /S testdir 2>/NUL
-rmdir /Q /S testdir 2>NUL
del /Q testfixture.exe test.db 2>NUL
del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe dbdump.exe 2>NUL
del /Q changeset.exe 2>NUL
del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL
+13 -13
View File
@@ -57,18 +57,18 @@ If you do not want to use Fossil, you can download tarballs or ZIP
archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows:
* Latest trunk check-in as
[Tarball](https://sqlite.org/src/tarball/sqlite.tar.gz),
[ZIP-archive](https://sqlite.org/src/zip/sqlite.zip), or
[SQLite-archive](https://sqlite.org/src/sqlar/sqlite.sqlar).
[Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz),
[ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip), or
[SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar).
* Latest release as
[Tarball](https://sqlite.org/src/tarball/sqlite.tar.gz?r=release),
[ZIP-archive](https://sqlite.org/src/zip/sqlite.zip?r=release), or
[SQLite-archive](https://sqlite.org/src/sqlar/sqlite.sqlar?r=release).
[Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release),
[ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip?r=release), or
[SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar?r=release).
* For other check-ins, substitute an appropriate branch name or
tag or hash prefix in place of "release" in the URLs of the previous
bullet. Or browse the [timeline](https://sqlite.org/src/timeline)
bullet. Or browse the [timeline](https://www.sqlite.org/src/timeline)
to locate the check-in desired, click on its information page link,
then click on the "Tarball" or "ZIP Archive" links on the information
page.
@@ -134,7 +134,7 @@ later. The "tclextension-install" target and the test targets that follow
all require TCL development libraries too. ("apt install tcl-dev"). It is
helpful, but is not required, to install the SQLite TCL extension (the
"tclextension-install" target) prior to running tests. The "releasetest"
target has additional requirements, such as "valgrind".
target has additional requiremenst, such as "valgrind".
On "make" command-lines, one can add "OPTIONS=..." to specify additional
compile-time options over and above those set by ./configure. For example,
@@ -308,14 +308,14 @@ individual source file exceeds 32K lines in length.
## How It All Fits Together
SQLite is modular in design.
See the [architectural description](https://sqlite.org/arch.html)
See the [architectural description](https://www.sqlite.org/arch.html)
for details. Other documents that are useful in
helping to understand how SQLite works include the
[file format](https://sqlite.org/fileformat2.html) description,
the [virtual machine](https://sqlite.org/opcode.html) that runs
[file format](https://www.sqlite.org/fileformat2.html) description,
the [virtual machine](https://www.sqlite.org/opcode.html) that runs
prepared statements, the description of
[how transactions work](https://sqlite.org/atomiccommit.html), and
the [overview of the query planner](https://sqlite.org/optoverview.html).
[how transactions work](https://www.sqlite.org/atomiccommit.html), and
the [overview of the query planner](https://www.sqlite.org/optoverview.html).
Decades of effort have gone into optimizing SQLite, both
for small size and high performance. And optimizations tend to result in
+260 -45
View File
@@ -1,64 +1,279 @@
#!/do/not/tclsh
#/do/not/tclsh
# ^^^ help out editors which guess this file's content type.
#
# This is the main autosetup-compatible configure script for the
# SQLite project.
#
# This script and all of its dependencies must be kept compatible with
# JimTCL, a copy of which is included in this source tree as
# ./autosetup/jimsh0.c. The number of incompatibilities between
# canonical TCL and JimTCL is very low and alternative formulations of
# incompatible constructs have, so far, been easy to find.
# This script should be kept compatible with JimTCL, a copy of which
# is included in this source tree as ./autosetup/jimsh0.c. The number
# of incompatibilities between canonical TCL and JimTCL is very low
# and alternative formulations of incompatible constructs have, so
# far, been easy to find.
#
# JimTCL: https://jim.tcl.tk
#
use sqlite-config
sqlite-configure canonical {
proj-if-opt-truthy dev {
# --enable-dev needs to come early so that the downstream tests
# which check for the following flags use their updated state.
proj-opt-set all 1
proj-opt-set debug 1
proj-opt-set amalgamation 0
define CFLAGS [get-env CFLAGS {-O0 -g}]
# -------------^^^^^^^ intentionally using [get-env] instead of
# [proj-get-env] here because [sqlite-setup-default-cflags] uses
# [proj-get-env] and we want this to supercede that.
sqlite-munge-cflags; # straighten out -DSQLITE_ENABLE/OMIT flags
}
sqlite-handle-debug ;# must come after --dev flag check
sqlite-check-common-bins ;# must come before [sqlite-handle-wasi-sdk]
sqlite-handle-wasi-sdk ;# must run relatively early, as it changes the environment
sqlite-check-common-system-deps
proj-define-for-opt amalgamation USE_AMALGAMATION "Use amalgamation for builds?"
if {[string first " " $autosetup(srcdir)] != -1} {
user-error "The pathname of the source tree\
may not contain space characters"
}
if {[string first " " $autosetup(builddir)] != -1} {
user-error "The pathname of the build directory\
may not contain space characters"
}
proj-define-for-opt gcov USE_GCOV "Use gcov?"
proj-define-for-opt test-status TSTRNNR_OPTS \
"test-runner flags:" {--status} {}
########################################################################
# Regarding flag compatibility with the historical autotool configure
# script:
#
# A very long story made short, autosetup's --flag handling has
# some behaviors which make it impossible to implement 100% identical
# flags compared to the historical autotools build. The differences
# are documented here:
#
# 1) --debug is used by autosetup itself, but we patch it because
# decades of muscle memory expect --debug to apply to this code,
# not the configure script (details are in autosetup/README.md).
#
# 2) In autosetup, all flags starting with (--enable, --disable) are
# forced to be booleans and receive special handling in how they're
# resolved. Because of that we have to rename:
#
# 2.1) --enable-tempstore[=no] to --with-tempstore[=no], noting that
# it has four legal values, not two.
#
########################################################################
# A gentle introduction to flags handling in autosetup
#
# Reference: https://msteveb.github.io/autosetup/developer/
#
# All configure flags must be described in an 'options' call, which
# must appear very early on in this script. The general syntax is:
#
# FLAG => {Help text}
#
# Where FLAG can have any of the following formats:
#
# boolopt => "a boolean option which defaults to disabled"
# boolopt2=1 => "a boolean option which defaults to enabled"
# stringopt: => "an option which takes an argument, e.g. --stringopt=value"
# stringopt2:=value => "an option where the argument is optional and defaults to 'value'"
# optalias booltopt3 => "a boolean with a hidden alias. --optalias is not shown in --help"
#
# Autosetup does no small amount of specialized handling for flags,
# especially booleans. Each bool-type --FLAG implicitly gets
# --enable-FLAG and --disable-FLAG forms. e.g. we define a flag
# "readline", which will be interpreted in one of two ways, depending
# on how it's invoked and how its default is defined:
#
# --enable-readline ==> boolean true
# --disable-readline ==> boolean false
#
# Passing --readline or --readline=1 is equivalent to passing
# --enable-readline, and --readline=0 is equivalent to
# --disable-readline.
#
# The behavior described above can lead lead to some confusion when
# writing help text. For example:
#
# options { json=1 {Disable JSON functions} }
#
# The reason the help text says "disable" is because a boolean option
# which defaults to true is, in the --help text, rendered as:
#
# --disable-json Disable JSON functions
#
# Whereas a bool flag which defaults to false will instead render as:
#
# --enable-FLAG
#
# Non-boolean flags, in contrast, use the names specifically given to
# them in the [options] invocation. e.g. "with-tcl" is the --with-tcl
# flag.
#
# Fetching values for flags:
#
# booleans: use one of:
# - [opt-bool FLAG] is autosetup's built-in command for this, but we
# have some convenience variants:
# - [proj-opt-truthy FLAG]
# - [proj-opt-if-truthy FLAG {THEN} {ELSE}]
#
# Non-boolean (i.e. string) flags:
# - [opt-val FLAG ?default?]
# - [opt-str ...] - see the docs in ./autosetup/autosetup
#
########################################################################
set flags {
# When writing {help text blocks}, be aware that autosetup formats
# them differently (left-aligned, directly under the --flag) if the
# block starts with a newline. It does NOT expand vars and commands,
# but we use a [subst] call below which will replace (only) var
# refs.
proj-define-for-opt linemacros AMALGAMATION_LINE_MACROS \
"Use #line macros in the amalgamation:"
# <build-modes>
shared=1 => {Disable build of shared libary}
static=1 => {Disable build of static library (mostly)}
amalgamation=1 => {Disable the amalgamation and instead build all files separately.}
# </build-modes>
# <lib-feature>
threadsafe=1 => {Disable mutexing}
with-tempstore:=no => {Use an in-RAM database for temporary tables: never,no,yes,always}
largefile=1 => {Disable large file support}
load-extension=1 => {Disable loading of external extensions}
math=1 => {Disable math functions}
json=1 => {Disable JSON functions}
memsys5 => {Enable MEMSYS5}
memsys3 => {Enable MEMSYS3}
fts3 => {Enable the FTS3 extension}
fts4 => {Enable the FTS4 extension}
fts5 => {Enable the FTS5 extension}
update-limit => {Enable the UPDATE/DELETE LIMIT clause}
geopoly => {Enable the GEOPOLY extension}
rtree => {Enable the RTREE extension}
session => {Enable the SESSION extension}
all => {Enable FTS4, FTS5, Geopoly, RTree, Sessions}
# </lib-feature>
# <tcl>
with-tcl:DIR =>
{Directory containing tclConfig.sh or a directory one level up from
that, from which we can derive a directory containing tclConfig.sh.
A dir name of "prefix" is equivalent to the directory specified by
the --prefix flag.}
with-tclsh:PATH =>
{Full pathname of tclsh to use. It is used for (A) trying to find
tclConfig.sh and (B) all TCL-based code generation. Warning: if
its containing dir has multiple tclsh versions, it may select the
wrong tclConfig.sh!}
tcl=1 =>
{Disable components which require TCL, including all tests.
This tree requires TCL for code generation but can use the in-tree
copy of autosetup/jimsh0.c for that. The SQLite TCL extension and the
test code require a canonical tclsh.}
# <tcl>
# <line-editing>
readline=1 => {Disable readline support}
# --with-readline-lib is a backwards-compatible alias for
# --with-readline-ldflags
with-readline-lib:
with-readline-ldflags:=auto
=> {Readline LDFLAGS, e.g. -lreadline -lncurses}
# --with-readline-inc is a backwards-compatible alias for
# --with-readline-cflags.
with-readline-inc:
with-readline-cflags:=auto
=> {Readline CFLAGS, e.g. -I/path/to/includes}
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 => {Enable BSD editline support}
# </line-editing>
# <icu>
with-icu-ldflags:LDFLAGS
=> {Enable SQLITE_ENABLE_ICU and add the given linker flags for the ICU libraries}
with-icu-cflags:CFLAGS
=> {Apply extra CFLAGS/CPPFLAGS necessary for building with ICU. e.g. -I/usr/local/include}
with-icu-config:=auto => {Enable SQLITE_ENABLE_ICU. Value must be one of: auto, pkg-config, /path/to/icu-config}
icu-collations=0 => {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-ldflags=... or --with-icu-config}
# </icu>
# <alternative-builds>
with-wasi-sdk:=/opt/wasi-sdk
=> {Top-most dir of the wasi-sdk for a WASI build}
with-emsdk:=auto => {Top-most dir of the Emscripten SDK installation. Default = EMSDK env var.}
# </alternative-builds>
# <developer>
# Note that using the --debug/--enable-debug flag here requires patching
# autosetup/autosetup to rename the --debug to --autosetup-debug.
with-debug=0
debug=0 =>
{Enable debug build flags. This option will impact performance by
as much as 4x, as it includes large numbers of assert()s in
performance-critical loops. Never use --debug for production
builds.}
scanstatus => {Enable the SQLITE_ENABLE_STMT_SCANSTATUS feature flag}
dev => {Enable dev-mode build: automatically enables certain other flags}
test-status => {Enable status of tests}
gcov=0 => {Enable coverage testing using gcov}
linemacros => {Enable #line macros in the amalgamation}
dynlink-tools => {Dynamically link libsqlite3 to certain tools which normally statically embed it.}
soname:=legacy =>
# --soname has a long story behind it: https://sqlite.org/src/forumpost/5a3b44f510df8ded
{SONAME for libsqlite3.so. "none", or not using this flag, sets no
soname. "legacy" sets it to its historical value of
libsqlite3.so.0. A value matching the glob "libsqlite3.*" sets
it to that literal value. Any other value is assumed to be a
suffix which gets applied to "libsqlite3.so.",
e.g. --soname=9.10 equates to "libsqlite3.so.9.10".
}
dump-defines=0 => {Dump autosetup defines to $::sqliteConfig(dump-defines-txt) (for build debugging)}
# </developer>
}
if {"" ne $::sqliteConfig(dump-defines-json)} {
lappend flags \
defines-json-include-lowercase=0 \
=> {Include lower-case defines (primarily system paths) in $::sqliteConfig(dump-defines-json)}
}
define AMALGAMATION_EXTRA_SRC \
[join [opt-val amalgamation-extra-src ""] " "]
options [subst -nobackslashes -nocommands $flags]
unset flags
sqlite-post-options-init
define LINK_TOOLS_DYNAMICALLY [proj-opt-was-provided dynlink-tools]
sqlite-setup-default-cflags
proj-if-opt-truthy dev {
# --enable-dev needs to come early so that the downstream tests
# which check for the following flags use their updated state.
proj-opt-set all 1
proj-opt-set debug 1
proj-opt-set amalgamation 0
define CFLAGS [get-env CFLAGS {-O0 -g}]
# -------------^^^^^^^ intentionally using [get-env] instead of
# [proj-get-env] here because [sqlite-setup-default-cflags] uses
# [proj-get-env] and we want this to supercede that.
}
if {[set fsan [join [opt-val asan-fsanitize] ","]] in {auto ""}} {
set fsan address,bounds-strict
}
define CFLAGS_ASAN_FSANITIZE [proj-check-fsanitize [split $fsan ", "]]
sqlite-check-common-bins ;# must come before [sqlite-handle-wasi-sdk]
sqlite-handle-wasi-sdk ;# must run relatively early, as it changes the environment
sqlite-check-common-system-deps
sqlite-handle-tcl
sqlite-handle-emsdk
#
# Enable large file support (if special flags are necessary)
#
define HAVE_LFS 0
if {[opt-bool largefile]} {
cc-check-lfs
}
proj-if-opt-truthy static-shells {
proj-opt-set static-tclsqlite3 1
proj-opt-set static-cli-shell 1
}
proj-define-for-opt static-tclsqlite3 STATIC_TCLSQLITE3 "Statically link tclsqlite3?"
proj-define-for-opt static-cli-shell STATIC_CLI_SHELL "Statically link CLI shell?"
proj-define-for-opt shared ENABLE_SHARED "Build shared library?"
}; # sqlite-configure
if {![proj-define-for-opt static ENABLE_STATIC \
"Build static library?"]} {
proj-warn "Static lib build may be implicitly re-activated by other components, e.g. some test apps."
}
proj-define-for-opt amalgamation USE_AMALGAMATION "Use amalgamation for builds?"
proj-define-for-opt gcov USE_GCOV "Use gcov?"
proj-define-for-opt test-status TSTRNNR_OPTS \
"test-runner flags:" {--status} {}
proj-define-for-opt linemacros AMALGAMATION_LINE_MACROS \
"Use #line macros in the amalgamation:"
define LINK_TOOLS_DYNAMICALLY [proj-opt-was-provided dynlink-tools]
proj-check-rpath
sqlite-handle-soname
sqlite-handle-debug
sqlite-handle-tcl
sqlite-handle-threadsafe
sqlite-handle-tempstore
sqlite-handle-line-editing
sqlite-handle-load-extension
sqlite-handle-math
sqlite-handle-icu
sqlite-handle-emsdk
sqlite-common-late-stage-config
sqlite-dump-defines
+56 -107
View File
@@ -50,7 +50,6 @@ CC = @CC@
ENABLE_LIB_SHARED = @ENABLE_LIB_SHARED@
ENABLE_LIB_STATIC = @ENABLE_LIB_STATIC@
HAVE_WASI_SDK = @HAVE_WASI_SDK@
CFLAGS = @CFLAGS@ @CPPFLAGS@
#
@@ -68,12 +67,14 @@ LDFLAGS.pthread = @LDFLAGS_PTHREAD@
LDFLAGS.dlopen = @LDFLAGS_DLOPEN@
LDFLAGS.readline = @LDFLAGS_READLINE@
CFLAGS.readline = @CFLAGS_READLINE@
LDFLAGS.rt = @LDFLAGS_RT@
LDFLAGS.icu = @LDFLAGS_ICU@
CFLAGS.icu = @CFLAGS_ICU@
# INSTALL reminder: we specifically do not strip binaries,
# as discussed in https://sqlite.org/forum/forumpost/9a67df63eda9925c.
# When cross-compiling, we need to avoid the -s flag because it only
# works on the build host's platform.
INSTALL.strip.1 = $(INSTALL)
INSTALL.strip.0 = $(INSTALL) -s
INSTALL.strip = $(INSTALL.strip.@IS_CROSS_COMPILING@)
INSTALL.noexec = $(INSTALL) -m 0644
install-dir.bin = $(DESTDIR)$(bindir)
@@ -85,7 +86,7 @@ install-dir.all = $(install-dir.bin) $(install-dir.include) \
$(install-dir.lib) $(install-dir.man1) \
$(install-dir.pkgconfig)
$(install-dir.all):
@if [ ! -d "$@" ]; then set -x; $(INSTALL) -d "$@"; fi
if [ ! -d "$@" ]; then $(INSTALL) -d "$@"; fi
# ^^^^ on some platforms, install -d fails if the target already exists.
@@ -125,92 +126,67 @@ OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@
LDFLAGS.libsqlite3.soname = @LDFLAGS_LIBSQLITE3_SONAME@
# soname: see https://sqlite.org/src/forumpost/5a3b44f510df8ded
LDFLAGS.libsqlite3.os-specific = \
@LDFLAGS_MAC_CVERSION@ @LDFLAGS_MAC_INSTALL_NAME@ @LDFLAGS_OUT_IMPLIB@
LDFLAGS.libsqlite3.os-specific = @LDFLAGS_MAC_CVERSION@ @LDFLAGS_OUT_IMPLIB@
# os-specific: see
# - https://sqlite.org/forum/forumpost/9dfd5b8fd525a5d7
# - https://sqlite.org/forum/forumpost/0c7fc097b2
LDFLAGS.libsqlite3 = \
$(LDFLAGS.rpath) $(LDFLAGS.pthread) \
$(LDFLAGS.math) $(LDFLAGS.dlopen) \
$(LDFLAGS.zlib) $(LDFLAGS.icu) \
$(LDFLAGS.rt) $(LDFLAGS.configure)
$(LDFLAGS.configure)
CFLAGS.libsqlite3 = -I. $(CFLAGS.core) $(CFLAGS.icu) $(OPT_FEATURE_FLAGS)
sqlite3.o: $(TOP)/sqlite3.h $(TOP)/sqlite3.c
$(CC) -c $(TOP)/sqlite3.c -o $@ $(CFLAGS) $(CFLAGS.libsqlite3)
libsqlite3.LIB = libsqlite3$(T.lib)
libsqlite3.DLL.basename = @SQLITE_DLL_BASENAME@
libsqlite3.out.implib = @SQLITE_OUT_IMPLIB@
libsqlite3.DLL = $(libsqlite3.DLL.basename)$(T.dll)
libsqlite3.DLL.install-rules = @SQLITE_DLL_INSTALL_RULES@
libsqlite3.SO = libsqlite3$(T.dll)
$(libsqlite3.DLL): sqlite3.o
$(libsqlite3.SO): sqlite3.o
$(CC) -o $@ sqlite3.o $(LDFLAGS.shlib) \
$(LDFLAGS) $(LDFLAGS.libsqlite3) \
$(LDFLAGS.libsqlite3.os-specific) $(LDFLAGS.libsqlite3.soname)
$(libsqlite3.DLL)-1: $(libsqlite3.DLL)
$(libsqlite3.DLL)-0:
all: $(libsqlite3.DLL)-$(ENABLE_LIB_SHARED)
all: $(libsqlite3.SO)
$(libsqlite3.LIB): sqlite3.o
$(AR) $(AR.flags) $@ sqlite3.o
$(libsqlite3.LIB)-1: $(libsqlite3.LIB)
$(libsqlite3.LIB)-0:
all: $(libsqlite3.LIB)-$(ENABLE_LIB_STATIC)
all: $(libsqlite3.LIB)
#
# Maintenance reminder: the install-dll-... rules must be kept in sync
# with the main copies rom /main.mk.
#
install-dll-out-implib: $(install-dir.lib) $(libsqlite3.DLL)
if [ x != "x$(libsqlite3.out.implib)" ] && [ -f "$(libsqlite3.out.implib)" ]; then \
$(INSTALL) $(libsqlite3.out.implib) "$(install-dir.lib)"; \
install-so-1: $(install-dir.lib) $(libsqlite3.SO)
$(INSTALL) $(libsqlite3.SO) "$(install-dir.lib)"
@echo "Setting up $(libsqlite3.SO) version symlinks..."; \
cd "$(install-dir.lib)" || exit $$?; \
if [ x.dylib = x$(T.dll) ]; then \
rm -f libsqlite3.0$(T.dll) libsqlite3.$(PACKAGE_VERSION)$(T.dll) || exit $$?; \
dllname=libsqlite3.$(PACKAGE_VERSION)$(T.dll); \
mv $(libsqlite3.SO) $$dllname || exit $$?; \
ln -s $$dllname $(libsqlite3.SO) || exit $$?; \
ln -s $$dllname libsqlite3.0$(T.dll) || exit $$?; \
ls -la $$dllname $(libsqlite3.SO) libsqlite3.0$(T.dll); \
else \
rm -f $(libsqlite3.SO).0 $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \
mv $(libsqlite3.SO) $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \
ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO) || exit $$?; \
ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0 || exit $$?; \
ls -la $(libsqlite3.SO) $(libsqlite3.SO).[03]*; \
if [ -e $(libsqlite3.SO).0.8.6 ]; then \
echo "ACHTUNG: legacy libtool-compatible install found. Re-linking it..."; \
rm -f libsqlite3.la $(libsqlite3.SO).0.8.6 || exit $$?; \
ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \
ls -la $(libsqlite3.SO).0.8.6; \
elif [ x1 = "x$(INSTALL_SO_086_LINK)" ]; then \
echo "ACHTUNG: installing legacy libtool-style links because INSTALL_SO_086_LINK=1"; \
rm -f libsqlite3.la $(libsqlite3.SO).0.8.6 || exit $$?; \
ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0.8.6 || exit $$?; \
ls -la $(libsqlite3.SO).0.8.6; \
fi; \
fi
install-dll-unix-generic: install-dll-out-implib
$(INSTALL) $(libsqlite3.DLL) "$(install-dir.lib)"
@echo "Setting up $(libsqlite3.DLL) version symlinks..."; \
cd "$(install-dir.lib)" || exit $$?; \
rm -f $(libsqlite3.DLL).0 $(libsqlite3.DLL).$(PACKAGE_VERSION) || exit $$?; \
mv $(libsqlite3.DLL) $(libsqlite3.DLL).$(PACKAGE_VERSION) || exit $$?; \
ln -s $(libsqlite3.DLL).$(PACKAGE_VERSION) $(libsqlite3.DLL) || exit $$?; \
ln -s $(libsqlite3.DLL).$(PACKAGE_VERSION) $(libsqlite3.DLL).0 || exit $$?; \
ls -la $(libsqlite3.DLL) $(libsqlite3.DLL).[a03]*; \
if [ -e $(libsqlite3.DLL).0.8.6 ]; then \
echo "ACHTUNG: legacy libtool-compatible install found. Re-linking it..."; \
rm -f libsqlite3.la $(libsqlite3.DLL).0.8.6 || exit $$?; \
ln -s $(libsqlite3.DLL).$(PACKAGE_VERSION) $(libsqlite3.DLL).0.8.6 || exit $$?; \
ls -la $(libsqlite3.DLL).0.8.6; \
elif [ x1 = "x$(INSTALL_SO_086_LINK)" ]; then \
echo "ACHTUNG: installing legacy libtool-style links because INSTALL_SO_086_LINK=1"; \
rm -f libsqlite3.la $(libsqlite3.DLL).0.8.6 || exit $$?; \
ln -s $(libsqlite3.DLL).$(PACKAGE_VERSION) $(libsqlite3.DLL).0.8.6 || exit $$?; \
ls -la $(libsqlite3.DLL).0.8.6; \
fi
install-dll-msys: install-dll-out-implib $(install-dir.bin)
$(INSTALL) $(libsqlite3.DLL) "$(install-dir.bin)"
# ----------------------------------------------^^^ yes, bin
# Each of {msys,mingw,cygwin} uses a different name for the DLL, but
# that is already accounted for via $(libsqlite3.DLL).
install-dll-mingw: install-dll-msys
install-dll-cygwin: install-dll-msys
install-dll-darwin: $(install-dir.lib) $(libsqlite3.DLL)
$(INSTALL) $(libsqlite3.DLL) "$(install-dir.lib)"
@echo "Setting up $(libsqlite3.DLL) version symlinks..."; \
cd "$(install-dir.lib)" || exit $$?; \
rm -f libsqlite3.0$(T.dll) libsqlite3.$(PACKAGE_VERSION)$(T.dll) || exit $$?; \
dllname=libsqlite3.$(PACKAGE_VERSION)$(T.dll); \
mv $(libsqlite3.DLL) $$dllname || exit $$?; \
ln -s $$dllname $(libsqlite3.DLL) || exit $$?; \
ln -s $$dllname libsqlite3.0$(T.dll) || exit $$?; \
ls -la $$dllname $(libsqlite3.DLL) libsqlite3.0$(T.dll)
install-dll-1: install-dll-$(libsqlite3.DLL.install-rules)
install-dll-0 install-dll-:
install-dll: install-dll-$(ENABLE_LIB_SHARED)
install: install-dll
install-so-0 install-so-:
install-so: install-so-$(ENABLE_LIB_SHARED)
install: install-so
install-lib-1: $(install-dir.lib) $(libsqlite3.LIB)
$(INSTALL.noexec) $(libsqlite3.LIB) "$(install-dir.lib)"
@@ -218,43 +194,18 @@ install-lib-0 install-lib-:
install-lib: install-lib-$(ENABLE_LIB_STATIC)
install: install-lib
#
# Flags to link the shell app either directly against sqlite3.c
# (ENABLE_STATIC_SHELL==1) or libsqlite3.so (ENABLE_STATIC_SHELL==0).
#
ENABLE_STATIC_SHELL = @ENABLE_STATIC_SHELL@
sqlite3-shell-link-flags.1 = $(TOP)/sqlite3.c $(LDFLAGS.libsqlite3)
sqlite3-shell-link-flags.0 = -L. -lsqlite3 $(LDFLAGS.zlib)
sqlite3-shell-deps.1 = $(TOP)/sqlite3.c
sqlite3-shell-deps.0 = $(libsqlite3.DLL)
#
# STATIC_CLI_SHELL = 1 to statically link sqlite3$(T.exe), else
# 0. Requires static versions of all requisite libraries. Primarily
# intended for use with static-friendly environments like Alpine
# Linux.
#
STATIC_CLI_SHELL = @STATIC_CLI_SHELL@
#
# sqlite3-shell-static.flags.N = N is $(STATIC_CLI_SHELL)
#
sqlite3-shell-static.flags.1 = -static
sqlite3-shell-static.flags.0 =
sqlite3$(T.exe): $(TOP)/shell.c $(sqlite3-shell-deps.$(ENABLE_STATIC_SHELL))
sqlite3$(T.exe): $(TOP)/shell.c $(TOP)/sqlite3.c
$(CC) -o $@ \
$(TOP)/shell.c $(sqlite3-shell-link-flags.$(ENABLE_STATIC_SHELL)) \
$(sqlite3-shell-static.flags.$(STATIC_CLI_SHELL)) \
$(TOP)/shell.c $(TOP)/sqlite3.c \
-I. $(OPT_FEATURE_FLAGS) $(SHELL_OPT) \
$(CFLAGS) $(CFLAGS.readline) $(CFLAGS.icu) \
$(LDFLAGS) $(LDFLAGS.readline)
$(LDFLAGS) $(LDFLAGS.libsqlite3) $(LDFLAGS.readline)
all: sqlite3$(T.exe)
sqlite3$(T.exe)-1:
sqlite3$(T.exe)-0: sqlite3$(T.exe)
all: sqlite3$(T.exe)-$(HAVE_WASI_SDK)
install-shell-0: sqlite3$(T.exe) $(install-dir.bin)
$(INSTALL) sqlite3$(T.exe) "$(install-dir.bin)"
install-shell-1:
install: install-shell-$(HAVE_WASI_SDK)
install-shell: sqlite3$(T.exe) $(install-dir.bin)
$(INSTALL.strip) sqlite3$(T.exe) "$(install-dir.bin)"
install: install-shell
install-headers: $(TOP)/sqlite3.h $(install-dir.include)
$(INSTALL.noexec) $(TOP)/sqlite3.h $(TOP)/sqlite3ext.h "$(install-dir.include)"
@@ -270,10 +221,10 @@ install: install-man1
clean:
rm -f *.o sqlite3$(T.exe)
rm -f $(libsqlite3.LIB) $(libsqlite3.DLL) libsqlite3$(T.dll).a
rm -f $(libsqlite3.LIB) $(libsqlite3.SO) $(libsqlite3.SO).a
distclean: clean
rm -f jimsh0$(T.exe) config.* sqlite3.pc sqlite_cfg.h Makefile
rm -f jimsh0$(T.exe) config.* sqlite3.pc
DIST_FILES := \
README.txt VERSION \
@@ -283,10 +234,8 @@ DIST_FILES := \
sqlite3.rc sqlite3rc.h Replace.cs \
sqlite3.pc.in sqlite3.1
#
# Maintenance note: dist_name must be sqlite-$(PACKAGE_VERSION) so
# that tool/mkautoconfamal.sh knows how to find it.
#
dist_name = sqlite-$(PACKAGE_VERSION)
dist_tarball = $(dist_name).tar.gz
dist:
+1 -11
View File
@@ -247,12 +247,6 @@ SESSION = 0
RBU = 0
!ENDIF
# Set this to non-0 to enable support for blocking locks.
#
!IFNDEF SETLK_TIMEOUT
SETLK_TIMEOUT = 0
!ENDIF
# Set the source code file to be used by executables and libraries when
# they need the amalgamation.
#
@@ -378,10 +372,6 @@ EXT_FEATURE_FLAGS =
!ENDIF
!ENDIF
!IF $(SETLK_TIMEOUT)!=0
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SETLK_TIMEOUT
!ENDIF
###############################################################################
############################### END OF OPTIONS ################################
###############################################################################
@@ -1098,5 +1088,5 @@ $(LIBRESOBJS): $(TOP)\sqlite3.rc rcver.vc $(SQLITE3H)
clean:
del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
del /Q *.bsc *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
del /Q sqlite3.def tclsqlite3.def ctime.c pragma.h 2>NUL
del /Q sqlite3.def tclsqlite3.def 2>NUL
del /Q $(SQLITE3EXE) $(SQLITE3DLL) Replace.exe 2>NUL
+2 -2
View File
@@ -27,7 +27,7 @@ the embedded copy of JimTCL).
REASONS TO USE THE CANONICAL BUILD SYSTEM RATHER THAN THIS PACKAGE
==================================================================
* the canonical build system allows you to run tests to verify that
* the cononical build system allows you to run tests to verify that
the build worked
* the canonical build system supports more compile-time options
* the canonical build system works for any arbitrary check-in to
@@ -90,7 +90,7 @@ Other preprocessor defines
Additionally, preprocessor defines may be specified by using the OPTS macro
on the NMAKE command line. However, not all possible preprocessor defines
may be specified in this manner as some require the amalgamation to be built
with them enabled (see http://sqlite.org/compile.html). For example, the
with them enabled (see http://www.sqlite.org/compile.html). For example, the
following will work:
"OPTS=-DSQLITE_ENABLE_STAT4=1 -DSQLITE_OMIT_JSON=1"
+90 -18
View File
@@ -1,25 +1,97 @@
#!/do/not/tclsh
#/do/not/tclsh
# ^^^ help out editors which guess this file's content type.
#
# This is the main autosetup-compatible configure script for the
# "autoconf" bundle of the SQLite project.
#
# This script must be kept compatible with JimTCL, a copy of which is
# included in this source tree as ./autosetup/jimsh0.c.
#
use sqlite-config
sqlite-configure autoconf {
sqlite-handle-debug
sqlite-check-common-bins ;# must come before [sqlite-handle-wasi-sdk]
sqlite-handle-wasi-sdk ;# must run relatively early, as it changes the environment
sqlite-check-common-system-deps
proj-define-for-opt static-shell ENABLE_STATIC_SHELL \
"Link library statically into the CLI shell?"
proj-define-for-opt static-cli-shell STATIC_CLI_SHELL "Statically link CLI shell?"
if {![opt-bool static-shell] && [opt-bool static-cli-shell]} {
proj-fatal "--disable-static-shell and --static-cli-shell are mutualy exclusive"
}
if {![opt-bool shared] && ![opt-bool static-shell]} {
proj-opt-set shared 1
proj-indented-notice {
NOTICE: ignoring --disable-shared because --disable-static-shell
was specified.
options {
# <build-modes>
static=1 => {Disable build of static library}
shared=1 => {Disable build of shared library}
# </build-modes>
# <lib-feature>
threadsafe=1 => {Disable mutexing}
with-tempstore:=no => {Use an in-RAM database for temporary tables: never,no,yes,always}
load-extension=1 => {Disable loading of external extensions}
math=1 => {Disable math functions}
json=1 => {Disable JSON functions}
memsys5 => {Enable MEMSYS5}
memsys3 => {Enable MEMSYS3}
fts3 => {Enable the FTS3 extension}
fts4 => {Enable the FTS4 extension}
fts5 => {Enable the FTS5 extension}
update-limit => {Enable the UPDATE/DELETE LIMIT clause}
geopoly => {Enable the GEOPOLY extension}
rtree => {Enable the RTREE extension}
session => {Enable the SESSION extension}
all => {Enable FTS4, FTS5, Geopoly, RTree, Sessions}
# </lib-feature>
# <line-editing>
readline=1 => {Disable readline support}
# --with-readline-lib is a backwards-compatible alias for
# --with-readline-ldflags
with-readline-lib:
with-readline-ldflags:=auto
=> {Readline LDFLAGS, e.g. -lreadline -lncurses}
# --with-readline-inc is a backwards-compatible alias for
# --with-readline-cflags.
with-readline-inc:
with-readline-cflags:=auto
=> {Readline CFLAGS, e.g. -I/path/to/includes}
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 => {Enable BSD editline support}
# </line-editing>
# <icu>
with-icu-ldflags:LDFLAGS
=> {Enable SQLITE_ENABLE_ICU and add the given linker flags for the ICU libraries}
with-icu-cflags:CFLAGS
=> {Apply extra CFLAGS/CPPFLAGS necessary for building with ICU. e.g. -I/usr/local/include}
with-icu-config:=auto => {Enable SQLITE_ENABLE_ICU. Value must be one of: auto, pkg-config, /path/to/icu-config}
icu-collations=0 => {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-ldflags=... or --with-icu-config}
# </icu>
# <developer>
# Note that using the --debug/--enable-debug flag here requires patching
# autosetup/autosetup to rename the --debug to --autosetup-debug.
with-debug=0
debug=0 =>
{Enable debug build flags. This option will impact performance by
as much as 4x, as it includes large numbers of assert()s in
performance-critical loops. Never use --debug for production
builds.}
# </developer>
soname:=legacy =>
# --soname has a long story behind it: https://sqlite.org/src/forumpost/5a3b44f510df8ded
{SONAME for libsqlite3.so. "none", or not using this flag, sets no
soname. "legacy" sets it to its historical value of
libsqlite3.so.0. A value matching the glob "libsqlite3.*" sets
it to that literal value. Any other value is assumed to be a
suffix which gets applied to "libsqlite3.so.",
e.g. --soname=9.10 equates to "libsqlite3.so.9.10".
}
}
}
sqlite-post-options-init
sqlite-check-common-bins
sqlite-check-common-system-deps
proj-check-rpath
sqlite-handle-soname
sqlite-setup-default-cflags
sqlite-handle-debug
sqlite-handle-threadsafe
sqlite-handle-tempstore
sqlite-handle-line-editing
sqlite-handle-load-extension
sqlite-handle-math
sqlite-handle-icu
define ENABLE_LIB_SHARED [opt-bool shared]
define ENABLE_LIB_STATIC [opt-bool static]
sqlite-common-late-stage-config
+428 -354
View File
@@ -1,389 +1,463 @@
all:
# Makefile.in --
#
# This makefile is part of the teaish framework, a tool for building
# Tcl extensions, conceptually related to TEA/tclconfig but using the
# Autosetup configuration system instead of the GNU Autotools.
# This file is a Makefile for Sample TEA Extension. If it has the name
# "Makefile.in" then it is a template for a Makefile; to generate the
# actual Makefile, run "./configure", which is a configuration script
# generated by the "autoconf" program (constructs like "@foo@" will get
# replaced in the actual Makefile.
#
# A copy of this makefile gets processed for each extension separately
# and populated with info about how to build, test, and install the
# extension.
#
# Maintenance reminder: this file needs to stay portable with POSIX
# Make, not just GNU Make. Yes, that's unfortunate because it makes
# some things impossible (like skipping over swathes of rules when
# 'make distclean' is invoked).
# Copyright (c) 1999 Scriptics Corporation.
# Copyright (c) 2002-2005 ActiveState Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
CC = @CC@
INSTALL = @BIN_INSTALL@
INSTALL.noexec = $(INSTALL) -m 0644
#========================================================================
# Add additional lines to handle any additional AC_SUBST cases that
# have been added in a customized configure script.
#========================================================================
#
# Var name prefixes:
#
# teaish. => teaish core
# tx. => teaish extension
#
# Vars with a "tx." or "teaish." prefix are all "public" for purposes
# of the extension makefile, but the extension must not any "teaish."
# vars and must only modify "tx." vars where that allowance is
# specifically noted.
#
# Vars with a "teaish__" prefix are "private" and must not be used by
# the extension makefile. They may change semantics or be removed in
# any given teaish build.
#
tx.name = @TEAISH_NAME@
tx.pkgName = @TEAISH_PKGNAME@
tx.version = @TEAISH_VERSION@
tx.libdir = @TEAISH_LIBDIR_NAME@
tx.loadPrefix = @TEAISH_LOAD_PREFIX@
#tx.testScript = @TEAISH_TEST_TCL@
tx.tcl = @TEAISH_TCL@
tx.makefile = @TEAISH_MAKEFILE@
tx.makefile.in = @TEAISH_MAKEFILE_IN@
tx.dll8.basename = @TEAISH_DLL8_BASENAME@
tx.dll9.basename = @TEAISH_DLL9_BASENAME@
tx.dll8 = @TEAISH_DLL8@
tx.dll9 = @TEAISH_DLL9@
tx.dll = $(tx.dll$(TCL_MAJOR_VERSION))
tx.dir = @TEAISH_DIR@
#SAMPLE_NEW_VAR = @SAMPLE_NEW_VAR@
teaish.dir = @abs_top_srcdir@
teaish.dir.autosetup = @TEAISH_AUTOSETUP_DIR@
teaish.makefile = Makefile
teaish.makefile.in = $(teaish.dir)/Makefile.in
teaish__auto.def = $(teaish.dir)/auto.def
#========================================================================
# Nothing of the variables below this line should need to be changed.
# Please check the TARGETS section below to make sure the make targets
# are correct.
#========================================================================
#========================================================================
# The names of the source files is defined in the configure script.
# The object files are used for linking into the final library.
# This will be used when a dist target is added to the Makefile.
# It is not important to specify the directory, as long as it is the
# $(srcdir) or in the generic, win or unix subdirectory.
#========================================================================
PKG_SOURCES = @PKG_SOURCES@
PKG_OBJECTS = @PKG_OBJECTS@
PKG_STUB_SOURCES = @PKG_STUB_SOURCES@
PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@
#========================================================================
# PKG_TCL_SOURCES identifies Tcl runtime files that are associated with
# this package that need to be installed, if any.
#========================================================================
PKG_TCL_SOURCES = @PKG_TCL_SOURCES@
#========================================================================
# This is a list of public header files to be installed, if any.
#========================================================================
PKG_HEADERS = @PKG_HEADERS@
#========================================================================
# "PKG_LIB_FILE" refers to the library (dynamic or static as per
# configuration options) composed of the named objects.
#========================================================================
PKG_LIB_FILE = @PKG_LIB_FILE@
PKG_LIB_FILE8 = @PKG_LIB_FILE8@
PKG_LIB_FILE9 = @PKG_LIB_FILE9@
PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@
lib_BINARIES = $(PKG_LIB_FILE)
BINARIES = $(lib_BINARIES)
SHELL = @SHELL@
srcdir = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
libdir = @libdir@
includedir = @includedir@
datarootdir = @datarootdir@
runstatedir = @runstatedir@
datadir = @datadir@
mandir = @mandir@
DESTDIR =
PKG_DIR = $(PACKAGE_NAME)$(PACKAGE_VERSION)
pkgdatadir = $(datadir)/$(PKG_DIR)
pkglibdir = $(libdir)/$(PKG_DIR)
pkgincludedir = $(includedir)/$(PKG_DIR)
top_builddir = @abs_top_builddir@
INSTALL_OPTIONS =
INSTALL = @INSTALL@ $(INSTALL_OPTIONS)
INSTALL_DATA_DIR = @INSTALL_DATA_DIR@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_LIBRARY = @INSTALL_LIBRARY@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
CC = @CC@
CFLAGS_DEFAULT = @CFLAGS_DEFAULT@
CFLAGS_WARNING = @CFLAGS_WARNING@
EXEEXT = @EXEEXT@
LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@
MAKE_LIB = @MAKE_LIB@
MAKE_STUB_LIB = @MAKE_STUB_LIB@
OBJEXT = @OBJEXT@
RANLIB = @RANLIB@
RANLIB_STUB = @RANLIB_STUB@
SHLIB_CFLAGS = @SHLIB_CFLAGS@
SHLIB_LD = @SHLIB_LD@
SHLIB_LD_LIBS = @SHLIB_LD_LIBS@
STLIB_LD = @STLIB_LD@
#TCL_DEFS = @TCL_DEFS@
TCL_BIN_DIR = @TCL_BIN_DIR@
TCL_SRC_DIR = @TCL_SRC_DIR@
#TK_BIN_DIR = @TK_BIN_DIR@
#TK_SRC_DIR = @TK_SRC_DIR@
# Not used, but retained for reference of what libs Tcl required
#TCL_LIBS = @TCL_LIBS@
#========================================================================
# TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our
# package without installing. The other environment variables allow us
# to test against an uninstalled Tcl. Add special env vars that you
# require for testing here (like TCLX_LIBRARY).
#========================================================================
EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR)
#EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
TCLLIBPATH = $(top_builddir)
TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library`
PKG_ENV = @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
PATH="$(EXTRA_PATH):$(PATH)" \
TCLLIBPATH="$(TCLLIBPATH)"
TCLSH_PROG = @TCLSH_PROG@
TCLSH = $(TCLSH_ENV) $(PKG_ENV) $(TCLSH_PROG)
#WISH_ENV = TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library`
#WISH_PROG = @WISH_PROG@
#WISH = $(TCLSH_ENV) $(WISH_ENV) $(PKG_ENV) $(WISH_PROG)
SHARED_BUILD = @SHARED_BUILD@
INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ -I. -I$(srcdir)/..
#INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@
PKG_CFLAGS = @PKG_CFLAGS@
# TCL_DEFS is not strictly need here, but if you remove it, then you
# must make sure that configure.ac checks for the necessary components
# that your library may use. TCL_DEFS can actually be a problem if
# you do not compile with a similar machine setup as the Tcl core was
# compiled with.
#DEFS = $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS)
DEFS = @DEFS@ $(PKG_CFLAGS)
# Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile
CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl
CLEANFILES = @CLEANFILES@
CPPFLAGS = @CPPFLAGS@
LIBS = @PKG_LIBS@ @LIBS@
AR = @AR@
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) \
$(CFLAGS_DEFAULT) $(CFLAGS_WARNING) $(SHLIB_CFLAGS) $(CFLAGS)
GDB = gdb
VALGRIND = valgrind
VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high \
--leak-check=yes --show-reachable=yes -v
.SUFFIXES: .c .$(OBJEXT)
#========================================================================
# Start of user-definable TARGETS section
#========================================================================
#========================================================================
# TEA TARGETS. Please note that the "libraries:" target refers to platform
# independent files, and the "binaries:" target includes executable programs and
# platform-dependent libraries. Modify these targets so that they install
# the various pieces of your package. The make and install rules
# for the BINARIES that you specified above have already been done.
#========================================================================
all: binaries libraries doc
#========================================================================
# The binaries target builds executable programs, Windows .dll's, unix
# shared/static libraries, and any other platform-dependent files.
# The list of targets to build for "binaries:" is specified at the top
# of the Makefile, in the "BINARIES" variable.
#========================================================================
binaries: $(BINARIES)
libraries:
#========================================================================
# Your doc target should differentiate from doc builds (by the developer)
# and doc installs (see install-doc), which just install the docs on the
# end user machine when building from source.
#========================================================================
doc:
@echo "If you have documentation to create, place the commands to"
@echo "build the docs in the 'doc:' target. For example:"
@echo " xml2nroff sample.xml > sample.n"
@echo " xml2html sample.xml > sample.html"
install: all install-binaries install-libraries install-doc
install-binaries: binaries install-lib-binaries install-bin-binaries
#========================================================================
# This rule installs platform-independent files, such as header files.
# The list=...; for p in $$list handles the empty list case x-platform.
#========================================================================
install-libraries: libraries
@$(INSTALL_DATA_DIR) "$(DESTDIR)$(includedir)"
@echo "Installing header files in $(DESTDIR)$(includedir)"
@list='$(PKG_HEADERS)'; for i in $$list; do \
echo "Installing $(srcdir)/$$i" ; \
$(INSTALL_DATA) $(srcdir)/$$i "$(DESTDIR)$(includedir)" ; \
done;
#========================================================================
# Install documentation. Unix manpages should go in the $(mandir)
# directory.
#========================================================================
install-doc: doc
@$(INSTALL_DATA_DIR) "$(DESTDIR)$(mandir)/mann"
@echo "Installing documentation in $(DESTDIR)$(mandir)"
@list='$(srcdir)/doc/*.n'; for i in $$list; do \
echo "Installing $$i"; \
$(INSTALL_DATA) $$i "$(DESTDIR)$(mandir)/mann" ; \
done
test: binaries libraries
@echo "SQLite TEA distribution does not include tests"
shell: binaries libraries
@$(TCLSH) $(SCRIPT)
gdb:
$(TCLSH_ENV) $(PKG_ENV) $(GDB) $(TCLSH_PROG) $(SCRIPT)
gdb-test: binaries libraries
$(TCLSH_ENV) $(PKG_ENV) $(GDB) \
--args $(TCLSH_PROG) `@CYGPATH@ $(srcdir)/tests/all.tcl` \
$(TESTFLAGS) -singleproc 1 \
-load "package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \
[list load `@CYGPATH@ $(PKG_LIB_FILE)` [string totitle $(PACKAGE_NAME)]]"
valgrind: binaries libraries
$(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) \
`@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS)
valgrindshell: binaries libraries
$(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT)
depend:
#========================================================================
# $(PKG_LIB_FILE) should be listed as part of the BINARIES variable
# mentioned above. That will ensure that this target is built when you
# run "make binaries".
#
# Autotools-conventional vars. We don't actually use these in this
# makefile but some may be referenced by vars imported via
# tclConfig.sh. They are part of the public API and may be reliably
# depended on from teaish.make.in.
# The $(PKG_OBJECTS) objects are created and linked into the final
# library. In most cases these object files will correspond to the
# source files above.
#========================================================================
$(PKG_LIB_FILE): $(PKG_OBJECTS)
-rm -f $(PKG_LIB_FILE)
${MAKE_LIB}
$(RANLIB) $(PKG_LIB_FILE)
$(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS)
-rm -f $(PKG_STUB_LIB_FILE)
${MAKE_STUB_LIB}
$(RANLIB_STUB) $(PKG_STUB_LIB_FILE)
#========================================================================
# We need to enumerate the list of .c to .o lines here.
#
bindir = @bindir@
datadir = @datadir@
exec_prefix = @exec_prefix@
includedir = @includedir@
infodir = @infodir@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
# In the following lines, $(srcdir) refers to the toplevel directory
# containing your extension. If your sources are in a subdirectory,
# you will have to modify the paths to reflect this:
#
# sample.$(OBJEXT): $(srcdir)/generic/sample.c
# $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@
#
# Setting the VPATH variable to a list of paths will cause the makefile
# to look into these paths when resolving .c to .obj dependencies.
# As necessary, add $(srcdir):$(srcdir)/compat:....
#========================================================================
VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win:$(srcdir)/macosx
.c.@OBJEXT@:
$(COMPILE) -c `@CYGPATH@ $<` -o $@
#
# Vars derived (mostly) from tclConfig.sh. These may be reliably
# used from the extension makefile.
#
TCLSH = @TCLSH_CMD@
TCL_CONFIG_SH = @TCL_CONFIG_SH@
TCL_INCLUDE_SPEC = @TCL_INCLUDE_SPEC@
TCL_LIB_SPEC = @TCL_LIB_SPEC@
TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@
TCL_EXEC_PREFIX = @TCL_EXEC_PREFIX@
TCL_VERSION = @TCL_VERSION@
TCL_MAJOR_VERSION = @TCL_MAJOR_VERSION@
TCL_MINOR_VERSION = @TCL_MINOR_VERSION@
TCL_PATCH_LEVEL = @TCL_PATCH_LEVEL@
TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
TCL_LIBS = @TCL_LIBS@
TCLLIBDIR = @TCLLIBDIR@
#========================================================================
# Distribution creation
# You may need to tweak this target to make it work correctly.
#========================================================================
#
# CFLAGS.configure = CFLAGS as known at configure-time.
#
# This ordering is deliberate: flags populated via tcl's
# [teaish-add-cflags] should preceed CFLAGS and CPPFLAGS (which
# typically come from the ./configure command-line invocation).
#
CFLAGS.configure = @SH_CFLAGS@ @TEAISH_CFLAGS@ @CFLAGS@ @CPPFLAGS@ $(TCL_INCLUDE_SPEC)
#CFLAGS.configure += -DUSE_TCL_STUBS=1
#COMPRESS = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar
COMPRESS = tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR)
DIST_ROOT = /tmp/dist
DIST_DIR = $(DIST_ROOT)/$(PKG_DIR)
#
# LDFLAGS.configure = LDFLAGS as known at configure-time.
#
# This ordering is deliberate: flags populated via tcl's
# [teaish-add-ldflags] should preceed LDFLAGS (which typically
# comes from the ./configure command-line invocation).
#
LDFLAGS.configure = @SH_LDFLAGS@ @TEAISH_LDFLAGS@ @LDFLAGS@ $(TCL_STUB_LIB_SPEC)
DIST_INSTALL_DATA = CPPROG='cp -p' $(INSTALL) -m 644
DIST_INSTALL_SCRIPT = CPPROG='cp -p' $(INSTALL) -m 755
#
# The following tx.XYZ vars may be populated/modified by teaish.tcl
# and/or teaish.make.
#
dist-clean:
rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.*
#
# tx.src is the list of source or object files to include in the
# (single) compiler invocation. This will initially contain any
# sources passed to [teaish-add-src], but may also be appended to
# by teaish.make.
#
tx.src =@TEAISH_SRC@
dist: dist-clean $(srcdir)/manifest.uuid
$(INSTALL_DATA_DIR) $(DIST_DIR)
#
# tx.CFLAGS is typically set by teaish.make, whereas TEAISH_CFLAGS
# gets set up via the configure script.
#
tx.CFLAGS =
# TEA files
$(DIST_INSTALL_DATA) $(srcdir)/Makefile.in \
$(srcdir)/aclocal.m4 $(srcdir)/configure.ac \
$(DIST_DIR)/
$(DIST_INSTALL_SCRIPT) $(srcdir)/configure $(DIST_DIR)/
#
# tx.LDFLAGS is typically set by teaish.make, whereas TEAISH_LDFLAGS
# gets set up via the configure script.
#
tx.LDFLAGS =
$(INSTALL_DATA_DIR) $(DIST_DIR)/tclconfig
$(DIST_INSTALL_DATA) $(srcdir)/tclconfig/README.txt \
$(srcdir)/manifest.uuid \
$(srcdir)/tclconfig/tcl.m4 $(srcdir)/tclconfig/install-sh \
$(DIST_DIR)/tclconfig/
#
# The list of 'dist' files may be appended to from teaish.make.in.
# It can also be set up from teaish.tcl using [teaish-add-dist]
# and/or [teaish-add-src -dist ...].
#
tx.dist.files = @TEAISH_DIST_FILES@
# Extension files
$(DIST_INSTALL_DATA) \
$(srcdir)/ChangeLog \
$(srcdir)/README.sha \
$(srcdir)/license.terms \
$(srcdir)/README \
$(srcdir)/pkgIndex.tcl.in \
$(DIST_DIR)/
#
# May get amended with generated file names. They are cleaned up by
# the 'clean' rules. Client code which wants to clean up extra stuff
# should do so by adding their cleanup target (e.g. clean-extension)
# as a dependency to the 'clean' target, like so:
#
# clean: distclean-extension
# distclean: distclean-extension
#
teaish__cleanExtra =
list='demos doc generic library macosx tests unix win'; \
for p in $$list; do \
if test -d $(srcdir)/$$p ; then \
$(INSTALL_DATA_DIR) $(DIST_DIR)/$$p; \
$(DIST_INSTALL_DATA) $(srcdir)/$$p/* $(DIST_DIR)/$$p/; \
fi; \
done
#
# List of deps which may trigger an auto-reconfigure.
#
teaish__autogen.deps = \
$(tx.makefile.in) $(teaish.makefile.in) \
$(tx.tcl) $(teaish.dir)/pkgIndex.tcl.in \
@AUTODEPS@
#
# Problem: when more than one target can invoke TEAISH_AUTORECONFIG,
# we can get parallel reconfigures running. Thus, targets which
# may require reconfigure should depend on...
#
config.log: $(teaish__autogen.deps)
@TEAISH_AUTORECONFIG@
# ^^^ We would love to skip this when running [dist]clean, but there's
# no POSIX Make-portable way to do that. GNU Make can.
.PHONY: reconfigure
reconfigure:
@TEAISH_AUTORECONFIG@
(cd $(DIST_ROOT); $(COMPRESS);)
$(teaish.makefile): $(teaish__auto.def) $(teaish.makefile.in) \
@AUTODEPS@
#========================================================================
# End of user-definable section
#========================================================================
#
# The rest of this makefile exists solely to support this brief
# target: the extension shared lib.
#
$(tx.dll): $(tx.src) config.log
$(CC) -o $@ $(CFLAGS.configure) $(CFLAGS) $(tx.CFLAGS) \
$(tx.src) $(LDFLAGS.configure) $(LDFLAGS) $(tx.LDFLAGS)
#========================================================================
# Don't modify the file to clean here. Instead, set the "CLEANFILES"
# variable in configure.ac
#========================================================================
all: $(tx.dll)
clean:
-test -z "$(BINARIES)" || rm -f $(BINARIES)
-rm -f *.$(OBJEXT) core *.core
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
tclsh: $(teaish.makefile) config.log
@{ echo "#!/bin/sh"; echo "exec $(TCLSH) \"\$$@\""; } > $@
@chmod +x $@
@echo "Created $@"
distclean: clean
-rm -f *.tab.c
-rm -f $(CONFIG_CLEAN_FILES)
-rm -f config.cache config.log config.status
#========================================================================
# Install binary object libraries. On Windows this includes both .dll and
# .lib files. Because the .lib files are not explicitly listed anywhere,
# we need to deduce their existence from the .dll file of the same name.
# Library files go into the lib directory.
# In addition, this will generate the pkgIndex.tcl
# file in the install location (assuming it can find a usable tclsh shell)
#
# If the extension includes teaish.test.tcl then provide a "test"
# target which which runs that script, passing it (1) the full path to
# extension's DLL (which also provides the script with a way to get
# the test directory) and (2) a script of test utility code intended for
# sourcing by the client.
#
# If the extension has no test script, add a small one which
# simply loads the DLL and success if it can.
#
#
tx.tester.args = $(tx.dll) $(tx.loadPrefix) @TEAISH_TESTER_TCL@
.PHONY: test-pre test-core test test-post test-extension
test-extension: # this name is reserved for use by teaish.make
test-prepre: $(tx.dll)
test-pre: test-prepre
test-core: test-pre
$(TCLSH) teaish.tester.tcl $(tx.tester.args)
test-post: test-core
test: test-post
# You should not have to modify this target.
#========================================================================
#
# Cleanup rules...
#
.PHONY: clean-pre clean-core clean-post clean-extension
clean-extension: # this name is reserved for use by teaish.make
clean-pre:
clean-core: clean-pre
rm -f $(tx.dll8) $(tx.dll9) tclsh $(teaish__cleanExtra)
clean-post: clean-core
clean: clean-post
.PHONY: distclean-pre distclean-core distclean-post clean-extension
distclean-extension: # this name is reserved for use by teaish.make
distclean-pre: clean
distclean-core: distclean-pre
rm -f Makefile pkgIndex.tcl teaish.make teaish.tester.tcl
rm -f config.log config.defines.txt
distclean-post: distclean-core
distclean: distclean-post
#
# Installation rules...
#
.PHONY: install-pre install-core install-post install-test install-prepre install-extension
install-extension: # this name is reserved for use by teaish.make
install-prepre: $(tx.dll)
install-pre: install-prepre
install-core: install-pre
@if [ ! -d "$(DESTDIR)$(TCLLIBDIR)" ]; then \
set -x; $(INSTALL) -d "$(DESTDIR)$(TCLLIBDIR)"; \
install-lib-binaries: binaries
@$(INSTALL_DATA_DIR) "$(DESTDIR)$(pkglibdir)"
@list='$(lib_BINARIES)'; for p in $$list; do \
if test -f $$p; then \
echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \
$(INSTALL_LIBRARY) $$p "$(DESTDIR)$(pkglibdir)/$$p"; \
ext=`echo $$p|sed -e "s/.*\.//"`; \
if test "x$$ext" = "xdll"; then \
lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \
if test -f $$lib; then \
echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \
$(INSTALL_DATA) $$lib "$(DESTDIR)$(pkglibdir)/$$lib"; \
fi; \
fi; \
fi; \
done
@list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
if test -f $(srcdir)/$$p; then \
destp=`basename $$p`; \
echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \
$(INSTALL_DATA) $(srcdir)/$$p "$(DESTDIR)$(pkglibdir)/$$destp"; \
fi; \
done
@if test "x$(SHARED_BUILD)" = "x1"; then \
echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \
$(INSTALL_DATA) pkgIndex.tcl "$(DESTDIR)$(pkglibdir)"; \
fi
# ^^^^ on some platforms, install -d fails if the target already exists.
$(INSTALL) $(tx.dll) "$(DESTDIR)$(TCLLIBDIR)"
$(INSTALL.noexec) pkgIndex.tcl "$(DESTDIR)$(TCLLIBDIR)"
@if TEAISH_PKGINIT_TCL
$(INSTALL.noexec) @TEAISH_PKGINIT_TCL@ "$(DESTDIR)$(TCLLIBDIR)"
@endif
install-test: install-core
@echo 'package require $(tx.pkgName) $(tx.version)' > $@.tcl
@echo "Post-install test of [package require $(tx.pkgName) $(tx.version)]..."
@if $(TCLSH) $@.tcl ; then \
echo "test passed"; \
rm -f $@.tcl; \
else \
echo "TEST FAILED"; \
rm -f $@.tcl; \
exit 1; \
fi
install-post: install-test
install: install-post
#========================================================================
# Install binary executables (e.g. .exe files and dependent .dll files)
# This is for files that must go in the bin directory (located next to
# wish and tclsh), like dependent .dll files on Windows.
#
# Uninstall rules...
#
.PHONY: uninstall uninstall-pre uninstall-core uninstall-post uninstall-extension
uninstall-extension: # this name is reserved for use by teaish.make
uninstall-pre:
uninstall-core: uninstall-pre
rm -fr "$(DESTDIR)$(TCLLIBDIR)"
uninstall-post: uninstall-core
@echo "Uninstalled Tcl extension $(tx.name) $(tx.version)"
uninstall: uninstall-post
# You should not have to modify this target, except to define bin_BINARIES
# above if necessary.
#========================================================================
Makefile: config.log $(teaish.makefile.in)
@if TEAISH_MAKEFILE
$(tx.makefile): config.log
@endif
install-bin-binaries: binaries
@$(INSTALL_DATA_DIR) "$(DESTDIR)$(bindir)"
@list='$(bin_BINARIES)'; for p in $$list; do \
if test -f $$p; then \
echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \
$(INSTALL_PROGRAM) $$p "$(DESTDIR)$(bindir)/$$p"; \
fi; \
done
#
# Package archive generation ("dist") rules...
#
@if THEAISH_OUT_OF_EXT_TREE
dist:
@echo "'dist' can only be used from an extension's home dir" 1>&2; \
echo "In this case: @TEAISH_DIR@" 1>&2; exit 1
undist:
@else
@if BIN_ZIP
# Temp dir for dist.zip. Must be different than dist.tgz or else
# parallel builds may hose the dist.
teaish__dist.tmp.zip = teaish__dist_zip
#
# Make a distribution zip file...
#
dist.zip.dir = $(tx.name)-$(tx.version)
dist.zip = $(dist.zip.dir).zip
.PHONY: dist.zip dist.zip-core dist.zip-post
#dist.zip-pre:
# We apparently can't add a pre-hook here, even if dist.zip-pre is
# .PHONY, else "make dist" rebuilds the archive each time it's run.
$(dist.zip): $(tx.dist.files)
@rm -fr $(teaish__dist.tmp.zip)
@mkdir -p $(teaish__dist.tmp.zip)/$(dist.zip.dir)
@tar cf $(teaish__dist.tmp.zip)/tmp.tar $(tx.dist.files)
@tar xf $(teaish__dist.tmp.zip)/tmp.tar -C $(teaish__dist.tmp.zip)/$(dist.zip.dir)
@rm -f $(dist.zip.dir)/tmp.tar $(dist.zip)
@cd $(teaish__dist.tmp.zip) && zip -q -r ../$(dist.zip) $(dist.zip.dir)
@rm -fr $(teaish__dist.tmp.zip)
@ls -la $(dist.zip)
dist.zip-core: $(dist.zip)
dist.zip-post: dist.zip-core
dist.zip: dist.zip-post
dist: dist.zip
undist-zip:
rm -f $(dist.zip)
undist: undist-zip
@endif #BIN_ZIP
.SUFFIXES: .c .$(OBJEXT)
@if BIN_TAR
#
# Make a distribution tarball...
#
teaish__dist.tmp.tgz = teaish__dist_tgz
dist.tgz.dir = $(tx.name)-$(tx.version)
dist.tgz = $(dist.tgz.dir).tar.gz
.PHONY: dist.tgz dist.tgz-core dist.tgz-post
# dist.tgz-pre:
# see notes in dist.zip
$(dist.tgz): $(tx.dist.files)
@rm -fr $(teaish__dist.tmp.tgz)
@mkdir -p $(teaish__dist.tmp.tgz)/$(dist.tgz.dir)
@tar cf $(teaish__dist.tmp.tgz)/tmp.tar $(tx.dist.files)
@tar xf $(teaish__dist.tmp.tgz)/tmp.tar -C $(teaish__dist.tmp.tgz)/$(dist.tgz.dir)
@rm -f $(dist.tgz.dir)/tmp.tar $(dist.tgz)
@cd $(teaish__dist.tmp.tgz) && tar czf ../$(dist.tgz) $(dist.tgz.dir)
@rm -fr $(teaish__dist.tmp.tgz)
@ls -la $(dist.tgz)
dist.tgz-core: $(dist.tgz)
dist.tgz-post: dist.tgz-core
dist.tgz: dist.tgz-post
dist: dist.tgz
undist-tgz:
rm -f $(dist.tgz)
undist: undist-tgz
@endif #BIN_TAR
@endif #THEAISH_OUT_OF_EXT_TREE
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) \
&& CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
@if TEAISH_MAKEFILE
#
# tx.makefile defines any extension-specific state this file
# needs.
#
# It must set the following vars if they're not already accounted for
# via teaish.tcl.
#
# - tx.src = list of the extension's source files, being sure to
# prefix each with $(tx.dir) (if it's in the same dir as the
# extension) so that out-of-tree builds can find them. Optionally,
# [define] TEAISH_SRC or pass them to [teaish-add-src].
#
# It may optionally set the following vars:
#
# - tx.CFLAGS = CFLAGS/CPPFLAGS. Optionally, [define] TEAISH_CFLAGS
# or pass them to [teaish-add-cflags].
#
# - tx.LDFLAGS = LDFLAGS. Optionally, [define] TEAISH_LDFLAGS or
# pass them to [teaish-add-ldflags].
#
# It may optionally hook into various targets as documented in
# /doc/extensions.md in the canonical teaish source tree.
@include @TEAISH_MAKEFILE@
@endif #TEAISH_MAKEFILE
uninstall-binaries:
list='$(lib_BINARIES)'; for p in $$list; do \
rm -f "$(DESTDIR)$(pkglibdir)/$$p"; \
done
list='$(PKG_TCL_SOURCES)'; for p in $$list; do \
p=`basename $$p`; \
rm -f "$(DESTDIR)$(pkglibdir)/$$p"; \
done
list='$(bin_BINARIES)'; for p in $$list; do \
rm -f "$(DESTDIR)$(bindir)/$$p"; \
done
@if TEAISH_MAKEFILE_CODE
#
# TEAISH_MAKEFILE_CODE may contain literal makefile code, which
# gets pasted verbatim here. Either [define TEAISH_MAKEFILE_CODE
# ...] or use [teaish-add-make] to incrementally build up this
# content.
#
@TEAISH_MAKEFILE_CODE@
@endif #TEAISH_MAKEFILE_CODE
.PHONY: all binaries clean depend distclean doc install libraries test
.PHONY: gdb gdb-test valgrind valgrindshell
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
+5 -26
View File
@@ -1,30 +1,9 @@
This is the SQLite extension for Tcl using something akin to
the Tcl Extension Architecture (TEA). To build it:
This is the SQLite extension for Tcl using the Tcl Extension
Architecture (TEA).
./configure ...flags...
----------------------- A BETTER WAY ---------------------------
e.g.:
./configure --with-tcl=/path/to/tcl/install/root
or:
./configure --with-tclsh=/path/to/tcl/install/root
Run ./configure --help for the full list of flags.
The configuration process will fail if tclConfig.sh cannot be found.
The makefile will only honor CFLAGS and CPPFLAGS passed to the
configure script, not those directly passed to the makefile.
Then:
make test install
----------------------- THE PREFERRED WAY ---------------------------
The preferred way to build the TCL extension for SQLite is to use the
A better way to build the TCL extension for SQLite is to use the
canonical source code tarball. For Unix:
./configure --with-tclsh=$(TCLSH)
@@ -47,7 +26,7 @@ SQLite that does not require first installing TCL and/or "tclsh".
The canonical Makefile in the SQLite source tree provides more
capabilities (such as the the ability to run test cases to ensure
that the build worked) and is better maintained. The only
downside of the canonical Makefile is that it requires a TCL
downside of the canonical Makfile is that it requires a TCL
installation. But if you are wanting to build the TCL extension for
SQLite, then presumably you already have a TCL installation. So why
not just use the more-capable and better-maintained canoncal Makefile?
+9
View File
@@ -0,0 +1,9 @@
#
# Include the TEA standard macro set
#
builtin(include,tclconfig/tcl.m4)
#
# Add here whatever m4 macros you want to define for your package
#
-7
View File
@@ -1,7 +0,0 @@
#/do/not/tclsh
# ^^^ help out editors which guess this file's content type.
#
# Main configure script entry point for the "TEA-via-autosetup"
# framework.
use teaish-core
teaish-configure-core
-4
View File
@@ -1,4 +0,0 @@
The *.tcl files in this directory are part of the SQLite's "autoconf"
bundle which are specific to the TEA(-ish) build. During the tarball
generation process, they are copied into <TOP>/autoconf/autosetup
(which itself is created earlier in that process).
File diff suppressed because it is too large Load Diff
@@ -1,279 +0,0 @@
########################################################################
# 2025 April 7
#
# 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.
#
########################################################################
# ----- @module teaish-checks.tcl -----
# @section TEA-ish collection of feature tests.
#
# Functions in this file with a prefix of teaish__ are
# private/internal APIs. Those with a prefix of teaish- are
# public APIs.
use pkg-config
# @teaish-check-cached@ ?-flags? msg script
#
# Under construction.
#
# A proxy for feature-test impls which handles chacheing of the
# feature flag check on a per-caller basis, using the calling scope's
# name as the cache key.
#
# The test is performed by $script. This function caches the result
# and checks for a chache hit before running $script. The value stored
# in the cache is the final value of $script (and this routine will
# intercept a 'return' from $script).
#
# Flags:
#
# -nostatus = do not emit "ok" or "no" at the end. This presumes
# that the caller will emit a newline before turning.
proc teaish-check-cached {args} {
set quiet 0
set xargs {}
foreach arg $args {
switch -exact -- $arg {
-nostatus {
incr quiet
}
default {
lappend xargs $arg
}
}
}
lassign $xargs msg script
if {"" eq $msg} {
set msg [proj-current-scope 1]
}
if {[teaish-feature-cache-check 1 check]} {
msg-checking "${msg} ... (cached) "
if {$check} {msg-result "ok"} else {msg-result "no"}
return $check
} else {
msg-checking "${msg} ... "
set code [catch {uplevel 1 $script} rc xopt]
#puts "***** ::teaish__fCache ="; parray ::teaish__fCache
if {$code in {0 2}} {
teaish-feature-cache-set 1 $rc
if {!$quiet} {
if {$rc} {
msg-result "ok"
} else {
msg-result "no"
}
}
#puts "**** code=$code rc=$rc xopt=$xopt"
} else {
return -options $xopt $rc
}
}
}
# @teaish-check-libz
#
# Checks for zlib.h and the function deflate in libz. If found,
# prepends -lz to the extension's ldflags and returns 1, else returns
# 0. It also defines LDFLAGS_LIBZ to the libs flag.
#
proc teaish-check-libz {} {
teaish-check-cached "Checking for libz" {
set rc 0
if {[msg-quiet cc-check-includes zlib.h] && [msg-quiet proj-check-function-in-lib deflate z]} {
teaish-prepend-ldflags [define LDFLAGS_LIBZ [get-define lib_deflate]]
undefine lib_deflate
incr rc
}
expr $rc
}
}
# @teaish-check-librt ?funclist?
#
# Checks whether -lrt is needed for any of the given functions. If
# so, appends -lrt via [teaish-prepend-ldflags] and returns 1, else
# returns 0. It also defines LDFLAGS_LIBRT to the libs flag or an
# empty string.
#
# Some systems (ex: SunOS) require -lrt in order to use nanosleep.
#
proc teaish-check-librt {{funclist {fdatasync nanosleep}}} {
teaish-check-cached -nostatus "Checking whether ($funclist) need librt" {
define LDFLAGS_LIBRT ""
foreach func $funclist {
if {[msg-quiet proj-check-function-in-lib $func rt]} {
set ldrt [get-define lib_${func}]
undefine lib_${func}
if {"" ne $ldrt} {
teaish-prepend-ldflags -r [define LDFLAGS_LIBRT $ldrt]
msg-result $ldrt
return 1
} else {
msg-result "no lib needed"
return 1
}
}
}
msg-result "not found"
return 0
}
}
# @teaish-check-stdint
#
# A thin proxy for [cc-with] which checks for <stdint.h> and the
# various fixed-size int types it declares. It defines HAVE_STDINT_T
# to 0 or 1 and (if it's 1) defines HAVE_XYZ_T for each XYZ int type
# to 0 or 1, depending on whether its available.
proc teaish-check-stdint {} {
teaish-check-cached "Checking for stdint.h" {
msg-quiet cc-with {-includes stdint.h} \
{cc-check-types int8_t int16_t int32_t int64_t intptr_t \
uint8_t uint16_t uint32_t uint64_t uintptr_t}
}
}
# @teaish-is-mingw
#
# Returns 1 if building for mingw, else 0.
proc teaish-is-mingw {} {
return [expr {
[string match *mingw* [get-define host]] &&
![file exists /dev/null]
}]
}
# @teaish-check-libdl
#
# Checks for whether dlopen() can be found and whether it requires -ldl
# for linking. If found, returns 1, defines LDFLAGS_DLOPEN to the linker flags
# (if any), and passes those flags to teaish-prepend-ldflags.
proc teaish-check-dlopen {} {
teaish-check-cached -nostatus "Checking for dlopen()" {
set rc 0
set lfl ""
if {[cc-with {-includes dlfcn.h} {
cctest -link 1 -declare "extern char* dlerror(void);" -code "dlerror();"}]} {
msg-result "-ldl not needed"
incr rc
} elseif {[cc-check-includes dlfcn.h]} {
incr rc
if {[cc-check-function-in-lib dlopen dl]} {
set lfl [get-define lib_dlopen]
undefine lib_dlopen
msg-result " dlopen() needs $lfl"
} else {
msg-result " - dlopen() not found in libdl. Assuming dlopen() is built-in."
}
} else {
msg-result "not found"
}
teaish-prepend-ldflags [define LDFLAGS_DLOPEN $lfl]
define HAVE_DLOPEN $rc
}
}
########################################################################
# Handles the --enable-math flag.
proc teaish-check-libmath {} {
teaish-check-cached "Checking for libc math library" {
set lfl ""
set rc 0
if {[msg-quiet proj-check-function-in-lib ceil m]} {
incr rc
set lfl [get-define lib_ceil]
undefine lib_ceil
teaish-prepend-ldflags $lfl
msg-checking "$lfl "
}
define LDFLAGS_LIBMATH $lfl
expr $rc
}
}
# @teaish-check-pkg-config-libssl
#
# Returns 1 if libssl is found via pkg-config, else 0. If found,
# passes its link flags to teaish-prepend-ldflags. Defines LDFLAGS_SSL
# to the linker flags, if found, else "".
#
# If it returns true, the underlying pkg-config test will set several
# defines named PKG_LIBSSL_... (see the docs for [pkg-config] for
# details).
proc teaish-check-pkg-config-libssl {} {
teaish-check-cached -nostatus "Checking for libssl via pkg-config" {
msg-result "Looking for libssl ..."
set lfl {}
set rc 0
if {[msg-quiet pkg-config-init 0] && [msg-quiet pkg-config libssl]} {
lappend lfl [get-define PKG_LIBSSL_LDFLAGS] \
[get-define PKG_LIBSSL_LIBS]
incr rc
} else {
# TODO: port over the more elaborate checks from fossil.
}
if {$rc} {
set lfl [string trim [join $lfl]]
define LDFLAGS_SSL $lfl
teaish-prepend-ldflags $lfl
}
define HAVE_LIBSSL $rc
return [teaish-feature-cache-set $rc]
}
}
# Under construction
#
# Helper for OpenSSL checking
proc teaish__check-openssl {msg {cflags {}} {libs {-lssl -lcrypto -lpthread}}} {
msg-checking "Checking for $msg..."
set rc 0
set isMinGw [teaish-is-mingw]
if {$isMinGw} {
lappend libs -lgdi32 -lwsock32 -lcrypt32
}
if {[teaish-check-libz]} {
lappend libs [get-define LDFLAGS_LIBZ]
}
msg-quiet cc-with [list -cflags $cflags -libs $libs] {
if {[cc-check-includes openssl/ssl.h] && \
[cc-check-functions SSL_new]} {
incr rc
}
}
# TODO
if {!$rc && !$isMinGw} {
# On some systems, OpenSSL appears to require -ldl to link.
if {[teaish-check-dlopen]} {
lappend libs [get-define LDFLAGS_DLOPEN ""]
msg-quiet cc-with [list -cflags $cflags -libs $libs] {
if {[cc-check-includes openssl/ssl.h] && \
[cc-check-functions SSL_new]} {
incr rc
}
}
}
}
if {$rc} {
msg-result "ok"
} else {
msg-result "no"
}
return $rc
}
# Under construction
proc teaish-check-libssl {} {
# Goal: port in fossil's handle-with-openssl. It's a bit of a beast.
if {![teaish-check-pkg-config-libssl]} {
#teaish__check-openssl
}
}
-103
View File
@@ -1,103 +0,0 @@
########################################################################
# 2025 April 5
#
# 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.
#
########################################################################
#
# Helper routines for running automated tests on teaish extensions
#
########################################################################
# ----- @module teaish-tester.tcl -----
# @section TEA-ish Testing APIs
########################################################################
# @test-current-scope ?lvl?
#
# Returns the name of the _calling_ proc from ($lvl + 1) levels up the
# call stack (where the caller's level will be 1 up from _this_
# call). If $lvl would resolve to global scope "global scope" is
# returned and if it would be negative then a string indicating such
# is returned (as opposed to throwing an error).
proc test-current-scope {{lvl 0}} {
#uplevel [expr {$lvl + 1}] {lindex [info level 0] 0}
set ilvl [info level]
set offset [expr {$ilvl - $lvl - 1}]
if { $offset < 0} {
return "invalid scope ($offset)"
} elseif { $offset == 0} {
return "global scope"
} else {
return [lindex [info level $offset] 0]
}
}
proc test-msg {args} {
puts "{*}$args"
}
########################################################################
# @test-error msg
#
# Emits an error message to stderr and exits with non-0.
proc test-fail {msg} {
#puts stderr "ERROR: \[[test-current-scope 1]]: $msg"
#exit 1
error "ERROR: \[[test-current-scope 1]]: $msg"
}
########################################################################
# @assert script ?message?
#
# Kind of like a C assert: if uplevel (eval) of [expr {$script}] is
# false, a fatal error is triggered. The error message, by default,
# includes the body of the failed assertion, but if $msg is set then
# that is used instead.
proc assert {script {msg ""}} {
set x "expr \{ $script \}"
if {![uplevel 1 $x]} {
if {"" eq $msg} {
set msg $script
}
test-fail "Assertion failed in \[[test-current-scope 1]]: $msg"
}
}
########################################################################
# @test-expect testId script result
#
# Runs $script in the calling scope and compares its result to
# $result. If they differ, it triggers an [assert].
proc test-expect {testId script result} {
puts "test $testId"
set x [uplevel 1 $script]
assert {$x eq $result} "\nEXPECTED: <<$result>>\nGOT: <<$x>>"
}
########################################################################
# @test-assert testId script ?msg?
#
# Works like [assert] but emits $testId to stdout first.
proc test-assert {testId script {msg ""}} {
puts "test $testId"
assert $script $msg
}
########################################################################
# @test-catch cmd ?...args?
#
# Runs [cmd ...args], repressing any exception except to possibly log
# the failure.
proc test-catch {cmd args} {
if {[catch {
$cmd {*}$args
} rc xopts]} {
puts "[test-current-scope] ignoring failure of: $cmd [lindex $args 0]"
#how to extract just the message text from $xopts?
}
}
-7
View File
@@ -1,7 +0,0 @@
#!/bin/sh
dir0="`dirname "$0"`"
dirA="$dir0/../autosetup"
# This is the case ^^^^^^^^^^^^ in the SQLite "autoconf" bundle.
WRAPPER="$0"; export WRAPPER; exec "`"$dirA/autosetup-find-tclsh"`" \
"$dirA/autosetup" --teaish-extension-dir="$dir0" \
"$@"
+227
View File
@@ -0,0 +1,227 @@
#!/bin/bash -norc
dnl This file is an input file used by the GNU "autoconf" program to
dnl generate the file "configure", which is run during Tcl installation
dnl to configure the system for the local environment.
#-----------------------------------------------------------------------
# Sample configure.ac for Tcl Extensions. The only places you should
# need to modify this file are marked by the string __CHANGE__
#-----------------------------------------------------------------------
#-----------------------------------------------------------------------
# __CHANGE__
# Set your package name and version numbers here.
#
# This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
# set as provided. These will also be added as -D defs in your Makefile
# so you can encode the package version directly into the source files.
# This will also define a special symbol for Windows (BUILD_<PACKAGE_NAME>
# so that we create the export library with the dll.
#-----------------------------------------------------------------------
AC_INIT([sqlite],[3.50.0])
#--------------------------------------------------------------------
# Call TEA_INIT as the first TEA_ macro to set up initial vars.
# This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
# as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
#--------------------------------------------------------------------
TEA_INIT()
AC_CONFIG_AUX_DIR(tclconfig)
#--------------------------------------------------------------------
# Load the tclConfig.sh file
#--------------------------------------------------------------------
TEA_PATH_TCLCONFIG
TEA_LOAD_TCLCONFIG
#--------------------------------------------------------------------
# Load the tkConfig.sh file if necessary (Tk extension)
#--------------------------------------------------------------------
#TEA_PATH_TKCONFIG
#TEA_LOAD_TKCONFIG
#-----------------------------------------------------------------------
# Handle the --prefix=... option by defaulting to what Tcl gave.
# Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER.
#-----------------------------------------------------------------------
TEA_PREFIX
#-----------------------------------------------------------------------
# Standard compiler checks.
# This sets up CC by using the CC env var, or looks for gcc otherwise.
# This also calls AC_PROG_CC and a few others to create the basic setup
# necessary to compile executables.
#-----------------------------------------------------------------------
TEA_SETUP_COMPILER
#-----------------------------------------------------------------------
# __CHANGE__
# Specify the C source files to compile in TEA_ADD_SOURCES,
# public headers that need to be installed in TEA_ADD_HEADERS,
# stub library C source files to compile in TEA_ADD_STUB_SOURCES,
# and runtime Tcl library files in TEA_ADD_TCL_SOURCES.
# This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS
# and PKG_TCL_SOURCES.
#-----------------------------------------------------------------------
TEA_ADD_SOURCES([tclsqlite3.c])
TEA_ADD_HEADERS([])
TEA_ADD_INCLUDES([])
TEA_ADD_LIBS([])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS3=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS4=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_FTS5=1])
TEA_ADD_CFLAGS([-DSQLITE_3_SUFFIX_ONLY=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_RTREE=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_GEOPOLY=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_MATH_FUNCTIONS=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_DESERIALIZE=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_DBPAGE_VTAB=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_BYTECODE_VTAB=1])
TEA_ADD_CFLAGS([-DSQLITE_ENABLE_DBSTAT_VTAB=1])
TEA_ADD_STUB_SOURCES([])
TEA_ADD_TCL_SOURCES([])
#--------------------------------------------------------------------
# The --with-system-sqlite causes the TCL bindings to SQLite to use
# the system shared library for SQLite rather than statically linking
# against its own private copy. This is dangerous and leads to
# undersirable dependences and is not recommended.
# Patchs from rmax.
#--------------------------------------------------------------------
AC_ARG_WITH([system-sqlite],
[AS_HELP_STRING([--with-system-sqlite],
[use a system-supplied libsqlite3 instead of the bundled one])],
[], [with_system_sqlite=no])
if test x$with_system_sqlite != xno; then
AC_CHECK_HEADER([sqlite3.h],
[AC_CHECK_LIB([sqlite3],[sqlite3_initialize],
[AC_DEFINE(USE_SYSTEM_SQLITE)
LIBS="$LIBS -lsqlite3"])])
fi
#--------------------------------------------------------------------
# __CHANGE__
#
# You can add more files to clean if your extension creates any extra
# files by extending CLEANFILES.
# Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure
# and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var.
#
# A few miscellaneous platform-specific items:
# TEA_ADD_* any platform specific compiler/build info here.
#--------------------------------------------------------------------
#CLEANFILES="$CLEANFILES pkgIndex.tcl"
if test "${TEA_PLATFORM}" = "windows" ; then
# Ensure no empty if clauses
:
#TEA_ADD_SOURCES([win/winFile.c])
#TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"])
else
# Ensure no empty else clauses
:
#TEA_ADD_SOURCES([unix/unixFile.c])
#TEA_ADD_LIBS([-lsuperfly])
fi
#--------------------------------------------------------------------
# __CHANGE__
# Choose which headers you need. Extension authors should try very
# hard to only rely on the Tcl public header files. Internal headers
# contain private data structures and are subject to change without
# notice.
# This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG
#--------------------------------------------------------------------
TEA_PUBLIC_TCL_HEADERS
#TEA_PRIVATE_TCL_HEADERS
#TEA_PUBLIC_TK_HEADERS
#TEA_PRIVATE_TK_HEADERS
#TEA_PATH_X
#--------------------------------------------------------------------
# Check whether --enable-threads or --disable-threads was given.
# This auto-enables if Tcl was compiled threaded.
#--------------------------------------------------------------------
TEA_ENABLE_THREADS
if test "${TCL_THREADS}" = "1" ; then
AC_DEFINE(SQLITE_THREADSAFE, 1, [Trigger sqlite threadsafe build])
# Not automatically added by Tcl because its assumed Tcl links to them,
# but it may not if it isn't really a threaded build.
TEA_ADD_LIBS([$THREADS_LIBS])
else
AC_DEFINE(SQLITE_THREADSAFE, 0, [Trigger sqlite non-threadsafe build])
fi
#--------------------------------------------------------------------
# The statement below defines a collection of symbols related to
# building as a shared library instead of a static library.
#--------------------------------------------------------------------
TEA_ENABLE_SHARED
#--------------------------------------------------------------------
# This macro figures out what flags to use with the compiler/linker
# when building shared/static debug/optimized objects. This information
# can be taken from the tclConfig.sh file, but this figures it all out.
#--------------------------------------------------------------------
TEA_CONFIG_CFLAGS
#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols option.
#--------------------------------------------------------------------
TEA_ENABLE_SYMBOLS
#--------------------------------------------------------------------
# This macro generates a line to use when building a library. It
# depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS,
# and TEA_LOAD_TCLCONFIG macros above.
#--------------------------------------------------------------------
TEA_MAKE_LIB
#--------------------------------------------------------------------
# Determine the name of the tclsh and/or wish executables in the
# Tcl and Tk build directories or the location they were installed
# into. These paths are used to support running test cases only,
# the Makefile should not be making use of these paths to generate
# a pkgIndex.tcl file or anything else at extension build time.
#--------------------------------------------------------------------
TEA_PROG_TCLSH
#TEA_PROG_WISH
#--------------------------------------------------------------------
# Setup a *Config.sh.in configuration file.
#--------------------------------------------------------------------
#TEA_EXPORT_CONFIG([sample])
#AC_SUBST(SAMPLE_VAR)
#--------------------------------------------------------------------
# Specify files to substitute AC variables in. You may alternatively
# have a special pkgIndex.tcl.in or other files which require
# substituting the AC variables in. Include these here.
#--------------------------------------------------------------------
AC_CONFIG_FILES([Makefile pkgIndex.tcl])
#AC_CONFIG_FILES([sampleConfig.sh])
#--------------------------------------------------------------------
# Finally, substitute all of the various values into the files
# specified with AC_CONFIG_FILES.
#--------------------------------------------------------------------
AC_OUTPUT
+2 -2
View File
@@ -11,5 +11,5 @@ SQLite3 is a self-contains, zero-configuration, transactional SQL database
engine. This extension provides an easy to use interface for accessing
SQLite database files from Tcl.
.PP
For full documentation see \fIhttp://sqlite.org/\fR and
in particular \fIhttp://sqlite.org/tclsqlite.html\fR.
For full documentation see \fIhttp://www.sqlite.org/\fR and
in particular \fIhttp://www.sqlite.org/tclsqlite.html\fR.
+6 -26
View File
@@ -1,30 +1,10 @@
# -*- tcl -*-
# Automatically generated - do not edit
# Tcl package index file
# Adapted from https://core.tcl-lang.org/tcltls
# Tcl package index file, version 1.1
#
if {[package vsatisfies [package provide Tcl] 9.0-]} {
package ifneeded @TEAISH_PKGNAME@ @TEAISH_VERSION@ [list apply {{dir} {
load [file join $dir @TEAISH_DLL9@] @TEAISH_LOAD_PREFIX@
@if TEAISH_PKGINIT_TCL
set initScript [file join $dir @TEAISH_PKGINIT_TCL@]
# if {[file exists $initScript]} {
source -encoding utf-8 $initScript
# }
@endif
}} $dir]
package ifneeded sqlite3 @PACKAGE_VERSION@ \
[list load [file join $dir @PKG_LIB_FILE9@] Sqlite3]
} else {
if {![package vsatisfies [package provide Tcl] 8.5]} {return}
package ifneeded @TEAISH_PKGNAME@ @TEAISH_VERSION@ [list apply {{dir} {
if {[string tolower [file extension @TEAISH_DLL8@]] in [list .dll .dylib .so]} {
load [file join $dir @TEAISH_DLL8@] @TEAISH_LOAD_PREFIX@
} else {
load {} @TEAISH_LOAD_PREFIX@
}
@if TEAISH_PKGINIT_TCL
set initScript [file join $dir @TEAISH_PKGINIT_TCL@]
# if {[file exists $initScript]} {
source -encoding utf-8 $initScript
# }
@endif
}} $dir]
package ifneeded sqlite3 @PACKAGE_VERSION@ \
[list load [file join $dir @PKG_LIB_FILE8@] Sqlite3]
}
+541
View File
@@ -0,0 +1,541 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2020-11-14.01; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# 'make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch.
tab=' '
nl='
'
IFS=" $tab$nl"
# Set DOITPROG to "echo" to test this script.
doit=${DOITPROG-}
doit_exec=${doit:-exec}
# Put in absolute file names if you don't have them in your path;
# or use environment vars.
chgrpprog=${CHGRPPROG-chgrp}
chmodprog=${CHMODPROG-chmod}
chownprog=${CHOWNPROG-chown}
cmpprog=${CMPPROG-cmp}
cpprog=${CPPROG-cp}
mkdirprog=${MKDIRPROG-mkdir}
mvprog=${MVPROG-mv}
rmprog=${RMPROG-rm}
stripprog=${STRIPPROG-strip}
posix_mkdir=
# Desired mode of installed file.
mode=0755
# Create dirs (including intermediate dirs) using mode 755.
# This is like GNU 'install' as of coreutils 8.32 (2020).
mkdir_umask=22
backupsuffix=
chgrpcmd=
chmodcmd=$chmodprog
chowncmd=
mvcmd=$mvprog
rmcmd="$rmprog -f"
stripcmd=
src=
dst=
dir_arg=
dst_arg=
copy_on_change=false
is_target_a_directory=possibly
usage="\
Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
--help display this help and exit.
--version display version info and exit.
-c (ignored)
-C install only if different (preserve data modification time)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-p pass -p to $cpprog.
-s $stripprog installed files.
-S SUFFIX attempt to back up existing files, with suffix SUFFIX.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
RMPROG STRIPPROG
By default, rm is invoked with -f; when overridden with RMPROG,
it's up to you to specify -f if you want it.
If -S is not specified, no backups are attempted.
Email bug reports to bug-automake@gnu.org.
Automake home page: https://www.gnu.org/software/automake/
"
while test $# -ne 0; do
case $1 in
-c) ;;
-C) copy_on_change=true;;
-d) dir_arg=true;;
-g) chgrpcmd="$chgrpprog $2"
shift;;
--help) echo "$usage"; exit $?;;
-m) mode=$2
case $mode in
*' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
echo "$0: invalid mode: $mode" >&2
exit 1;;
esac
shift;;
-o) chowncmd="$chownprog $2"
shift;;
-p) cpprog="$cpprog -p";;
-s) stripcmd=$stripprog;;
-S) backupsuffix="$2"
shift;;
-t)
is_target_a_directory=always
dst_arg=$2
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
shift;;
-T) is_target_a_directory=never;;
--version) echo "$0 $scriptversion"; exit $?;;
--) shift
break;;
-*) echo "$0: invalid option: $1" >&2
exit 1;;
*) break;;
esac
shift
done
# We allow the use of options -d and -T together, by making -d
# take the precedence; this is for compatibility with GNU install.
if test -n "$dir_arg"; then
if test -n "$dst_arg"; then
echo "$0: target directory not allowed when installing a directory." >&2
exit 1
fi
fi
if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
# When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dst_arg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dst_arg"
shift # fnord
fi
shift # arg
dst_arg=$arg
# Protect names problematic for 'test' and other utilities.
case $dst_arg in
-* | [=\(\)!]) dst_arg=./$dst_arg;;
esac
done
fi
if test $# -eq 0; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call 'install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
if test -z "$dir_arg"; then
if test $# -gt 1 || test "$is_target_a_directory" = always; then
if test ! -d "$dst_arg"; then
echo "$0: $dst_arg: Is not a directory." >&2
exit 1
fi
fi
fi
if test -z "$dir_arg"; then
do_exit='(exit $ret); exit $ret'
trap "ret=129; $do_exit" 1
trap "ret=130; $do_exit" 2
trap "ret=141; $do_exit" 13
trap "ret=143; $do_exit" 15
# Set umask so as not to create temps with too-generous modes.
# However, 'strip' requires both read and write access to temps.
case $mode in
# Optimize common cases.
*644) cp_umask=133;;
*755) cp_umask=22;;
*[0-7])
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw='% 200'
fi
cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
*)
if test -z "$stripcmd"; then
u_plus_rw=
else
u_plus_rw=,u+rw
fi
cp_umask=$mode$u_plus_rw;;
esac
fi
for src
do
# Protect names problematic for 'test' and other utilities.
case $src in
-* | [=\(\)!]) src=./$src;;
esac
if test -n "$dir_arg"; then
dst=$src
dstdir=$dst
test -d "$dstdir"
dstdir_status=$?
# Don't chown directories that already exist.
if test $dstdir_status = 0; then
chowncmd=""
fi
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dst_arg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dst_arg
# If destination is a directory, append the input filename.
if test -d "$dst"; then
if test "$is_target_a_directory" = never; then
echo "$0: $dst_arg: Is a directory" >&2
exit 1
fi
dstdir=$dst
dstbase=`basename "$src"`
case $dst in
*/) dst=$dst$dstbase;;
*) dst=$dst/$dstbase;;
esac
dstdir_status=0
else
dstdir=`dirname "$dst"`
test -d "$dstdir"
dstdir_status=$?
fi
fi
case $dstdir in
*/) dstdirslash=$dstdir;;
*) dstdirslash=$dstdir/;;
esac
obsolete_mkdir_used=false
if test $dstdir_status != 0; then
case $posix_mkdir in
'')
# With -d, create the new directory with the user-specified mode.
# Otherwise, rely on $mkdir_umask.
if test -n "$dir_arg"; then
mkdir_mode=-m$mode
else
mkdir_mode=
fi
posix_mkdir=false
# The $RANDOM variable is not portable (e.g., dash). Use it
# here however when possible just to lower collision chance.
tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
trap '
ret=$?
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
exit $ret
' 0
# Because "mkdir -p" follows existing symlinks and we likely work
# directly in world-writeable /tmp, make sure that the '$tmpdir'
# directory is successfully created first before we actually test
# 'mkdir -p'.
if (umask $mkdir_umask &&
$mkdirprog $mkdir_mode "$tmpdir" &&
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
# Check for POSIX incompatibilities with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
test_tmpdir="$tmpdir/a"
ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
case $ls_ld_tmpdir in
d????-?r-*) different_mode=700;;
d????-?--*) different_mode=755;;
*) false;;
esac &&
$mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
}
}
then posix_mkdir=:
fi
rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
else
# Remove any dirs left behind by ancient mkdir implementations.
rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
fi
trap '' 0;;
esac
if
$posix_mkdir && (
umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
)
then :
else
# mkdir does not conform to POSIX,
# or it failed possibly due to a race condition. Create the
# directory the slow way, step by step, checking for races as we go.
case $dstdir in
/*) prefix='/';;
[-=\(\)!]*) prefix='./';;
*) prefix='';;
esac
oIFS=$IFS
IFS=/
set -f
set fnord $dstdir
shift
set +f
IFS=$oIFS
prefixes=
for d
do
test X"$d" = X && continue
prefix=$prefix$d
if test -d "$prefix"; then
prefixes=
else
if $posix_mkdir; then
(umask $mkdir_umask &&
$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
# Don't fail if two instances are running concurrently.
test -d "$prefix" || exit 1
else
case $prefix in
*\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
*) qprefix=$prefix;;
esac
prefixes="$prefixes '$qprefix'"
fi
fi
prefix=$prefix/
done
if test -n "$prefixes"; then
# Don't fail if two instances are running concurrently.
(umask $mkdir_umask &&
eval "\$doit_exec \$mkdirprog $prefixes") ||
test -d "$dstdir" || exit 1
obsolete_mkdir_used=true
fi
fi
fi
if test -n "$dir_arg"; then
{ test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
{ test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
else
# Make a couple of temp file names in the proper directory.
dsttmp=${dstdirslash}_inst.$$_
rmtmp=${dstdirslash}_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
# Copy the file name to the temp name.
(umask $cp_umask &&
{ test -z "$stripcmd" || {
# Create $dsttmp read-write so that cp doesn't create it read-only,
# which would cause strip to fail.
if test -z "$doit"; then
: >"$dsttmp" # No need to fork-exec 'touch'.
else
$doit touch "$dsttmp"
fi
}
} &&
$doit_exec $cpprog "$src" "$dsttmp") &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
{ test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
{ test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
{ test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
# If -C, don't bother to copy if it wouldn't change the file.
if $copy_on_change &&
old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` &&
new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
set -f &&
set X $old && old=:$2:$4:$5:$6 &&
set X $new && new=:$2:$4:$5:$6 &&
set +f &&
test "$old" = "$new" &&
$cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
then
rm -f "$dsttmp"
else
# If $backupsuffix is set, and the file being installed
# already exists, attempt a backup. Don't worry if it fails,
# e.g., if mv doesn't support -f.
if test -n "$backupsuffix" && test -f "$dst"; then
$doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
fi
# Rename the file to the real destination.
$doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
{
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
test ! -f "$dst" ||
$doit $rmcmd "$dst" 2>/dev/null ||
{ $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
{ $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
} ||
{ echo "$0: cannot unlink or rename $dst" >&2
(exit 1); exit 1
}
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dst"
}
fi || exit 1
trap '' 0
fi
done
# Local variables:
# eval: (add-hook 'before-save-hook 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:
File diff suppressed because it is too large Load Diff
-543
View File
@@ -1,543 +0,0 @@
# Teaish configure script extension for the SQLite TCL extension
define TEAISH_NAME sqlite
define TEAISH_PKGNAME sqlite3
define TEAISH_LIBDIR_NAME sqlite3
define TEAISH_LOAD_PREFIX Sqlite3; # 2nd arg to [load]
#
# Get the version...
#
define TEAISH_VERSION [proj-file-content -trim [get-define TEAISH_DIR]/../VERSION]
proj-assert {[string match 3.*.* [get-define TEAISH_VERSION]]}
#
# Object for communicating certain config-time state across various
# auto.def-related pieces.
#
array set sqliteConfig [subst [proj-strip-hash-comments {
#
# The list of feature --flags which the --all flag implies. This
# requires special handling in a few places.
#
all-flag-enables {fts3 fts4 fts5 rtree geopoly}
}]]
#
# Must return either an empty string or a list in the form accepted by
# autosetup's [options] function.
#
proc teaish-options {} {
return [proj-strip-hash-comments [subst -nocommands -nobackslashes {
with-system-sqlite=0
=> {Use the system-level sqlite instead of the copy in this tree.
WARNING: this extension's version is taken from the in-tree copy
and there is no reliable way to get the version of a system-level copy
without knowing exactly where it lives (which this script does not)}
override-sqlite-version:VERSION
=> {For use with --with-system-sqlite to set the version number.}
threadsafe=1 => {Disable mutexing}
with-tempstore:=no => {Use an in-RAM database for temporary tables: never,no,yes,always}
load-extension=0 => {Enable loading of external extensions}
math=1 => {Disable math functions}
json=1 => {Disable JSON functions}
fts3 => {Enable the FTS3 extension}
fts4 => {Enable the FTS4 extension}
fts5 => {Enable the FTS5 extension}
update-limit => {Enable the UPDATE/DELETE LIMIT clause}
geopoly => {Enable the GEOPOLY extension}
rtree => {Enable the RTREE extension}
session => {Enable the SESSION extension}
all=1 => {Disable $::sqliteConfig(all-flag-enables)}
with-icu-ldflags:LDFLAGS
=> {Enable SQLITE_ENABLE_ICU and add the given linker flags for the
ICU libraries. e.g. on Ubuntu systems, try '-licui18n -licuuc -licudata'.}
with-icu-cflags:CFLAGS
=> {Apply extra CFLAGS/CPPFLAGS necessary for building with ICU.
e.g. -I/usr/local/include}
with-icu-config:=auto
=> {Enable SQLITE_ENABLE_ICU. Value must be one of: auto, pkg-config,
/path/to/icu-config}
icu-collations=0
=> {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-ldflags=...
or --with-icu-config}
}]]
}
#
# Gets called by tea-configure-core. Must perform any configuration
# work needed for this extension.
#
proc teaish-configure {} {
uplevel 1 {use teaish-feature-tests}
set srcdir [get-define TEAISH_DIR]
teaish-add-src -dist -dir generic/tclsqlite3.c
teaish-add-cflags -I${srcdir}/.. ; # for sqlite3.c
if {[proj-opt-was-provided override-sqlite-version]} {
define TEAISH_VERSION [opt-val override-sqlite-version]
msg-result "NOTICE: overriding version number: [get-define TEAISH_VERSION]"
}
define CFLAGS [proj-get-env CFLAGS {-O2}]
sqlite-munge-cflags
#
# Add feature flags from legacy configure.ac which are not covered by
# --flags.
#
sqlite-add-feature-flag {
-DSQLITE_3_SUFFIX_ONLY=1
-DSQLITE_ENABLE_DESERIALIZE=1
-DSQLITE_ENABLE_DBPAGE_VTAB=1
-DSQLITE_ENABLE_BYTECODE_VTAB=1
-DSQLITE_ENABLE_DBSTAT_VTAB=1
}
if {[opt-bool with-system-sqlite]} {
msg-result "Using system-level sqlite3."
teaish-add-cflags -DUSE_SYSTEM_SQLITE
teaish-add-ldflags -lsqlite3
}
sqlite-check-common-system-deps
sqlite-handle-threadsafe
sqlite-handle-tempstore
sqlite-handle-load-extension
sqlite-handle-math
sqlite-handle-icu
sqlite-handle-common-feature-flags
teaish-add-ldflags -p -d \
LDFLAGS_LIBICU LDFLAGS_LIBMATH LDFLAGS_DLOPEN \
LDFLAGS_LIBRT
teaish-add-cflags -define CFLAGS_LIBICU OPT_FEATURE_FLAGS
}; # teaish-configure
define OPT_FEATURE_FLAGS {} ; # -DSQLITE_OMIT/ENABLE flags.
########################################################################
# Adds $args, if not empty, to OPT_FEATURE_FLAGS. This is intended only for holding
# -DSQLITE_ENABLE/OMIT/... flags, but that is not enforced here.
proc sqlite-add-feature-flag {args} {
if {"" ne $args} {
define-append OPT_FEATURE_FLAGS {*}$args
}
}
########################################################################
# Check for log(3) in libm and die with an error if it is not
# found. $featureName should be the feature name which requires that
# function (it's used only in error messages). defines LDFLAGS_MATH to
# the required linker flags (which may be empty even if the math APIs
# are found, depending on the OS).
proc sqlite-affirm-have-math {featureName} {
if {"" eq [get-define LDFLAGS_MATH ""]} {
if {![msg-quiet proj-check-function-in-lib log m]} {
user-error "Missing math APIs for $featureName"
}
define LDFLAGS_MATH [get-define lib_log ""]
undefine lib_log
}
}
########################################################################
# Handle various SQLITE_ENABLE/OMIT_... feature flags.
proc sqlite-handle-common-feature-flags {} {
msg-result "Feature flags..."
if {![opt-bool all]} {
# Special handling for --disable-all
foreach flag $::sqliteConfig(all-flag-enables) {
if {![proj-opt-was-provided $flag]} {
proj-opt-set $flag 0
}
}
}
foreach {boolFlag featureFlag ifSetEvalThis} [proj-strip-hash-comments {
all {} {
# The 'all' option must be first in this list. This impl makes
# an effort to only apply flags which the user did not already
# apply, so that combinations like (--all --disable-geopoly)
# will indeed disable geopoly. There are corner cases where
# flags which depend on each other will behave in non-intuitive
# ways:
#
# --all --disable-rtree
#
# Will NOT disable geopoly, though geopoly depends on rtree.
# The --geopoly flag, though, will automatically re-enable
# --rtree, so --disable-rtree won't actually disable anything in
# that case.
foreach k $::sqliteConfig(all-flag-enables) {
if {![proj-opt-was-provided $k]} {
proj-opt-set $k 1
}
}
}
fts3 -DSQLITE_ENABLE_FTS3 {sqlite-affirm-have-math fts3}
fts4 -DSQLITE_ENABLE_FTS4 {sqlite-affirm-have-math fts4}
fts5 -DSQLITE_ENABLE_FTS5 {sqlite-affirm-have-math fts5}
geopoly -DSQLITE_ENABLE_GEOPOLY {proj-opt-set rtree}
rtree -DSQLITE_ENABLE_RTREE {}
session {-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK} {}
update-limit -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT {}
scanstatus -DSQLITE_ENABLE_STMT_SCANSTATUS {}
}] {
if {$boolFlag ni $::autosetup(options)} {
# Skip flags which are in the canonical build but not
# the autoconf bundle.
continue
}
proj-if-opt-truthy $boolFlag {
sqlite-add-feature-flag $featureFlag
if {0 != [eval $ifSetEvalThis] && "all" ne $boolFlag} {
msg-result " + $boolFlag"
}
} {
if {"all" ne $boolFlag} {
msg-result " - $boolFlag"
}
}
}
########################################################################
# Invert the above loop's logic for some SQLITE_OMIT_... cases. If
# config option $boolFlag is false, [sqlite-add-feature-flag
# $featureFlag], where $featureFlag is intended to be
# -DSQLITE_OMIT_...
foreach {boolFlag featureFlag} {
json -DSQLITE_OMIT_JSON
} {
if {[proj-opt-truthy $boolFlag]} {
msg-result " + $boolFlag"
} else {
sqlite-add-feature-flag $featureFlag
msg-result " - $boolFlag"
}
}
sqlite-finalize-feature-flags
}
#########################################################################
# Remove duplicates from the final feature flag sets and show them to
# the user.
proc sqlite-finalize-feature-flags {} {
set oFF [get-define OPT_FEATURE_FLAGS]
if {"" ne $oFF} {
define OPT_FEATURE_FLAGS [lsort -unique $oFF]
msg-result "Library feature flags: [get-define OPT_FEATURE_FLAGS]"
}
if {[lsearch [get-define TARGET_DEBUG ""] -DSQLITE_DEBUG=1] > -1} {
msg-result "Note: this is a debug build, so performance will suffer."
}
}
########################################################################
# Run checks for system-level includes and libs which are common to
# both the canonical build and the "autoconf" bundle.
#
proc sqlite-check-common-system-deps {} {
# Check for needed/wanted data types
if {0} {
# We don't need these until/unless we want to generate
# sqlite_cfg.h. The historical TEA build does not generate that
# file.
cc-with {-includes stdint.h} \
{cc-check-types int8_t int16_t int32_t int64_t intptr_t \
uint8_t uint16_t uint32_t uint64_t uintptr_t}
# Check for needed/wanted functions
cc-check-functions gmtime_r isnan localtime_r localtime_s \
malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64
# Check for needed/wanted headers
cc-check-includes \
sys/types.h sys/stat.h dlfcn.h unistd.h \
stdlib.h malloc.h memory.h \
string.h strings.h \
inttypes.h
}
teaish-check-librt
teaish-check-libz
}
########################################################################
# If --enable-threadsafe is set, this adds -DSQLITE_THREADSAFE=1 to
# OPT_FEATURE_FLAGS and sets LDFLAGS_PTHREAD to the linker flags
# needed for linking pthread (possibly an empty string). If
# --enable-threadsafe is not set, adds -DSQLITE_THREADSAFE=0 to
# OPT_FEATURE_FLAGS and sets LDFLAGS_PTHREAD to an empty string.
proc sqlite-handle-threadsafe {} {
msg-checking "Support threadsafe operation? "
define LDFLAGS_PTHREAD ""
set enable 0
if {[proj-opt-was-provided threadsafe]} {
proj-if-opt-truthy threadsafe {
if {[proj-check-function-in-lib pthread_create pthread]
&& [proj-check-function-in-lib pthread_mutexattr_init pthread]} {
set enable 1
define LDFLAGS_PTHREAD [get-define lib_pthread_create]
undefine lib_pthread_create
undefine lib_pthread_mutexattr_init
} elseif {[proj-opt-was-provided threadsafe]} {
user-error "Missing required pthread libraries. Use --disable-threadsafe to disable this check."
} else {
msg-result "pthread support not detected"
}
# Recall that LDFLAGS_PTHREAD might be empty even if pthreads if
# found because it's in -lc on some platforms.
} {
msg-result "Disabled using --disable-threadsafe"
}
} else {
#
# If user does not specify --[disable-]threadsafe then select a
# default based on whether it looks like TCL has threading
# support.
#
#puts "TCL_LIBS = [get-define TCL_LIBS]"
if {[string match *pthread* [get-define TCL_LIBS]]} {
# ^^^ FIXME: there must be a better way of testing this
set flagName "--threadsafe"
set lblAbled "en"
set enable 1
msg-result "yes"
} else {
set flagName "--disable-threadsafe"
set lblAbled "dis"
set enable 0
msg-result "no"
}
msg-result "NOTICE: defaulting to ${flagName} because TCL has threading ${lblAbled}abled."
# ^^^ We don't need to link against -lpthread in the is-enabled case.
}
sqlite-add-feature-flag -DSQLITE_THREADSAFE=${enable}
return $enable
}
########################################################################
# Handles the --enable-load-extension flag. Returns 1 if the support
# is enabled, else 0. If support for that feature is not found, a
# fatal error is triggered if --enable-load-extension is explicitly
# provided, else a loud warning is instead emitted. If
# --disable-load-extension is used, no check is performed.
#
# Makes the following environment changes:
#
# - defines LDFLAGS_DLOPEN to any linker flags needed for this
# feature. It may legally be empty on some systems where dlopen()
# is in libc.
#
# - If the feature is not available, adds
# -DSQLITE_OMIT_LOAD_EXTENSION=1 to the feature flags list.
proc sqlite-handle-load-extension {} {
define LDFLAGS_DLOPEN ""
set found 0
proj-if-opt-truthy load-extension {
set found [proj-check-function-in-lib dlopen dl]
if {$found} {
define LDFLAGS_DLOPEN [get-define lib_dlopen]
undefine lib_dlopen
} else {
if {[proj-opt-was-provided load-extension]} {
# Explicit --enable-load-extension: fail if not found
proj-indented-notice -error {
--enable-load-extension was provided but dlopen()
not found. Use --disable-load-extension to bypass this
check.
}
} else {
# It was implicitly enabled: warn if not found
proj-indented-notice {
WARNING: dlopen() not found, so loadable module support will
be disabled. Use --disable-load-extension to bypass this
check.
}
}
}
}
if {$found} {
msg-result "Loadable extension support enabled."
} else {
msg-result "Disabling loadable extension support. Use --enable-load-extension to enable them."
sqlite-add-feature-flag -DSQLITE_OMIT_LOAD_EXTENSION=1
}
return $found
}
########################################################################
# ICU - International Components for Unicode
#
# Handles these flags:
#
# --with-icu-ldflags=LDFLAGS
# --with-icu-cflags=CFLAGS
# --with-icu-config[=auto | pkg-config | /path/to/icu-config]
# --enable-icu-collations
#
# --with-icu-config values:
#
# - auto: use the first one of (pkg-config, icu-config) found on the
# system.
# - pkg-config: use only pkg-config to determine flags
# - /path/to/icu-config: use that to determine flags
#
# If --with-icu-config is used as neither pkg-config nor icu-config
# are found, fail fatally.
#
# If both --with-icu-ldflags and --with-icu-config are provided, they
# are cumulative. If neither are provided, icu-collations is not
# honored and a warning is emitted if it is provided.
#
# Design note: though we could automatically enable ICU if the
# icu-config binary or (pkg-config icu-io) are found, we specifically
# do not. ICU is always an opt-in feature.
proc sqlite-handle-icu {} {
define LDFLAGS_LIBICU [join [opt-val with-icu-ldflags ""]]
define CFLAGS_LIBICU [join [opt-val with-icu-cflags ""]]
if {[proj-opt-was-provided with-icu-config]} {
msg-result "Checking for ICU support..."
set icuConfigBin [opt-val with-icu-config]
set tryIcuConfigBin 1; # set to 0 if we end up using pkg-config
if {$icuConfigBin in {auto pkg-config}} {
uplevel 3 { use pkg-config }
if {[pkg-config-init 0] && [pkg-config icu-io]} {
# Maintenance reminder: historical docs say to use both of
# (icu-io, icu-uc). icu-uc lacks a required lib and icu-io has
# all of them on tested OSes.
set tryIcuConfigBin 0
define LDFLAGS_LIBICU [get-define PKG_ICU_IO_LDFLAGS]
define-append LDFLAGS_LIBICU [get-define PKG_ICU_IO_LIBS]
define CFLAGS_LIBICU [get-define PKG_ICU_IO_CFLAGS]
} elseif {"pkg-config" eq $icuConfigBin} {
proj-fatal "pkg-config cannot find package icu-io"
} else {
proj-assert {"auto" eq $icuConfigBin}
}
}
if {$tryIcuConfigBin} {
if {"auto" eq $icuConfigBin} {
set icuConfigBin [proj-first-bin-of \
/usr/local/bin/icu-config \
/usr/bin/icu-config]
if {"" eq $icuConfigBin} {
proj-indented-notice -error {
--with-icu-config=auto cannot find (pkg-config icu-io) or icu-config binary.
On Ubuntu-like systems try:
--with-icu-ldflags='-licui18n -licuuc -licudata'
}
}
}
if {[file-isexec $icuConfigBin]} {
set x [exec $icuConfigBin --ldflags]
if {"" eq $x} {
proj-indented-notice -error \
[subst {
$icuConfigBin --ldflags returned no data.
On Ubuntu-like systems try:
--with-icu-ldflags='-licui18n -licuuc -licudata'
}]
}
define-append LDFLAGS_LIBICU $x
set x [exec $icuConfigBin --cppflags]
define-append CFLAGS_LIBICU $x
} else {
proj-fatal "--with-icu-config=$icuConfigBin does not refer to an executable"
}
}
}
set ldflags [define LDFLAGS_LIBICU [string trim [get-define LDFLAGS_LIBICU]]]
set cflags [define CFLAGS_LIBICU [string trim [get-define CFLAGS_LIBICU]]]
if {"" ne $ldflags} {
sqlite-add-feature-flag -DSQLITE_ENABLE_ICU
msg-result "Enabling ICU support with flags: $ldflags $cflags"
if {[opt-bool icu-collations]} {
msg-result "Enabling ICU collations."
sqlite-add-feature-flag -DSQLITE_ENABLE_ICU_COLLATIONS
}
} elseif {[opt-bool icu-collations]} {
proj-warn "ignoring --enable-icu-collations because neither --with-icu-ldflags nor --with-icu-config provided any linker flags"
} else {
msg-result "ICU support is disabled."
}
}; # sqlite-handle-icu
########################################################################
# Handles the --with-tempstore flag.
#
# The test fixture likes to set SQLITE_TEMP_STORE on its own, so do
# not set that feature flag unless it was explicitly provided to the
# configure script.
proc sqlite-handle-tempstore {} {
if {[proj-opt-was-provided with-tempstore]} {
set ts [opt-val with-tempstore no]
set tsn 1
msg-checking "Use an in-RAM database for temporary tables? "
switch -exact -- $ts {
never { set tsn 0 }
no { set tsn 1 }
yes { set tsn 2 }
always { set tsn 3 }
default {
user-error "Invalid --with-tempstore value '$ts'. Use one of: never, no, yes, always"
}
}
msg-result $ts
sqlite-add-feature-flag -DSQLITE_TEMP_STORE=$tsn
}
}
########################################################################
# Handles the --enable-math flag.
proc sqlite-handle-math {} {
proj-if-opt-truthy math {
if {![proj-check-function-in-lib ceil m]} {
user-error "Cannot find libm functions. Use --disable-math to bypass this."
}
set lfl [get-define lib_ceil]
undefine lib_ceil
define LDFLAGS_MATH $lfl
teaish-prepend-ldflags $lfl
sqlite-add-feature-flag -DSQLITE_ENABLE_MATH_FUNCTIONS
msg-result "Enabling math SQL functions"
} {
define LDFLAGS_MATH ""
msg-result "Disabling math SQL functions"
}
}
########################################################################
# Move -DSQLITE_OMIT... and -DSQLITE_ENABLE... flags from CFLAGS and
# CPPFLAGS to OPT_FEATURE_FLAGS and remove them from BUILD_CFLAGS.
proc sqlite-munge-cflags {} {
# Move CFLAGS and CPPFLAGS entries matching -DSQLITE_OMIT* and
# -DSQLITE_ENABLE* to OPT_FEATURE_FLAGS. This behavior is derived
# from the legacy build and was missing the 3.48.0 release (the
# initial Autosetup port).
# https://sqlite.org/forum/forumpost/9801e54665afd728
#
# Handling of CPPFLAGS, as well as removing ENABLE/OMIT from
# CFLAGS/CPPFLAGS, was missing in the 3.49.0 release as well.
#
# If any configure flags for features are in conflict with
# CFLAGS/CPPFLAGS-specified feature flags, all bets are off. There
# are no guarantees about which one will take precedence.
foreach flagDef {CFLAGS CPPFLAGS} {
set tmp ""
foreach cf [get-define $flagDef ""] {
switch -glob -- $cf {
-DSQLITE_OMIT* -
-DSQLITE_ENABLE* {
sqlite-add-feature-flag $cf
}
default {
lappend tmp $cf
}
}
}
define $flagDef $tmp
}
}
-14
View File
@@ -1,14 +0,0 @@
test-expect 1.0-open {
sqlite3 db :memory:
} {}
test-assert 1.1-version-3.x {
[string match 3.* [db eval {select sqlite_version()}]]
}
test-expect 1.2-select {
db eval {select 'hi, world',1,2,3}
} {{hi, world} 1 2 3}
test-expect 99.0-db-close {db close} {}
-13
View File
@@ -1,13 +0,0 @@
# -*- tcl -*-
# Automatically generated - do not edit
#
# This is the wrapper script invoked by teaish's "make test" recipe.
load [lindex $::argv 0] [lindex $::argv 1]; source [lindex $::argv 2]
@if TEAISH_PKGINIT_TCL
apply {{} {set dir [file dirname $::argv0]; source @TEAISH_PKGINIT_TCL@}}
@endif
@if TEAISH_TEST_TCL
source @TEAISH_TEST_TCL@
@else
puts "Extension successfully loaded"
@endif
+61
View File
@@ -0,0 +1,61 @@
#------------------------------------------------------------- -*- makefile -*-
#
# Sample makefile for building Tcl extensions.
#
# Basic build, test and install
# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\tcl
# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\tcl test
# nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\tcl install
#
# For other build options (debug, static etc.)
# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
# detailed documentation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
#------------------------------------------------------------------------------
# PROJECT is sqlite, not sqlite3 to match TEA AC_INIT definition.
# This makes the generated DLL name also consistent between the two
# except for the "t" suffix which is the convention for nmake builds.
PROJECT = sqlite
PRJ_PACKAGE_TCLNAME = sqlite3
!include "rules-ext.vc"
PRJ_OBJS = $(TMP_DIR)\tclsqlite3.obj
# Preprocessor macros specific to sqlite3.
PRJ_DEFINES = -I"$(ROOT)\.." -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE \
-DSQLITE_ENABLE_DBPAGE_VTAB=1 -DSQLITE_ENABLE_DBSTAT_VTAB=1 \
-DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS4=1 \
-DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 \
-DSQLITE_ENABLE_JSON1=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1 \
-DSQLITE_3_SUFFIX_ONLY=1 -DSQLITE_ENABLE_RTREE=1 \
-DSQLITE_UNTESTABLE=1 -DSQLITE_OMIT_LOOKASIDE=1 \
-DSQLITE_SECURE_DELETE=1 -DSQLITE_SOUNDEX=1 -DSQLITE_ENABLE_GEOPOLY=1 \
-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 \
-DSQLITE_ENABLE_MATH_FUNCTIONS=1 -DDSQLITE_USE_ALLOCA=1 \
-DSQLITE_ENABLE_STAT4=1 -DSQLITE_OMIT_DEPRECATED=1 \
-DSQLITE_WIN32_GETVERSIONEX=0 -DSQLITE_WIN32_NO_ANSI=1
PRJ_DEFINES = $(PRJ_DEFINES) -I$(TMP_DIR)
# Standard targets to build, install, test etc.
!include "$(_RULESDIR)\targets.vc"
# The built-in pkgindex does no suffice for our extension as
# the PROJECT name (sqlite) is not same as init function name (Sqlite3)
pkgindex:
@echo if {[package vsatisfies [package provide Tcl] 9.0-]} { > $(OUT_DIR)\pkgIndex.tcl
@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
[list load [file join $$dir $(PRJLIBNAME9)] [string totitle $(PRJ_PACKAGE_TCLNAME)]] >> $(OUT_DIR)\pkgIndex.tcl
@echo } else { >> $(OUT_DIR)\pkgIndex.tcl
@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
[list load [file join $$dir $(PRJLIBNAME8)] [string totitle $(PRJ_PACKAGE_TCLNAME)]] >> $(OUT_DIR)\pkgIndex.tcl
@echo } >> $(OUT_DIR)\pkgIndex.tcl
# Install the manpage though on Windows, doubt it does much good
install: default-install-docs-n
# Explicit dependency rules
+815
View File
@@ -0,0 +1,815 @@
/*
* ----------------------------------------------------------------------------
* nmakehlp.c --
*
* This is used to fix limitations within nmake and the environment.
*
* Copyright (c) 2002 by David Gravereaux.
* Copyright (c) 2006 by Pat Thoyts
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
* ----------------------------------------------------------------------------
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <windows.h>
#ifdef _MSC_VER
#pragma comment (lib, "user32.lib")
#pragma comment (lib, "kernel32.lib")
#endif
#include <stdio.h>
#include <math.h>
/*
* This library is required for x64 builds with _some_ versions of MSVC
*/
#if defined(_M_IA64) || defined(_M_AMD64)
#if _MSC_VER >= 1400 && _MSC_VER < 1500
#pragma comment(lib, "bufferoverflowU")
#endif
#endif
/* ISO hack for dumb VC++ */
#ifdef _MSC_VER
#define snprintf _snprintf
#endif
/* protos */
static int CheckForCompilerFeature(const char *option);
static int CheckForLinkerFeature(char **options, int count);
static int IsIn(const char *string, const char *substring);
static int SubstituteFile(const char *substs, const char *filename);
static int QualifyPath(const char *path);
static int LocateDependency(const char *keyfile);
static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
static DWORD WINAPI ReadFromPipe(LPVOID args);
/* globals */
#define CHUNK 25
#define STATICBUFFERSIZE 1000
typedef struct {
HANDLE pipe;
char buffer[STATICBUFFERSIZE];
} pipeinfo;
pipeinfo Out = {INVALID_HANDLE_VALUE, ""};
pipeinfo Err = {INVALID_HANDLE_VALUE, ""};
/*
* exitcodes: 0 == no, 1 == yes, 2 == error
*/
int
main(
int argc,
char *argv[])
{
char msg[300];
DWORD dwWritten;
int chars;
const char *s;
/*
* Make sure children (cl.exe and link.exe) are kept quiet.
*/
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
/*
* Make sure the compiler and linker aren't effected by the outside world.
*/
SetEnvironmentVariable("CL", "");
SetEnvironmentVariable("LINK", "");
if (argc > 1 && *argv[1] == '-') {
switch (*(argv[1]+1)) {
case 'c':
if (argc != 3) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -c <compiler option>\n"
"Tests for whether cl.exe supports an option\n"
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return CheckForCompilerFeature(argv[2]);
case 'l':
if (argc < 3) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -l <linker option> ?<mandatory option> ...?\n"
"Tests for whether link.exe supports an option\n"
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return CheckForLinkerFeature(&argv[2], argc-2);
case 'f':
if (argc == 2) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -f <string> <substring>\n"
"Find a substring within another\n"
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
} else if (argc == 3) {
/*
* If the string is blank, there is no match.
*/
return 0;
} else {
return IsIn(argv[2], argv[3]);
}
case 's':
if (argc == 2) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -s <substitutions file> <file>\n"
"Perform a set of string map type substutitions on a file\n"
"exitcodes: 0\n",
argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return SubstituteFile(argv[2], argv[3]);
case 'V':
if (argc != 4) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -V filename matchstring\n"
"Extract a version from a file:\n"
"eg: pkgIndex.tcl \"package ifneeded http\"",
argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 0;
}
s = GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0');
if (s && *s) {
printf("%s\n", s);
return 0;
} else
return 1; /* Version not found. Return non-0 exit code */
case 'Q':
if (argc != 3) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -Q path\n"
"Emit the fully qualified path\n"
"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return QualifyPath(argv[2]);
case 'L':
if (argc != 3) {
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -L keypath\n"
"Emit the fully qualified path of directory containing keypath\n"
"exitcodes: 0 == success, 1 == not found, 2 == error\n", argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
&dwWritten, NULL);
return 2;
}
return LocateDependency(argv[2]);
}
}
chars = snprintf(msg, sizeof(msg) - 1,
"usage: %s -c|-f|-l|-Q|-s|-V ...\n"
"This is a little helper app to equalize shell differences between WinNT and\n"
"Win9x and get nmake.exe to accomplish its job.\n",
argv[0]);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
return 2;
}
static int
CheckForCompilerFeature(
const char *option)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
DWORD threadID;
char msg[300];
BOOL ok;
HANDLE hProcess, h, pipeThreads[2];
char cmdline[100];
hProcess = GetCurrentProcess();
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = INVALID_HANDLE_VALUE;
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = FALSE;
/*
* Create a non-inheritible pipe.
*/
CreatePipe(&Out.pipe, &h, &sa, 0);
/*
* Dupe the write side, make it inheritible, and close the original.
*/
DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
/*
* Same as above, but for the error side.
*/
CreatePipe(&Err.pipe, &h, &sa, 0);
DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
/*
* Base command line.
*/
lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");
/*
* Append our option for testing
*/
lstrcat(cmdline, option);
/*
* Filename to compile, which exists, but is nothing and empty.
*/
lstrcat(cmdline, " .\\nul");
ok = CreateProcess(
NULL, /* Module name. */
cmdline, /* Command line. */
NULL, /* Process handle not inheritable. */
NULL, /* Thread handle not inheritable. */
TRUE, /* yes, inherit handles. */
DETACHED_PROCESS, /* No console for you. */
NULL, /* Use parent's environment block. */
NULL, /* Use parent's starting directory. */
&si, /* Pointer to STARTUPINFO structure. */
&pi); /* Pointer to PROCESS_INFORMATION structure. */
if (!ok) {
DWORD err = GetLastError();
int chars = snprintf(msg, sizeof(msg) - 1,
"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars],
(300-chars), 0);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
return 2;
}
/*
* Close our references to the write handles that have now been inherited.
*/
CloseHandle(si.hStdOutput);
CloseHandle(si.hStdError);
WaitForInputIdle(pi.hProcess, 5000);
CloseHandle(pi.hThread);
/*
* Start the pipe reader threads.
*/
pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
/*
* Block waiting for the process to end.
*/
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
/*
* Wait for our pipe to get done reading, should it be a little slow.
*/
WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
CloseHandle(pipeThreads[0]);
CloseHandle(pipeThreads[1]);
/*
* Look for the commandline warning code in both streams.
* - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
*/
return !(strstr(Out.buffer, "D4002") != NULL
|| strstr(Err.buffer, "D4002") != NULL
|| strstr(Out.buffer, "D9002") != NULL
|| strstr(Err.buffer, "D9002") != NULL
|| strstr(Out.buffer, "D2021") != NULL
|| strstr(Err.buffer, "D2021") != NULL);
}
static int
CheckForLinkerFeature(
char **options,
int count)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
DWORD threadID;
char msg[300];
BOOL ok;
HANDLE hProcess, h, pipeThreads[2];
int i;
char cmdline[255];
hProcess = GetCurrentProcess();
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = INVALID_HANDLE_VALUE;
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
/*
* Create a non-inheritible pipe.
*/
CreatePipe(&Out.pipe, &h, &sa, 0);
/*
* Dupe the write side, make it inheritible, and close the original.
*/
DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
/*
* Same as above, but for the error side.
*/
CreatePipe(&Err.pipe, &h, &sa, 0);
DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
/*
* Base command line.
*/
lstrcpy(cmdline, "link.exe -nologo ");
/*
* Append our option for testing.
*/
for (i = 0; i < count; i++) {
lstrcat(cmdline, " \"");
lstrcat(cmdline, options[i]);
lstrcat(cmdline, "\"");
}
ok = CreateProcess(
NULL, /* Module name. */
cmdline, /* Command line. */
NULL, /* Process handle not inheritable. */
NULL, /* Thread handle not inheritable. */
TRUE, /* yes, inherit handles. */
DETACHED_PROCESS, /* No console for you. */
NULL, /* Use parent's environment block. */
NULL, /* Use parent's starting directory. */
&si, /* Pointer to STARTUPINFO structure. */
&pi); /* Pointer to PROCESS_INFORMATION structure. */
if (!ok) {
DWORD err = GetLastError();
int chars = snprintf(msg, sizeof(msg) - 1,
"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPSTR)&msg[chars],
(300-chars), 0);
WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
return 2;
}
/*
* Close our references to the write handles that have now been inherited.
*/
CloseHandle(si.hStdOutput);
CloseHandle(si.hStdError);
WaitForInputIdle(pi.hProcess, 5000);
CloseHandle(pi.hThread);
/*
* Start the pipe reader threads.
*/
pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
/*
* Block waiting for the process to end.
*/
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
/*
* Wait for our pipe to get done reading, should it be a little slow.
*/
WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
CloseHandle(pipeThreads[0]);
CloseHandle(pipeThreads[1]);
/*
* Look for the commandline warning code in the stderr stream.
*/
return !(strstr(Out.buffer, "LNK1117") != NULL ||
strstr(Err.buffer, "LNK1117") != NULL ||
strstr(Out.buffer, "LNK4044") != NULL ||
strstr(Err.buffer, "LNK4044") != NULL ||
strstr(Out.buffer, "LNK4224") != NULL ||
strstr(Err.buffer, "LNK4224") != NULL);
}
static DWORD WINAPI
ReadFromPipe(
LPVOID args)
{
pipeinfo *pi = (pipeinfo *) args;
char *lastBuf = pi->buffer;
DWORD dwRead;
BOOL ok;
again:
if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) {
CloseHandle(pi->pipe);
return (DWORD)-1;
}
ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L);
if (!ok || dwRead == 0) {
CloseHandle(pi->pipe);
return 0;
}
lastBuf += dwRead;
goto again;
return 0; /* makes the compiler happy */
}
static int
IsIn(
const char *string,
const char *substring)
{
return (strstr(string, substring) != NULL);
}
/*
* GetVersionFromFile --
* Looks for a match string in a file and then returns the version
* following the match where a version is anything acceptable to
* package provide or package ifneeded.
*/
static const char *
GetVersionFromFile(
const char *filename,
const char *match,
int numdots)
{
static char szBuffer[100];
char *szResult = NULL;
FILE *fp = fopen(filename, "rt");
if (fp != NULL) {
/*
* Read data until we see our match string.
*/
while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
LPSTR p, q;
p = strstr(szBuffer, match);
if (p != NULL) {
/*
* Skip to first digit after the match.
*/
p += strlen(match);
while (*p && !isdigit((unsigned char)*p)) {
++p;
}
/*
* Find ending whitespace.
*/
q = p;
while (*q && (strchr("0123456789.ab", *q)) && (((!strchr(".ab", *q)
&& !strchr("ab", q[-1])) || --numdots))) {
++q;
}
*q = 0;
szResult = p;
break;
}
}
fclose(fp);
}
return szResult;
}
/*
* List helpers for the SubstituteFile function
*/
typedef struct list_item_t {
struct list_item_t *nextPtr;
char * key;
char * value;
} list_item_t;
/* insert a list item into the list (list may be null) */
static list_item_t *
list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
{
list_item_t *itemPtr = (list_item_t *)malloc(sizeof(list_item_t));
if (itemPtr) {
itemPtr->key = strdup(key);
itemPtr->value = strdup(value);
itemPtr->nextPtr = NULL;
while(*listPtrPtr) {
listPtrPtr = &(*listPtrPtr)->nextPtr;
}
*listPtrPtr = itemPtr;
}
return itemPtr;
}
static void
list_free(list_item_t **listPtrPtr)
{
list_item_t *tmpPtr, *listPtr = *listPtrPtr;
while (listPtr) {
tmpPtr = listPtr;
listPtr = listPtr->nextPtr;
free(tmpPtr->key);
free(tmpPtr->value);
free(tmpPtr);
}
}
/*
* SubstituteFile --
* As windows doesn't provide anything useful like sed and it's unreliable
* to use the tclsh you are building against (consider x-platform builds -
* eg compiling AMD64 target from IX86) we provide a simple substitution
* option here to handle autoconf style substitutions.
* The substitution file is whitespace and line delimited. The file should
* consist of lines matching the regular expression:
* \s*\S+\s+\S*$
*
* Usage is something like:
* nmakehlp -S << $** > $@
* @PACKAGE_NAME@ $(PACKAGE_NAME)
* @PACKAGE_VERSION@ $(PACKAGE_VERSION)
* <<
*/
static int
SubstituteFile(
const char *substitutions,
const char *filename)
{
static char szBuffer[1024], szCopy[1024];
list_item_t *substPtr = NULL;
FILE *fp, *sp;
fp = fopen(filename, "rt");
if (fp != NULL) {
/*
* Build a list of substutitions from the first filename
*/
sp = fopen(substitutions, "rt");
if (sp != NULL) {
while (fgets(szBuffer, sizeof(szBuffer), sp) != NULL) {
unsigned char *ks, *ke, *vs, *ve;
ks = (unsigned char*)szBuffer;
while (ks && *ks && isspace(*ks)) ++ks;
ke = ks;
while (ke && *ke && !isspace(*ke)) ++ke;
vs = ke;
while (vs && *vs && isspace(*vs)) ++vs;
ve = vs;
while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
*ke = 0, *ve = 0;
list_insert(&substPtr, (char*)ks, (char*)vs);
}
fclose(sp);
}
/* debug: dump the list */
#ifndef NDEBUG
{
int n = 0;
list_item_t *p = NULL;
for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
}
}
#endif
/*
* Run the substitutions over each line of the input
*/
while (fgets(szBuffer, sizeof(szBuffer), fp) != NULL) {
list_item_t *p = NULL;
for (p = substPtr; p != NULL; p = p->nextPtr) {
char *m = strstr(szBuffer, p->key);
if (m) {
char *cp, *op, *sp;
cp = szCopy;
op = szBuffer;
while (op != m) *cp++ = *op++;
sp = p->value;
while (sp && *sp) *cp++ = *sp++;
op += strlen(p->key);
while (*op) *cp++ = *op++;
*cp = 0;
memcpy(szBuffer, szCopy, sizeof(szCopy));
}
}
printf("%s", szBuffer);
}
list_free(&substPtr);
}
fclose(fp);
return 0;
}
BOOL FileExists(LPCTSTR szPath)
{
#ifndef INVALID_FILE_ATTRIBUTES
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
DWORD pathAttr = GetFileAttributes(szPath);
return (pathAttr != INVALID_FILE_ATTRIBUTES &&
!(pathAttr & FILE_ATTRIBUTE_DIRECTORY));
}
/*
* QualifyPath --
*
* This composes the current working directory with a provided path
* and returns the fully qualified and normalized path.
* Mostly needed to setup paths for testing.
*/
static int
QualifyPath(
const char *szPath)
{
char szCwd[MAX_PATH + 1];
GetFullPathName(szPath, sizeof(szCwd)-1, szCwd, NULL);
printf("%s\n", szCwd);
return 0;
}
/*
* Implements LocateDependency for a single directory. See that command
* for an explanation.
* Returns 0 if found after printing the directory.
* Returns 1 if not found but no errors.
* Returns 2 on any kind of error
* Basically, these are used as exit codes for the process.
*/
static int LocateDependencyHelper(const char *dir, const char *keypath)
{
HANDLE hSearch;
char path[MAX_PATH+1];
size_t dirlen;
int keylen, ret;
WIN32_FIND_DATA finfo;
if (dir == NULL || keypath == NULL)
return 2; /* Have no real error reporting mechanism into nmake */
dirlen = strlen(dir);
if ((dirlen + 3) > sizeof(path))
return 2;
strncpy(path, dir, dirlen);
strncpy(path+dirlen, "\\*", 3); /* Including terminating \0 */
keylen = strlen(keypath);
#if 0 /* This function is not available in Visual C++ 6 */
/*
* Use numerics 0 -> FindExInfoStandard,
* 1 -> FindExSearchLimitToDirectories,
* as these are not defined in Visual C++ 6
*/
hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0);
#else
hSearch = FindFirstFile(path, &finfo);
#endif
if (hSearch == INVALID_HANDLE_VALUE)
return 1; /* Not found */
/* Loop through all subdirs checking if the keypath is under there */
ret = 1; /* Assume not found */
do {
int sublen;
/*
* We need to check it is a directory despite the
* FindExSearchLimitToDirectories in the above call. See SDK docs
*/
if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
continue;
sublen = strlen(finfo.cFileName);
if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
continue; /* Path does not fit, assume not matched */
strncpy(path+dirlen+1, finfo.cFileName, sublen);
path[dirlen+1+sublen] = '\\';
strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
if (FileExists(path)) {
/* Found a match, print to stdout */
path[dirlen+1+sublen] = '\0';
QualifyPath(path);
ret = 0;
break;
}
} while (FindNextFile(hSearch, &finfo));
FindClose(hSearch);
return ret;
}
/*
* LocateDependency --
*
* Locates a dependency for a package.
* keypath - a relative path within the package directory
* that is used to confirm it is the correct directory.
* The search path for the package directory is currently only
* the parent and grandparent of the current working directory.
* If found, the command prints
* name_DIRPATH=<full path of located directory>
* and returns 0. If not found, does not print anything and returns 1.
*/
static int LocateDependency(const char *keypath)
{
size_t i;
int ret;
static const char *paths[] = {"..", "..\\..", "..\\..\\.."};
for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
ret = LocateDependencyHelper(paths[i], keypath);
if (ret == 0)
return ret;
}
return ret;
}
/*
* Local variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* indent-tabs-mode: t
* tab-width: 8
* End:
*/
+123
View File
@@ -0,0 +1,123 @@
# This file should only be included in makefiles for Tcl extensions,
# NOT in the makefile for Tcl itself.
!ifndef _RULES_EXT_VC
# We need to run from the directory the parent makefile is located in.
# nmake does not tell us what makefile was used to invoke it so parent
# makefile has to set the MAKEFILEVC macro or we just make a guess and
# warn if we think that is not the case.
!if "$(MAKEFILEVC)" == ""
!if exist("$(PROJECT).vc")
MAKEFILEVC = $(PROJECT).vc
!elseif exist("makefile.vc")
MAKEFILEVC = makefile.vc
!endif
!endif # "$(MAKEFILEVC)" == ""
!if !exist("$(MAKEFILEVC)")
MSG = ^
You must run nmake from the directory containing the project makefile.^
If you are doing that and getting this message, set the MAKEFILEVC^
macro to the name of the project makefile.
!message WARNING: $(MSG)
!endif
!if "$(PROJECT)" == "tcl"
!error The rules-ext.vc file is not intended for Tcl itself.
!endif
# We extract version numbers using the nmakehlp program. For now use
# the local copy of nmakehlp. Once we locate Tcl, we will use that
# one if it is newer.
!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
!if [$(CC) -nologo -DNDEBUG "nmakehlp.c" -link -subsystem:console > nul]
!endif
!else
!if [copy x86_64-w64-mingw32-nmakehlp.exe nmakehlp.exe >NUL]
!endif
!endif
# First locate the Tcl directory that we are working with.
!if "$(TCLDIR)" != ""
_RULESDIR = $(TCLDIR:/=\)
!else
# If an installation path is specified, that is also the Tcl directory.
# Also Tk never builds against an installed Tcl, it needs Tcl sources
!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
_RULESDIR=$(INSTALLDIR:/=\)
!else
# Locate Tcl sources
!if [echo _RULESDIR = \> nmakehlp.out] \
|| [nmakehlp -L generic\tcl.h >> nmakehlp.out]
_RULESDIR = ..\..\tcl
!else
!include nmakehlp.out
!endif
!endif # defined(INSTALLDIR)....
!endif # ifndef TCLDIR
# Now look for the targets.vc file under the Tcl root. Note we check this
# file and not rules.vc because the latter also exists on older systems.
!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
_RULESDIR = $(_RULESDIR)\lib\nmake
!elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources
_RULESDIR = $(_RULESDIR)\win
!else
# If we have not located Tcl's targets file, most likely we are compiling
# against an older version of Tcl and so must use our own support files.
_RULESDIR = .
!endif
!if "$(_RULESDIR)" != "."
# Potentially using Tcl's support files. If this extension has its own
# nmake support files, need to compare the versions and pick newer.
!if exist("rules.vc") # The extension has its own copy
!if [echo TCL_RULES_MAJOR = \> versions.vc] \
&& [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
!endif
!if [echo TCL_RULES_MINOR = \>> versions.vc] \
&& [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
!endif
!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
&& [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
!endif
!if [echo OUR_RULES_MINOR = \>> versions.vc] \
&& [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
!endif
!include versions.vc
# We have a newer version of the support files, use them
!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
_RULESDIR = .
!endif
!endif # if exist("rules.vc")
!endif # if $(_RULESDIR) != "."
# Let rules.vc know what copy of nmakehlp.c to use.
NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
# Get rid of our internal defines before calling rules.vc
!undef TCL_RULES_MAJOR
!undef TCL_RULES_MINOR
!undef OUR_RULES_MAJOR
!undef OUR_RULES_MINOR
!if exist("$(_RULESDIR)\rules.vc")
!message *** Using $(_RULESDIR)\rules.vc
!include "$(_RULESDIR)\rules.vc"
!else
!error *** Could not locate rules.vc in $(_RULESDIR)
!endif
!endif # _RULES_EXT_VC
File diff suppressed because it is too large Load Diff
+98
View File
@@ -0,0 +1,98 @@
#------------------------------------------------------------- -*- makefile -*-
# targets.vc --
#
# Part of the nmake based build system for Tcl and its extensions.
# This file defines some standard targets for the convenience of extensions
# and can be optionally included by the extension makefile.
# See TIP 477 (https://core.tcl-lang.org/tips/doc/main/tip/477.md) for docs.
$(PROJECT): setup pkgindex $(PRJLIB)
!ifdef PRJ_STUBOBJS
$(PROJECT): $(PRJSTUBLIB)
$(PRJSTUBLIB): $(PRJ_STUBOBJS)
$(LIBCMD) $**
$(PRJ_STUBOBJS):
$(CCSTUBSCMD) %s
!endif # PRJ_STUBOBJS
!ifdef PRJ_MANIFEST
$(PROJECT): $(PRJLIB).manifest
$(PRJLIB).manifest: $(PRJ_MANIFEST)
@nmakehlp -s << $** >$@
@MACHINE@ $(MACHINE:IX86=X86)
<<
!endif
!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
!if $(STATIC_BUILD)
$(LIBCMD) $**
!else
$(DLLCMD) $**
$(_VC_MANIFEST_EMBED_DLL)
!endif
-@del $*.exp
!endif
!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
$(PRJ_OBJS): $(PRJ_HEADERS)
!endif
# If parent makefile has defined stub objects, add their installation
# to the default install
!if "$(PRJ_STUBOBJS)" != ""
default-install: default-install-stubs
!endif
# Unlike the other default targets, these cannot be in rules.vc because
# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
# that the parent makefile will not define until after including rules-ext.vc
!if "$(PRJ_HEADERS_PUBLIC)" != ""
default-install: default-install-headers
default-install-headers:
@echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
@for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
!endif
!if "$(DISABLE_STANDARD_TARGETS)" == ""
DISABLE_STANDARD_TARGETS = 0
!endif
!if "$(DISABLE_TARGET_setup)" == ""
DISABLE_TARGET_setup = 0
!endif
!if "$(DISABLE_TARGET_install)" == ""
DISABLE_TARGET_install = 0
!endif
!if "$(DISABLE_TARGET_clean)" == ""
DISABLE_TARGET_clean = 0
!endif
!if "$(DISABLE_TARGET_test)" == ""
DISABLE_TARGET_test = 0
!endif
!if "$(DISABLE_TARGET_shell)" == ""
DISABLE_TARGET_shell = 0
!endif
!if !$(DISABLE_STANDARD_TARGETS)
!if !$(DISABLE_TARGET_setup)
setup: default-setup
!endif
!if !$(DISABLE_TARGET_install)
install: default-install
!endif
!if !$(DISABLE_TARGET_clean)
clean: default-clean
realclean: hose
hose: default-hose
distclean: realclean default-distclean
!endif
!if !$(DISABLE_TARGET_test)
test: default-test
!endif
!if !$(DISABLE_TARGET_shell)
shell: default-shell
!endif
!endif # DISABLE_STANDARD_TARGETS
+44 -117
View File
@@ -14,9 +14,7 @@ build infrastructure. It is not an [Autosetup][] reference.
- Symbolic Names of Feature Flags
- Do Not Update Global Shared State
- [Updating Autosetup](#updating)
- ***[Patching Autosetup for Project-local changes](#patching)***
- [Branch-specific Customization](#branch-customization)
- [Patching Autosetup for Project-local changes](#patching)
------------------------------------------------------------------------
@@ -44,13 +42,12 @@ following files:
(e.g. Fossil), and personal projects of SQLite's developers. It is
essentially an amalgamation of a decade's worth of autosetup-related
utility code.
- [auto.def][]: the primary driver for the `./configure` process.
When we talk about "the configure script," we're referring to
this file.
- [sqlite-config.tcl][]: utility code which is too project-specific
for `proj.tcl`. We split this out of `auto.def` so that it can be
used by both `auto.def` and...
- [auto.def][]: the primary driver for the `./configure` process.
When we talk about "the configure script," we're technically
referring to this file, though it actually contains very little
of the TCL code.
- [autoconf/auto.def][]: the main driver script for the "autoconf"
bundle's configure script. It is essentially a slightly trimmed-down
version of the main `auto.def` file. The `autoconf` dir was ported
@@ -64,11 +61,11 @@ 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
from a casual perusal of the relevant TCL files. The complete docs of
those with `proj-` prefix can be found in [proj.tcl][] and those with
an `sqlite-` prefix are in [sqlite-config.tcl][]. The others are part
of Autosetup's core packages and are scattered around [the TCL files
in ./autosetup](/dir/autosetup).
obvious from a casual perusal of the relevant TCL files. The complete
docs of those with `proj-` prefix can be found in [proj.tcl][] and
those with an `sqlite-` prefix are in [sqlite-config.tcl][]. The
others are scattered around [the TCL files in
./autosetup](/dir/autosetup).
In (mostly) alphabetical order:
@@ -86,14 +83,19 @@ In (mostly) alphabetical order:
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`.\
Tip: adding `-O0` to `.env-CFLAGS` reduces rebuild times
considerably at the cost of performance in `make devtest` and the
like.
local preferences for the default `CFLAGS`.
- **`define-for-opt flag defineName ?checkingMsg? ?yesVal=1? ?noVal=0?`**\
`[define $defineName]` to either `$yesVal` or `$noVal`, depending on
whether `--$flag` is truthy or not. `$checkingMsg` is a
human-readable description of the check being made, e.g. "enable foo?"
If no `checkingMsg` is provided, the operation is silent.\
Potential TODO: change the final two args to `-yes` and `-no`
flags. They're rarely needed, though: search [auto.def][] for
`TSTRNNR_OPTS` for an example of where they are used.
- **`proj-fatal msg`**\
Emits `$msg` to stderr and exits with non-zero. Its differences from
autosetup's `user-error` are purely cosmetic.
Emits `$msg` to stderr and exits with non-zero.
- **`proj-if-opt-truthy flag thenScript ?elseScript?`**\
Evals `thenScript` if the given `--flag` is truthy, else it
@@ -115,10 +117,7 @@ In (mostly) alphabetical order:
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, where in the latter case it's not.\
Unlike most functions which deal with `--flags`, this one does not
validate that `$FLAG` is a registered flag so will not fail fatally
if `$FLAG` is not registered as an Autosetup option.
be treated as fatal, where in the latter case it's not.
- **`proj-val-truthy value`**\
Returns 1 if `$value` is "truthy," See `proj-opt-truthy` for the definition
@@ -140,15 +139,6 @@ In (mostly) alphabetical order:
The shell-specific counterpart of `sqlite-add-feature-flag` which
only adds the given flag(s) to the CLI-shell-specific CFLAGS.
- **`sqlite-configure BUILD-NAME {script}`**\
This is where all configure `--flags` are defined for all known
build modes ("canonical" or "autoconf"). After processing all flags,
this function runs `$script`, which contains the build-mode-specific
configuration bits, and then runs any finalization bits which are
common to all build modes. The `auto.def` files are intended to contain
exactly two commands:
`use sqlite-config; sqlite-configure BUILD-NAME {script}`
- **`user-notice msg`**\
Queues `$msg` to be sent to stderr, but does not emit it until
either `show-notices` is called or the next time autosetup would
@@ -162,18 +152,13 @@ In (mostly) alphabetical order:
Ensuring TCL Compatibility
========================================================================
One of the significant benefits of using Autosetup is that (A) this
project uses many TCL scripts in the build process and (B) Autosetup
comes with a TCL interpreter named [JimTCL][].
It is important that any TCL files used by the configure process and
makefiles 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.
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
@@ -202,17 +187,14 @@ compatibility across TCL implementations:
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
**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-only implementation of `[file-normalize]` (note the dash) for
portable use in the configure script. Contrariwise, code-generation
scripts invoked via `make` may use `[file normalize]`, as they'll use
`./jimsh` or `tclsh` instead of `./jimsh0`.
portable use in the configure script.
Known TCL Incompatibilities
------------------------------------------------------------------------
@@ -239,7 +221,6 @@ A summary of known incompatibilities in JimTCL
- `regsub` does not support the `\y` flag. A workaround is demonstrated
in [](/info/c2e5dd791cce3ec4).
<a name="conventions"></a>
Design Conventions
========================================================================
@@ -266,9 +247,8 @@ 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 from `@X_Y@`
into into `X.y` form for consumption by [Makefile.in][] and
[main.mk][]. For example:
exactly once in [Makefile.in][], where it's translated into into `X.y`
form for consumption by [Makefile.in][] and [main.mk][]. For example:
>
```
@@ -285,9 +265,9 @@ of taste, for which there is no accounting.)
Do Not Update Global Shared State
------------------------------------------------------------------------
In both the legacy Autotools-driven build and common Autosetup usage,
feature tests performed by the configure script may amend global flags
such as `LIBS`, `LDFLAGS`, and `CFLAGS`[^as-cflags]. That's
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:
@@ -295,8 +275,8 @@ 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
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
@@ -377,70 +357,17 @@ Patching Autosetup for Project-local Changes
Autosetup reserves the flag name **`--debug`** for its own purposes,
and its own special handling of `--enable-...` flags makes `--debug`
an alias for `--enable-debug`. As this project has a long history of
using `--enable-debug`, we patch autosetup to use the name
`--autosetup-debug` in place of `--debug`. That requires (as of this
writing) four small edits in [](/file/autosetup/autosetup), as
demonstrated in [check-in 3296c8d3](/info/3296c8d3).
an alias for `--enable-debug`. As we have a long history of using
`--enable-debug` for this project's own purposes, we patch autosetup
to use the name `--autosetup-debug` in place of `--debug`. That
requires (as of this writing) four small edits in
[](/file/autosetup/autosetup), as demonstrated in [check-in
3296c8d3](/info/3296c8d3).
If autosetup is upgraded and this patch is _not_ applied the invoking
`./configure` will fail loudly because of the declaration of the
`debug` flag in `auto.def` - duplicated flags are not permitted.
<a name="branch-customization"></a>
Branch-specific Customization
========================================================================
Certain vendor-specific branches require slight configure script
customization. Rather than editing `sqlite-config.tcl` for this,
which frequently leads to merge conflicts, the following approach
is recommended:
In the vendor-specific branch, create a file named
`autosetup/sqlite-custom.tcl`.
That file should contain the following content...
If flag customization is required, add:
>
```
proc sqlite-custom-flags {} {
# If any existing --flags require different default values
# then call:
options-defaults {
flag-name new-default-value
...
}
# ^^^ That will replace the default value but will not update
# the --help text, which may lead to some confusion:
# https://github.com/msteveb/autosetup/issues/77
return {
{*} {
new-flag-name => {Help text}
...
}
}; #see below
}
```
That function must return either an empty string or a list in the form
used internally by `sqlite-config.tcl:sqlite-configure`.
Next, define:
>
```
proc sqlite-custom-handle-flags {} {
... do any custom flag handling here ...
}
```
That function, if defined, will be called relatively late in the
configure process, before any filtered files are generated but after
all other significant processing.
[Autosetup]: https://msteveb.github.io/autosetup/
[auto.def]: /file/auto.def
+4 -8
View File
@@ -1634,8 +1634,8 @@ proc automf_command_reference {} {
if {[regexp {^#.*@section (.*)$} $line -> section]} {
lappend doc($current) [list section $section]
continue
}
continue
}
# Find embedded module names
if {[regexp {^#.*@module ([^ ]*)} $line -> modulename]} {
@@ -1651,7 +1651,7 @@ proc automf_command_reference {} {
if {$cmd eq "synopsis:"} {
set current $modulename
lappend doc($current) [list section "Module: $modulename"]
} else {
} else {
lappend doc($current) [list subsection $cmd]
}
@@ -2088,12 +2088,8 @@ if {$autosetup(iswin)} {
proc split-path {} {
split [getenv PATH .] :
}
# Check for an executable file
proc file-isexec {exec} {
if {[file executable $exec] && [file isfile $exec]} {
return 1
}
return 0
file executable $exec
}
}
+1 -1
View File
@@ -9,7 +9,7 @@ for tclsh in ./jimsh0 $autosetup_tclsh jimsh tclsh tclsh8.5 tclsh8.6 tclsh8.7; d
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"; } 2>/dev/null >/dev/null || continue
{ $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."
+12 -8
View File
@@ -1252,14 +1252,6 @@ int Jim_OpenForRead(const char *filename);
#endif
# ifndef MAXPATHLEN
# ifdef PATH_MAX
# define MAXPATHLEN PATH_MAX
# else
# define MAXPATHLEN JIM_PATH_LEN
# endif
# endif
int Jim_FileStoreStatData(Jim_Interp *interp, Jim_Obj *varName, const jim_stat_t *sb);
@@ -2096,6 +2088,10 @@ enum wbuftype {
#define UNIX_SOCKETS 0
#endif
#ifndef MAXPATHLEN
#define MAXPATHLEN JIM_PATH_LEN
#endif
@@ -4177,6 +4173,14 @@ int Jim_regexpInit(Jim_Interp *interp)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
# ifndef MAXPATHLEN
# ifdef PATH_MAX
# define MAXPATHLEN PATH_MAX
# else
# define MAXPATHLEN JIM_PATH_LEN
# endif
# endif
#if defined(__MINGW32__) || defined(__MSYS__) || defined(_MSC_VER)
#define ISWINDOWS 1
+87 -481
View File
@@ -15,16 +15,12 @@
# The intent is that these routines be relatively generic, independent
# of a given project.
#
# For practical purposes, the copy of this file hosted in the SQLite
# project is the "canonical" one:
#
# https://sqlite.org/src/file/autosetup/proj.tcl
#
# This file was initially derived from one used in the libfossil
# project, authored by the same person who ported it here, and this is
# noted here only as an indication that there are no licensing issues
# despite this code having a handful of near-twins running around a
# handful of third-party source trees.
#
########################################################################
#
# Design notes:
@@ -58,54 +54,43 @@
# $proj_ is an internal-use-only array for storing whatever generic
# internal stuff we need stored.
array set proj_ {}
#
# List of dot-in files to filter in the final stages of
# configuration. Some configuration steps may append to this. Each
# one in this list which exists will trigger the generation of a
# file with that same name, minus the ".in", in the build directory
# (which differ from the source dir in out-of-tree builds).
#
# See: proj-dot-ins-append and proj-dot-ins-process
#
set proj_(dot-in-files) {}
set proj_(isatty) [isatty? stdout]
########################################################################
# @proj-warn msg
#
# Emits a warning message to stderr.
proc proj-warn {args} {
proc proj-warn {msg} {
show-notices
puts stderr [join [list "WARNING:" {*}$args] " "]
puts stderr "WARNING: $msg"
}
########################################################################
# @proj-error msg
#
# Emits an error message to stderr and exits with non-0.
proc proj-fatal {args} {
proc proj-fatal {msg} {
show-notices
puts stderr "ERROR: \[[proj-current-scope 1]]: $args"
puts stderr "ERROR: $msg"
exit 1
}
########################################################################
# @proj-assert script ?message?
# @proj-assert script
#
# Kind of like a C assert: if uplevel (eval) of [expr {$script}] is
# false, a fatal error is triggered. The error message, by default,
# includes the body of the failed assertion, but if $msg is set then
# includes the body of the failed assertion, but if $descr is set then
# that is used instead.
proc proj-assert {script {msg ""}} {
proc proj-assert {script {descr ""}} {
if {1 == [get-env proj-assert 0]} {
msg-result [proj-bold "asserting: $script"]
}
set x "expr \{ $script \}"
if {![uplevel 1 $x]} {
if {"" eq $msg} {
set msg $script
if {"" eq $descr} {
set descr $script
}
proj-fatal "Assertion failed: $msg"
proj-fatal "Assertion failed: $descr"
}
}
@@ -115,18 +100,17 @@ proc proj-assert {script {msg ""}} {
# 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.
proc proj-bold {args} {
proc proj-bold {str} {
if {$::autosetup(iswin) || !$::proj_(isatty)} {
return $str
}
return "\033\[1m${args}\033\[0m"
return "\033\[1m${str}\033\[0m"
}
########################################################################
# @proj-indented-notice ?-error? ?-notice? msg
#
# Takes a multi-line message and emits it with consistent indentation.
# It does not perform any line-wrapping of its own.
#
# If the -notice flag it used then it emits using [user-notice], which
# means its rendering will (A) go to stderr and (B) be delayed until
@@ -179,13 +163,30 @@ proc proj-is-cross-compiling {} {
}
########################################################################
# @proj-strip-hash-comments value
# proj-lshift_ shifts $count elements from the list named $listVar
# and returns them as a new list. On empty input, returns "".
#
# Modified slightly from: https://wiki.tcl-lang.org/page/lshift
proc proj-lshift_ {listVar {count 1}} {
upvar 1 $listVar l
if {![info exists l]} {
# make the error message show the real variable name
error "can't read \"$listVar\": no such variable"
}
if {![llength $l]} {
# error Empty
return ""
}
set r [lrange $l 0 [incr count -1]]
set l [lreplace $l [set l 0] $count]
return $r
}
########################################################################
# Expects to receive string input, which it splits on newlines, strips
# out any lines which begin with any number of whitespace followed by
# a '#', and returns a value containing the [append]ed results of each
# remaining line with a \n between each. It does not strip out
# comments which appear after the first non-whitespace character.
# remaining line with a \n between each.
proc proj-strip-hash-comments {val} {
set x {}
foreach line [split $val \n] {
@@ -196,42 +197,16 @@ proc proj-strip-hash-comments {val} {
return $x
}
########################################################################
# @proj-cflags-without-werror
#
# Fetches [define $var], strips out any -Werror entries, and returns
# the new value. This is intended for temporarily stripping -Werror
# from CFLAGS or CPPFLAGS within the scope of a [define-push] block.
proc proj-cflags-without-werror {{var CFLAGS}} {
set rv {}
foreach f [get-define $var ""] {
switch -exact -- $f {
-Werror {}
default { lappend rv $f }
}
}
return [join $rv " "]
}
########################################################################
# @proj-check-function-in-lib
#
# A proxy for cc-check-function-in-lib with the following differences:
#
# - Does not make any global changes to the LIBS define.
#
# - Strips out the -Werror flag from CFLAGS before running the test,
# as these feature tests will often fail if -Werror is used.
#
# Returns the result of cc-check-function-in-lib (i.e. true or false).
# The resulting linker flags are stored in the [define] named
# lib_${function}.
# 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 the [define] named lib_${function}.
proc proj-check-function-in-lib {function libs {otherlibs {}}} {
set found 0
define-push {LIBS CFLAGS} {
#puts "CFLAGS before=[get-define CFLAGS]"
define CFLAGS [proj-cflags-without-werror]
#puts "CFLAGS after =[get-define CFLAGS]"
define-push {LIBS} {
set found [cc-check-function-in-lib $function $libs $otherlibs]
}
return $found
@@ -359,9 +334,6 @@ proc proj-first-bin-of {args} {
# to the default value of baz. If the user does not explicitly pass in
# --foo-bar (with or without a value) then this returns 0.
#
# Calling [proj-opt-set] is, for purposes of the above, equivalent to
# explicitly passing in the flag.
#
# Note: unlike most functions which deal with configure --flags, this
# one does not validate that $key refers to a pre-defined flag. i.e.
# it accepts arbitrary keys, even those not defined via an [options]
@@ -381,6 +353,7 @@ proc proj-opt-was-provided {key} {
#
# Returns $val.
proc proj-opt-set {flag {val 1}} {
global autosetup
if {$flag ni $::autosetup(options)} {
# We have to add this to autosetup(options) or else future calls
# to [opt-bool $flag] will fail validation of $flag.
@@ -390,15 +363,6 @@ proc proj-opt-set {flag {val 1}} {
return $val
}
########################################################################
# @proj-opt-exists flag
#
# Returns 1 if the given flag has been defined as a legal configure
# option, else returns 0.
proc proj-opt-exists {flag} {
expr {$flag in $::autosetup(options)};
}
########################################################################
# @proj-val-truthy val
#
@@ -478,16 +442,16 @@ proc proj-opt-define-bool {args} {
set invert 0
if {[lindex $args 0] eq "-v"} {
set invert 1
lassign $args - optName defName descr
} else {
lassign $args optName defName descr
set args [lrange $args 1 end]
}
set optName [proj-lshift_ args]
set defName [proj-lshift_ args]
set descr [proj-lshift_ args]
if {"" eq $descr} {
set descr $defName
}
#puts "optName=$optName defName=$defName descr=$descr"
set rc 0
msg-checking "[join $descr] ... "
msg-checking "$descr ... "
if {[proj-opt-truthy $optName]} {
if {0 eq $invert} {
set rc 1
@@ -593,7 +557,7 @@ proc proj-file-content {args} {
set trim 1
lassign $args - fname
}
set fp [open $fname rb]
set fp [open $fname r]
set rc [read $fp]
close $fp
if {$trim} { return [string trim $rc] }
@@ -606,7 +570,7 @@ proc proj-file-content {args} {
# 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} {
set fp [open $fname rb]
set fp [open $fname r]
set rc {}
while { [gets $fp line] >= 0 } {
lappend rc $line
@@ -615,31 +579,6 @@ proc proj-file-content-list {fname} {
return $rc
}
########################################################################
# @proj-file-write ?-ro? fname content
#
# Works like autosetup's [writefile] but explicitly uses binary mode
# to avoid EOL translation on Windows. If $fname already exists, it is
# overwritten, even if it's flagged as read-only.
proc proj-file-write {args} {
if {"-ro" eq [lindex $args 0]} {
lassign $args ro fname content
} else {
set ro ""
lassign $args fname content
}
file delete -force -- $fname; # in case it's read-only
set f [open $fname wb]
puts -nonewline $f $content
close $f
if {"" ne $ro} {
catch {
exec chmod -w $fname
#file attributes -w $fname; #jimtcl has no 'attributes'
}
}
}
########################################################################
# @proj-check-compile-commands ?configFlag?
#
@@ -648,12 +587,10 @@ proc proj-file-write {args} {
# which controls whether to run/skip this check.
#
# Returns 1 if supported, else 0. Defines MAKE_COMPILATION_DB to "yes"
# if supported, "no" if not. The use of MAKE_COMPILATION_DB is
# deprecated/discouraged. It also sets HAVE_COMPILE_COMMANDS to 0 or
# 1, and that's the preferred usage.
# if supported, "no" if not.
#
# ACHTUNG: this test has a long history of false positive results
# because of compilers reacting differently to the -MJ flag.
# This test has a long history of false positive results because of
# compilers reacting differently to the -MJ flag.
proc proj-check-compile-commands {{configFlag {}}} {
msg-checking "compile_commands.json support... "
if {"" ne $configFlag && ![proj-opt-truthy $configFlag]} {
@@ -666,13 +603,11 @@ proc proj-check-compile-commands {{configFlag {}}} {
# Martin G.'s older systems. drh also reports a false
# positive on an unspecified older Mac system.
msg-result "compiler supports compile_commands.json"
define MAKE_COMPILATION_DB yes; # deprecated
define HAVE_COMPILE_COMMANDS 1
define MAKE_COMPILATION_DB yes
return 1
} else {
msg-result "compiler does not support compile_commands.json"
define MAKE_COMPILATION_DB no
define HAVE_COMPILE_COMMANDS 0
return 0
}
}
@@ -688,18 +623,11 @@ proc proj-touch {filename} {
}
########################################################################
# @proj-make-from-dot-in ?-touch? infile ?outfile?
# @proj-make-from-dot-in ?-touch? filename...
#
# Uses [make-template] to create makefile(-like) file(s) $outfile from
# $infile but explicitly makes the output read-only, to avoid
# inadvertent editing (who, me?).
#
# If $outfile is empty then:
#
# - If $infile is a 2-element list, it is assumed to be an in/out pair,
# and $outfile is set from the 2nd entry in that list. Else...
#
# - $outfile is set to $infile stripped of its extension.
# Uses [make-template] to create makefile(-like) file(s) $filename
# from $filename.in but explicitly makes the output read-only, to
# avoid inadvertent editing (who, me?).
#
# If the first argument is -touch then the generated file is touched
# to update its timestamp. This can be used as a workaround for
@@ -709,34 +637,20 @@ proc proj-touch {filename} {
#
# Failures when running chmod or touch are silently ignored.
proc proj-make-from-dot-in {args} {
set fIn ""
set fOut ""
set filename $args
set touch 0
if {[lindex $args 0] eq "-touch"} {
set touch 1
lassign $args - fIn fOut
} else {
lassign $args fIn fOut
set filename [lrange $args 1 end]
}
if {"" eq $fOut} {
if {[llength $fIn]>1} {
lassign $fIn fIn fOut
} else {
set fOut [file rootname $fIn]
foreach f $filename {
set f [string trim $f]
catch { exec chmod u+w $f }
make-template $f.in $f
if {$touch} {
proj-touch $f
}
}
#puts "filenames=$filename"
if {[file exists $fOut]} {
catch { exec chmod u+w $fOut }
}
#puts "making template: $fIn ==> $fOut"
make-template $fIn $fOut
if {$touch} {
proj-touch $fOut
}
catch {
exec chmod -w $fOut
#file attributes -w $f; #jimtcl has no 'attributes'
catch { exec chmod -w $f }
}
}
@@ -794,7 +708,7 @@ proc proj-looks-like-windows {{key host}} {
# These apply only to the local OS, not a cross-compilation target,
# as the above check potentially can.
if {$::autosetup(iswin)} { return 1 }
if {[find-an-executable cygpath] ne "" || $::tcl_platform(os) eq "Windows NT"} {
if {[find-an-executable cygpath] ne "" || $::tcl_platform(os)=="Windows NT"} {
return 1
}
}
@@ -993,35 +907,6 @@ proc proj-check-emsdk {} {
return $rc
}
########################################################################
# @proj-cc-check-Wl-flag ?flag ?args??
#
# Checks whether the given linker flag (and optional arguments) can be
# passed from the compiler to the linker using one of these formats:
#
# - -Wl,flag[,arg1[,...argN]]
# - -Wl,flag -Wl,arg1 ...-Wl,argN
#
# If so, that flag string is returned, else an empty string is
# returned.
proc proj-cc-check-Wl-flag {args} {
cc-with {-link 1} {
# Try -Wl,flag,...args
set fli "-Wl"
foreach f $args { append fli ",$f" }
if {[cc-check-flags $fli]} {
return $fli
}
# Try -Wl,flag -Wl,arg1 ...-Wl,argN
set fli ""
foreach f $args { append fli "-Wl,$f " }
if {[cc-check-flags $fli]} {
return [string trim $fli]
}
return ""
}
}
########################################################################
# @proj-check-rpath
#
@@ -1033,7 +918,12 @@ proc proj-cc-check-Wl-flag {args} {
# --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
if {[proj-opt-was-provided libdir]
|| [proj-opt-was-provided exec-prefix]} {
set lp "[get-define libdir]"
@@ -1044,18 +934,21 @@ proc proj-check-rpath {} {
# CFLAGS or LIBS or whatever it is that cc-check-flags updates) then
# downstream tests may fail because the resulting rpath gets
# implicitly injected into them.
cc-with {-link 1} {
cc-with {} {
if {[cc-check-flags "-rpath $lp"]} {
define LDFLAGS_RPATH "-rpath $lp"
} elseif {[cc-check-flags "-Wl,-rpath,$lp"]} {
define LDFLAGS_RPATH "-Wl,-rpath,$lp"
} elseif {[cc-check-flags "-Wl,-rpath -Wl,$lp"]} {
define LDFLAGS_RPATH "-Wl,-rpath -Wl,$lp"
} elseif {[cc-check-flags -Wl,-R$lp]} {
define LDFLAGS_RPATH "-Wl,-R$lp"
} else {
set wl [proj-cc-check-Wl-flag -rpath $lp]
if {"" eq $wl} {
set wl [proj-cc-check-Wl-flag -R$lp]
}
define LDFLAGS_RPATH $wl
define LDFLAGS_RPATH ""
set rc 0
}
}
expr {"" ne [get-define LDFLAGS_RPATH]}
return $rc
}
########################################################################
@@ -1072,7 +965,7 @@ proc proj-check-rpath {} {
# 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 {-link 1} {
cc-with {} {
if {[cc-check-flags "-Wl,-soname,${libname}"]} {
define LDFLAGS_SONAME_PREFIX "-Wl,-soname,"
return 1
@@ -1083,39 +976,6 @@ proc proj-check-soname {{libname "libfoo.so.0"}} {
}
}
########################################################################
# @proj-check-fsanitize ?list-of-opts?
#
# Checks whether CC supports -fsanitize=X, where X is each entry of
# the given list of flags. If any of those flags are supported, it
# returns the string "-fsanitize=X..." where X... is a comma-separated
# list of all flags from the original set which are supported. If none
# of the given options are supported then it returns an empty string.
#
# Example:
#
# set f [proj-check-fsanitize {address bounds-check just-testing}]
#
# Will, on many systems, resolve to "-fsanitize=address,bounds-check",
# but may also resolve to "-fsanitize=address".
proc proj-check-fsanitize {{opts {address bounds-strict}}} {
set sup {}
foreach opt $opts {
# -nooutput is used because -fsanitize=hwaddress will otherwise
# pass this test on x86_64, but then warn at build time that
# "hwaddress is not supported for this target".
cc-with {-nooutput 1} {
if {[cc-check-flags "-fsanitize=$opt"]} {
lappend sup $opt
}
}
}
if {[llength $sup] > 0} {
return "-fsanitize=[join $sup ,]"
}
return ""
}
########################################################################
# Internal helper for proj-dump-defs-json. Expects to be passed a
# [define] name and the variadic $args which are passed to
@@ -1263,11 +1123,6 @@ proc proj-dump-defs-json {file args} {
# 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.
#
# That said: autosetup's [opt-src] does support alias forms, but it
# requires that the caller know all possible aliases. It's simpler, in
# terms of options handling, if there's only a single canonical name
# which each down-stream call of [opt-...] has to know.
proc proj-xfer-options-aliases {mapping} {
foreach {hidden - canonical} [proj-strip-hash-comments $mapping] {
if {[proj-opt-was-provided $hidden]} {
@@ -1283,7 +1138,7 @@ proc proj-xfer-options-aliases {mapping} {
########################################################################
# Arguable/debatable...
#
# When _not_ cross-compiling and CC_FOR_BUILD is _not_ explicitly
# When _not_ cross-compiling and CC_FOR_BUILD is _not_ explcitely
# specified, force CC_FOR_BUILD to be the same as CC, so that:
#
# ./configure CC=clang
@@ -1291,7 +1146,7 @@ proc proj-xfer-options-aliases {mapping} {
# will use CC_FOR_BUILD=clang, instead of cc, for building in-tree
# tools. This is based off of an email discussion and is thought to
# be likely to cause less confusion than seeing 'cc' invocations
# when when the user passes CC=clang.
# will when the user passes CC=clang.
#
# 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
@@ -1336,11 +1191,11 @@ proc proj-which-linenoise {dotH} {
#
# In that make invocation, $(libdir) would, at make-time, normally be
# hard-coded to /foo/lib, rather than /blah/lib. That happens because
# autosetup exports conventional $prefix-based values for the numerous
# 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.
# the autosetup exports conventional $prefix-based values for the
# numerous 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
@@ -1420,252 +1275,3 @@ proc proj-env-file {flag {dflt ""}} {
proc proj-get-env {var {dflt ""}} {
return [get-env $var [proj-env-file $var $dflt]]
}
########################################################################
# @proj-current-scope ?lvl?
#
# Returns the name of the _calling_ proc from ($lvl + 1) levels up the
# call stack (where the caller's level will be 1 up from _this_
# call). If $lvl would resolve to global scope "global scope" is
# returned and if it would be negative then a string indicating such
# is returned (as opposed to throwing an error).
proc proj-current-scope {{lvl 0}} {
#uplevel [expr {$lvl + 1}] {lindex [info level 0] 0}
set ilvl [info level]
set offset [expr {$ilvl - $lvl - 1}]
if { $offset < 0} {
return "invalid scope ($offset)"
} elseif { $offset == 0} {
return "global scope"
} else {
return [lindex [info level $offset] 0]
}
}
########################################################################
# Converts parts of tclConfig.sh to autosetup [define]s.
#
# Expects to be passed the name of a value tclConfig.sh or an empty
# string. It converts certain parts of that file's contents to
# [define]s (see the code for the whole list). If $tclConfigSh is an
# empty string then it [define]s the various vars as empty strings.
proc proj-tclConfig-sh-to-autosetup {tclConfigSh} {
set shBody {}
set tclVars {
TCL_INCLUDE_SPEC
TCL_LIBS
TCL_LIB_SPEC
TCL_STUB_LIB_SPEC
TCL_EXEC_PREFIX
TCL_PREFIX
TCL_VERSION
TCL_MAJOR_VERSION
TCL_MINOR_VERSION
TCL_PATCH_LEVEL
TCL_SHLIB_SUFFIX
}
# Build a small shell script which proxies the $tclVars from
# $tclConfigSh into autosetup code...
lappend shBody "if test x = \"x${tclConfigSh}\"; then"
foreach v $tclVars {
lappend shBody "$v= ;"
}
lappend shBody "else . \"${tclConfigSh}\"; fi"
foreach v $tclVars {
lappend shBody "echo define $v {\$$v} ;"
}
lappend shBody "exit"
set shBody [join $shBody "\n"]
#puts "shBody=$shBody\n"; exit
if {0} {
# This doesn't work but would be preferable to using a temp file...
set fd [open "| sh" "rw"]
#puts "fd = $fd"; exit
puts $fd $shBody
flush $fd
set rd [read $fd]
close $fd
puts "rd=$rd"; exit 1
eval $rd
} else {
set shName ".tclConfigSh.tcl"
proj-file-write $shName $shBody
eval [exec sh $shName $tclConfigSh]
file delete -force $shName
}
}
########################################################################
# @proj-tweak-default-env-dirs
#
# This function is not useful before [use system] is called to set up
# --prefix and friends. It should be called as soon after [use system]
# as feasible.
#
# For certain target environments, if --prefix is _not_ passed in by
# the user, set the prefix to an environment-specific default. For
# such environments its does [define prefix ...] and [proj-opt-set
# prefix ...], but it does not process vars derived from the prefix,
# e.g. exec-prefix. To do so it is generally necessary to also call
# proj-remap-autoconf-dir-vars late in the config process (immediately
# before ".in" files are filtered).
#
# Returns 1 if it modifies the environment, else 0.
proc proj-tweak-default-env-dirs {} {
switch -glob -- [get-define host] {
*-haiku {
set hpre /boot/home/config/non-packaged
if {![proj-opt-was-provided prefix]} {
proj-opt-set prefix $hpre
define prefix $hpre
return 1
}
}
}
return 0
}
########################################################################
# @proj-dot-ins-append file ?fileOut ?postProcessScript??
#
# Queues up an autosetup [make-template]-style file to be processed
# at a later time using [proj-dot-ins-process].
#
# $file is the input file. If $fileOut is empty then this function
# derives $fileOut from $file, stripping both its directory and
# extension parts. i.e. it defaults to writing the output to the
# current directory (typically $::autosetup(builddir)).
#
# If $postProcessScript is not empty then, during
# [proj-dot-ins-process], it will be eval'd immediately after
# processing the file. In the context of that script, the vars
# $fileIn and $fileOut will be set to the input and output file
# names. This can be used, for example, to make the output file
# executable or perform validation on its.
#
# See [proj-dot-ins-process], [proj-dot-ins-list]
proc proj-dot-ins-append {fileIn args} {
set srcdir $::autosetup(srcdir)
switch -exact -- [llength $args] {
0 {
lappend fileIn [file rootname [file tail $fileIn]] ""
}
1 {
lappend fileIn [join $args] ""
}
2 {
lappend fileIn {*}$args
}
default {
proj-fatal "Too many arguments: $fileIn $args"
}
}
#puts "******* [proj-current-scope]: adding $fileIn"
lappend ::proj_(dot-in-files) $fileIn
}
########################################################################
# @proj-dot-ins-list
#
# Returns the current list of [proj-dot-ins-append]'d files, noting
# that each entry is a 3-element list of (inputFileName,
# outputFileName, postProcessScript).
proc proj-dot-ins-list {} {
return $::proj_(dot-in-files)
}
########################################################################
# @proj-dot-ins-process ?-touch?
#
# Each file which has previously been passed to [proj-dot-ins-append]
# is processed, with its passing its in-file out-file names to
# [proj-make-from-dot-in].
#
# The optional argument may be the -touch flag, which is passed on to
# that [proj-make-from-dot-in].
#
# The intent is that a project accumulate any number of files to
# filter and delay their actual filtering until the last stage of the
# configure script, calling this function at that time.
proc proj-dot-ins-process {args} {
set flags ""
if {"-touch" eq $args} {
set flags "-touch"
}
foreach f $::proj_(dot-in-files) {
proj-assert {3==[llength $f]}
lassign $f fIn fOut fScript
#puts "DOING $fIn ==> $fOut"
proj-make-from-dot-in {*}$flags $fIn $fOut
if {"" ne $fScript} {
uplevel 1 "set fileIn $fIn; set fileOut $fOut; eval {$fScript}"
}
}
}
########################################################################
# @proj-validate-no-unresolved-ats filenames...
#
# For each filename given to it, it validates that the file has no
# unresolved @VAR@ references. If it finds any, it produces an error
# with location information.
#
# Exception: if a filename matches the pattern {*[Mm]ake*} AND a given
# line begins with a # (not including leading whitespace) then that
# line is ignored for purposes of this validation. The intent is that
# @VAR@ inside of makefile comments should not (necessarily) cause
# validation to fail, as it's sometimes convenient to comment out
# sections during development of a configure script and its
# corresponding makefile(s).
proc proj-validate-no-unresolved-ats {args} {
foreach f $args {
set lnno 1
set isMake [string match {*[Mm]ake*} $f]
foreach line [proj-file-content-list $f] {
if {!$isMake || ![string match "#*" [string trimleft $line]]} {
if {[regexp {(@[A-Za-z0-9_]+@)} $line match]} {
error "Unresolved reference to $match at line $lnno of $f"
}
}
incr lnno
}
}
}
########################################################################
# @proj-first-found fileList tgtVar
#
# Searches $fileList for an existing file. If one is found, its name is
# assigned to tgtVar and 1 is returned, else tgtVar is not modified
# and 0 is returned.
proc proj-first-file-found {fileList tgtVar} {
upvar $tgtVar tgt
foreach f $fileList {
if {[file exists $f]} {
set tgt $f
return 1
}
}
return 0
}
########################################################################
# Defines $defName to contain makefile recipe commands for re-running
# the configure script with its current set of $::argv flags. This
# can be used to automatically reconfigure.
proc proj-setup-autoreconfig {defName} {
set 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 $defName cd [apply $squote $::autosetup(builddir)] \
&& [apply $squote $::autosetup(srcdir)/configure]
#{*}$::autosetup(argv) breaks with --flag='val with spaces', so...
foreach arg $::autosetup(argv) {
define-append $defName [apply $squote $arg]
}
}
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -567,7 +567,7 @@ proc sqlitecon::Cut w {
}
}
# Do a paste operation.
# Do a paste opeation.
#
proc sqlitecon::Paste w {
if {[sqlitecon::canCut $w]==1} {
+1 -1
View File
@@ -281,7 +281,7 @@ happen if and when they are actually needed.
A valid JSONB BLOB consists of a single JSON element. The element must
exactly fill the BLOB. This one element is often a JSON object or array
and those usually contain additional elements as its payload, but the
element can be a primitive value such a string, number, boolean, or null.
element can be a primite value such a string, number, boolean, or null.
When the built-in JSON functions are attempting to determine if a BLOB
argument is a JSONB or just a random BLOB, they look at the header of
+2 -2
View File
@@ -846,7 +846,7 @@ or more tokens. The alternative meaning is tried if the original token
would have generated a syntax error.</p>
<p>The <tt>%fallback</tt> directive was added to support robust parsing of SQL
syntax in <a href='https://sqlite.org/'>SQLite</a>.
syntax in <a href='https://www.sqlite.org/'>SQLite</a>.
The SQL language contains a large assortment of keywords, each of which
appears as a different token to the language parser. SQL contains so
many keywords that it can be difficult for programmers to keep up with
@@ -881,7 +881,7 @@ is allowed between the "%" and the directive name.</p>
<p>Grammar text in between "<tt>%ifdef MACRO</tt>" and the next nested
"<tt>%endif</tt>" is
ignored unless the "-DMACRO" command-line option is used. Grammar text
between "<tt>%ifndef MACRO</tt>" and the next nested "<tt>%endif</tt>" is
betwen "<tt>%ifndef MACRO</tt>" and the next nested "<tt>%endif</tt>" is
included except when the "-DMACRO" command-line option is used.<p>
<p>The text in between "<tt>%if</tt> <i>CONDITIONAL</i>" and its
+1 -1
View File
@@ -45,7 +45,7 @@
*** Definition: Two databases (or the same database at two points it time)
are said to be "logically equivalent" if they give the same answer to
all queries. Note in particular the content of freelist leaf
pages can be changed arbitrarily without effecting the logical equivalence
pages can be changed arbitarily without effecting the logical equivalence
of the database.
(7) At any time, if any subset, including the empty set and the total set,
+2 -2
View File
@@ -1,6 +1,6 @@
The 5 states of an historical rollback lock as implemented by the
xLock, xUnlock, and xCheckReservedLock methods of the sqlite3_io_methods
object are:
objec are:
UNLOCKED
SHARED
@@ -58,7 +58,7 @@ The meanings of the various wal-index locking states is as follows:
A particular lock manager implementation may coalesce one or more of
the wal-index locking states, though with a reduction in concurrency.
For example, an implementation might implement only exclusive locking,
For example, an implemention might implement only exclusive locking,
in which case all states would be equivalent to CHECKPOINT, meaning that
only one reader or one writer or one checkpointer could be active at a
time. Or, an implementation might combine READ and READ_FULL into
+1 -1
View File
@@ -12,7 +12,7 @@ facilitates transfer of OS priority between processes when a high priority
process is blocked by a lower priority one.
Only read/write clients use blocking locks. Clients that have read-only access
to the \*-shm file never use blocking locks.
to the \*-shm file nevery use blocking locks.
Threads or processes that access a single database at a time never deadlock as
a result of blocking database locks. But it is of course possible for threads
+1 -1
View File
@@ -1,6 +1,6 @@
## Loadable Extensions
Various [loadable extensions](https://sqlite.org/loadext.html) for
Various [loadable extensions](https://www.sqlite.org/loadext.html) for
SQLite are found in subfolders.
Most subfolders are dedicated to a single loadable extension (for
+1 -1
View File
@@ -2052,7 +2052,7 @@ sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){
sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void*)pNew);
}
/* If an error has occurred, free the new object and return NULL. Otherwise,
/* If an error has occurred, free the new object and reutrn NULL. Otherwise,
** return the new sqlite3expert handle. */
if( rc!=SQLITE_OK ){
sqlite3_expert_destroy(pNew);
+1 -1
View File
@@ -28,7 +28,7 @@
static int dbHandleFromObj(Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3 **pDb){
Tcl_CmdInfo info;
if( 0==Tcl_GetCommandInfo(interp, Tcl_GetString(pObj), &info) ){
Tcl_AppendResult(interp, "no such handle: ", Tcl_GetString(pObj), NULL);
Tcl_AppendResult(interp, "no such handle: ", Tcl_GetString(pObj), 0);
return TCL_ERROR;
}
+5 -5
View File
@@ -62,20 +62,20 @@
matches rows that contain both the "engineering" and "consultancy" tokens
in the same column with not more than 10 other words between them. It does
not matter which of the two terms occurs first in the document, only that
they be separated by only 10 tokens or less. The user may also specify
they be seperated by only 10 tokens or less. The user may also specify
a different required proximity by adding "/N" immediately after the NEAR
operator, where N is an integer. For example:
<col> MATCH 'engineering NEAR/5 consultancy'
searches for a row containing an instance of each specified token separated
searches for a row containing an instance of each specified token seperated
by not more than 5 other tokens. More than one NEAR operator can be used
in as sequence. For example this query:
<col> MATCH 'reliable NEAR/2 engineering NEAR/5 consultancy'
searches for a row that contains an instance of the token "reliable"
separated by not more than two tokens from an instance of "engineering",
seperated by not more than two tokens from an instance of "engineering",
which is in turn separated by not more than 5 other tokens from an
instance of the term "consultancy". Phrases enclosed in quotes may
also be used as arguments to the NEAR operator.
@@ -146,7 +146,7 @@
<col> MATCH '(hello world) OR (simple example)'
matches documents that contain both "hello" and "world", and documents
that contain both "simple" and "example". It is not possible to formulate
that contain both "simple" and "example". It is not possible to forumlate
such a query using the standard syntax.
2) Instead of separating tokens and phrases by whitespace, an AND operator
@@ -174,7 +174,7 @@
4) Unlike in the standard syntax, where the OR operator has a higher
precedence than the implicit AND operator, when using the enhanced
syntax implicit and explicit AND operators have a higher precedence
syntax implicit and explict AND operators have a higher precedence
than OR operators. Using the enhanced syntax, the following two
queries are equivalent:
+11 -5
View File
@@ -87,7 +87,7 @@
** Here, array { X } means zero or more occurrences of X, adjacent in
** memory. A "position" is an index of a token in the token stream
** generated by the tokenizer. Note that POS_END and POS_COLUMN occur
** in the same logical place as the position element, and act as sentinels
** in the same logical place as the position element, and act as sentinals
** ending a position list array. POS_END is 0. POS_COLUMN is 1.
** The positions numbers are not stored literally but rather as two more
** than the difference from the prior position, or the just the position plus
@@ -295,6 +295,12 @@
# define SQLITE_CORE 1
#endif
#include <assert.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "fts3.h"
#ifndef SQLITE_CORE
@@ -2633,7 +2639,7 @@ static int fts3DoclistOrMerge(
** sizes of the two inputs, plus enough space for exactly one of the input
** docids to grow.
**
** A symmetric argument may be made if the doclists are in descending
** A symetric argument may be made if the doclists are in descending
** order.
*/
aOut = sqlite3_malloc64((i64)n1+n2+FTS3_VARINT_MAX-1+FTS3_BUFFER_PADDING);
@@ -4432,7 +4438,7 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
nDistance = iPrev - nMaxUndeferred;
}
aOut = (char *)sqlite3Fts3MallocZero(((i64)nPoslist)+FTS3_BUFFER_PADDING);
aOut = (char *)sqlite3Fts3MallocZero(nPoslist+FTS3_BUFFER_PADDING);
if( !aOut ){
sqlite3_free(aPoslist);
return SQLITE_NOMEM;
@@ -4731,7 +4737,7 @@ static int incrPhraseTokenNext(
**
** * does not contain any deferred tokens.
**
** Advance it to the next matching document in the database and populate
** Advance it to the next matching documnent in the database and populate
** the Fts3Doclist.pList and nList fields.
**
** If there is no "next" entry and no error occurs, then *pbEof is set to
@@ -5738,7 +5744,7 @@ static int fts3EvalNext(Fts3Cursor *pCsr){
}
/*
** Restart iteration for expression pExpr so that the next call to
** Restart interation for expression pExpr so that the next call to
** fts3EvalNext() visits the first row. Do not allow incremental
** loading or merging of phrase doclists for this iteration.
**
+3 -27
View File
@@ -14,13 +14,6 @@
#ifndef _FTSINT_H
#define _FTSINT_H
#include <assert.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
# define NDEBUG 1
#endif
@@ -209,19 +202,6 @@ typedef sqlite3_int64 i64; /* 8-byte signed integer */
#define deliberate_fall_through
/*
** Macros needed to provide flexible arrays in a portable way
*/
#ifndef offsetof
# define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD))
#endif
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
# define FLEXARRAY
#else
# define FLEXARRAY 1
#endif
#endif /* SQLITE_AMALGAMATION */
#ifdef SQLITE_DEBUG
@@ -326,7 +306,7 @@ struct Fts3Table {
#endif
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
/* True to disable the incremental doclist optimization. This is controlled
/* True to disable the incremental doclist optimization. This is controled
** by special insert command 'test-no-incr-doclist'. */
int bNoIncrDoclist;
@@ -378,7 +358,7 @@ struct Fts3Cursor {
/*
** The Fts3Cursor.eSearch member is always set to one of the following.
** Actually, Fts3Cursor.eSearch can be greater than or equal to
** Actualy, Fts3Cursor.eSearch can be greater than or equal to
** FTS3_FULLTEXT_SEARCH. If so, then Fts3Cursor.eSearch - 2 is the index
** of the column to be searched. For example, in
**
@@ -451,13 +431,9 @@ struct Fts3Phrase {
*/
int nToken; /* Number of tokens in the phrase */
int iColumn; /* Index of column this phrase must match */
Fts3PhraseToken aToken[FLEXARRAY]; /* One for each token in the phrase */
Fts3PhraseToken aToken[1]; /* One entry for each token in the phrase */
};
/* Size (in bytes) of an Fts3Phrase object large enough to hold N tokens */
#define SZ_FTS3PHRASE(N) \
(offsetof(Fts3Phrase,aToken)+(N)*sizeof(Fts3PhraseToken))
/*
** A tree of these objects forms the RHS of a MATCH operator.
**
+16 -40
View File
@@ -161,23 +161,6 @@ int sqlite3Fts3OpenTokenizer(
*/
static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *);
/*
** Search buffer z[], size n, for a '"' character. Or, if enable_parenthesis
** is defined, search for '(' and ')' as well. Return the index of the first
** such character in the buffer. If there is no such character, return -1.
*/
static int findBarredChar(const char *z, int n){
int ii;
for(ii=0; ii<n; ii++){
if( (z[ii]=='"')
|| (sqlite3_fts3_enable_parentheses && (z[ii]=='(' || z[ii]==')'))
){
return ii;
}
}
return -1;
}
/*
** Extract the next token from buffer z (length n) using the tokenizer
** and other information (column names etc.) in pParse. Create an Fts3Expr
@@ -202,9 +185,16 @@ static int getNextToken(
int rc;
sqlite3_tokenizer_cursor *pCursor;
Fts3Expr *pRet = 0;
int i = 0;
*pnConsumed = n;
rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, n, &pCursor);
/* Set variable i to the maximum number of bytes of input to tokenize. */
for(i=0; i<n; i++){
if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break;
if( z[i]=='"' ) break;
}
*pnConsumed = i;
rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor);
if( rc==SQLITE_OK ){
const char *zToken;
int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0;
@@ -212,18 +202,7 @@ static int getNextToken(
rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
if( rc==SQLITE_OK ){
/* Check that this tokenization did not gobble up any " characters. Or,
** if enable_parenthesis is true, that it did not gobble up any
** open or close parenthesis characters either. If it did, call
** getNextToken() again, but pass only that part of the input buffer
** up to the first such character. */
int iBarred = findBarredChar(z, iEnd);
if( iBarred>=0 ){
pModule->xClose(pCursor);
return getNextToken(pParse, iCol, z, iBarred, ppExpr, pnConsumed);
}
nByte = sizeof(Fts3Expr) + SZ_FTS3PHRASE(1) + nToken;
nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken;
pRet = (Fts3Expr *)sqlite3Fts3MallocZero(nByte);
if( !pRet ){
rc = SQLITE_NOMEM;
@@ -233,7 +212,7 @@ static int getNextToken(
pRet->pPhrase->nToken = 1;
pRet->pPhrase->iColumn = iCol;
pRet->pPhrase->aToken[0].n = nToken;
pRet->pPhrase->aToken[0].z = (char*)&pRet->pPhrase->aToken[1];
pRet->pPhrase->aToken[0].z = (char *)&pRet->pPhrase[1];
memcpy(pRet->pPhrase->aToken[0].z, zToken, nToken);
if( iEnd<n && z[iEnd]=='*' ){
@@ -257,11 +236,7 @@ static int getNextToken(
}
*pnConsumed = iEnd;
}else if( n && rc==SQLITE_DONE ){
int iBarred = findBarredChar(z, n);
if( iBarred>=0 ){
*pnConsumed = iBarred;
}
}else if( i && rc==SQLITE_DONE ){
rc = SQLITE_OK;
}
@@ -308,9 +283,9 @@ static int getNextString(
Fts3Expr *p = 0;
sqlite3_tokenizer_cursor *pCursor = 0;
char *zTemp = 0;
i64 nTemp = 0;
int nTemp = 0;
const int nSpace = sizeof(Fts3Expr) + SZ_FTS3PHRASE(1);
const int nSpace = sizeof(Fts3Expr) + sizeof(Fts3Phrase);
int nToken = 0;
/* The final Fts3Expr data structure, including the Fts3Phrase,
@@ -682,7 +657,7 @@ static int fts3ExprParse(
/* The isRequirePhrase variable is set to true if a phrase or
** an expression contained in parenthesis is required. If a
** binary operator (AND, OR, NOT or NEAR) is encountered when
** binary operator (AND, OR, NOT or NEAR) is encounted when
** isRequirePhrase is set, this is a syntax error.
*/
if( !isPhrase && isRequirePhrase ){
@@ -1264,6 +1239,7 @@ static void fts3ExprTestCommon(
}
if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
sqlite3Fts3ExprFree(pExpr);
sqlite3_result_error(context, "Error parsing expression", -1);
}else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){
sqlite3_result_error_nomem(context);
+1 -1
View File
@@ -187,7 +187,7 @@ static void fts3HashInsertElement(
}
/* Resize the hash table so that it contains "new_size" buckets.
/* Resize the hash table so that it cantains "new_size" buckets.
** "new_size" must be a power of 2. The hash table might fail
** to resize if sqliteMalloc() fails.
**
+1 -1
View File
@@ -256,7 +256,7 @@ static int star_oh(const char *z){
/*
** If the word ends with zFrom and xCond() is true for the stem
** of the word that precedes the zFrom ending, then change the
** of the word that preceeds the zFrom ending, then change the
** ending to zTo.
**
** The input word *pz and zFrom are both in reverse order. zTo
+12 -16
View File
@@ -108,13 +108,9 @@ struct MatchinfoBuffer {
int nElem;
int bGlobal; /* Set if global data is loaded */
char *zMatchinfo;
u32 aMI[FLEXARRAY];
u32 aMatchinfo[1];
};
/* Size (in bytes) of a MatchinfoBuffer sufficient for N elements */
#define SZ_MATCHINFOBUFFER(N) \
(offsetof(MatchinfoBuffer,aMI)+(((N)+1)/2)*sizeof(u64))
/*
** The snippet() and offsets() functions both return text values. An instance
@@ -139,13 +135,13 @@ struct StrBuffer {
static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){
MatchinfoBuffer *pRet;
sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1)
+ SZ_MATCHINFOBUFFER(1);
+ sizeof(MatchinfoBuffer);
sqlite3_int64 nStr = strlen(zMatchinfo);
pRet = sqlite3Fts3MallocZero(nByte + nStr+1);
if( pRet ){
pRet->aMI[0] = (u8*)(&pRet->aMI[1]) - (u8*)pRet;
pRet->aMI[1+nElem] = pRet->aMI[0]
pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0]
+ sizeof(u32)*((int)nElem+1);
pRet->nElem = (int)nElem;
pRet->zMatchinfo = ((char*)pRet) + nByte;
@@ -159,10 +155,10 @@ static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){
static void fts3MIBufferFree(void *p){
MatchinfoBuffer *pBuf = (MatchinfoBuffer*)((u8*)p - ((u32*)p)[-1]);
assert( (u32*)p==&pBuf->aMI[1]
|| (u32*)p==&pBuf->aMI[pBuf->nElem+2]
assert( (u32*)p==&pBuf->aMatchinfo[1]
|| (u32*)p==&pBuf->aMatchinfo[pBuf->nElem+2]
);
if( (u32*)p==&pBuf->aMI[1] ){
if( (u32*)p==&pBuf->aMatchinfo[1] ){
pBuf->aRef[1] = 0;
}else{
pBuf->aRef[2] = 0;
@@ -179,18 +175,18 @@ static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){
if( p->aRef[1]==0 ){
p->aRef[1] = 1;
aOut = &p->aMI[1];
aOut = &p->aMatchinfo[1];
xRet = fts3MIBufferFree;
}
else if( p->aRef[2]==0 ){
p->aRef[2] = 1;
aOut = &p->aMI[p->nElem+2];
aOut = &p->aMatchinfo[p->nElem+2];
xRet = fts3MIBufferFree;
}else{
aOut = (u32*)sqlite3_malloc64(p->nElem * sizeof(u32));
if( aOut ){
xRet = sqlite3_free;
if( p->bGlobal ) memcpy(aOut, &p->aMI[1], p->nElem*sizeof(u32));
if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32));
}
}
@@ -200,7 +196,7 @@ static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){
static void fts3MIBufferSetGlobal(MatchinfoBuffer *p){
p->bGlobal = 1;
memcpy(&p->aMI[2+p->nElem], &p->aMI[1], p->nElem*sizeof(u32));
memcpy(&p->aMatchinfo[2+p->nElem], &p->aMatchinfo[1], p->nElem*sizeof(u32));
}
/*
@@ -615,7 +611,7 @@ static int fts3StringAppend(
}
/* If there is insufficient space allocated at StrBuffer.z, use realloc()
** to grow the buffer until so that it is big enough to accommodate the
** to grow the buffer until so that it is big enough to accomadate the
** appended data.
*/
if( pStr->n+nAppend+1>=pStr->nAlloc ){
+3 -3
View File
@@ -219,7 +219,7 @@ static int SQLITE_TCLAPI fts3_near_match_cmd(
rc = Tcl_ListObjGetElements(interp, pPhrase, &nToken, &apToken);
if( rc!=TCL_OK ) goto near_match_out;
if( nToken>NM_MAX_TOKEN ){
Tcl_AppendResult(interp, "Too many tokens in phrase", NULL);
Tcl_AppendResult(interp, "Too many tokens in phrase", 0);
rc = TCL_ERROR;
goto near_match_out;
}
@@ -547,7 +547,7 @@ static int SQLITE_TCLAPI fts3_test_varint_cmd(
if( w!=w2 || nByte!=nByte2 ){
char *zErr = sqlite3_mprintf("error testing %lld", w);
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, zErr, NULL);
Tcl_AppendResult(interp, zErr, 0);
return TCL_ERROR;
}
@@ -557,7 +557,7 @@ static int SQLITE_TCLAPI fts3_test_varint_cmd(
if( (int)w!=i || nByte!=nByte2 ){
char *zErr = sqlite3_mprintf("error testing %lld (32-bit)", w);
Tcl_ResetResult(interp);
Tcl_AppendResult(interp, zErr, NULL);
Tcl_AppendResult(interp, zErr, 0);
return TCL_ERROR;
}
}
+1 -1
View File
@@ -346,7 +346,7 @@ static int fts3tokFilterMethod(
fts3tokResetCursor(pCsr);
if( idxNum==1 ){
const char *zByte = (const char *)sqlite3_value_text(apVal[0]);
sqlite3_int64 nByte = sqlite3_value_bytes(apVal[0]);
int nByte = sqlite3_value_bytes(apVal[0]);
pCsr->zInput = sqlite3_malloc64(nByte+1);
if( pCsr->zInput==0 ){
rc = SQLITE_NOMEM;
+2 -2
View File
@@ -3956,7 +3956,7 @@ static int fts3IncrmergePush(
**
** It is assumed that the buffer associated with pNode is already large
** enough to accommodate the new entry. The buffer associated with pPrev
** is extended by this function if required.
** is extended by this function if requrired.
**
** If an error (i.e. OOM condition) occurs, an SQLite error code is
** returned. Otherwise, SQLITE_OK.
@@ -5619,7 +5619,7 @@ int sqlite3Fts3DeferToken(
/*
** SQLite value pRowid contains the rowid of a row that may or may not be
** present in the FTS3 table. If it is, delete it and adjust the contents
** of subsidiary data structures accordingly.
** of subsiduary data structures accordingly.
*/
static int fts3DeleteByRowid(
Fts3Table *p,
+1 -1
View File
@@ -893,7 +893,7 @@ proc print_test_main {} {
puts "\}"
}
# Process the command line arguments. Exit early if they are not to
# Proces the command line arguments. Exit early if they are not to
# our liking.
#
proc usage {} {
+2 -15
View File
@@ -75,18 +75,6 @@ typedef sqlite3_uint64 u64;
# define EIGHT_BYTE_ALIGNMENT(X) ((((uptr)(X) - (uptr)0)&7)==0)
#endif
/*
** Macros needed to provide flexible arrays in a portable way
*/
#ifndef offsetof
# define offsetof(STRUCTURE,FIELD) ((size_t)((char*)&((STRUCTURE*)0)->FIELD))
#endif
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
# define FLEXARRAY
#else
# define FLEXARRAY 1
#endif
#endif
/* Truncate very long tokens to this many bytes. Hard limit is
@@ -159,11 +147,10 @@ typedef struct Fts5Colset Fts5Colset;
*/
struct Fts5Colset {
int nCol;
int aiCol[FLEXARRAY];
int aiCol[1];
};
/* Size (int bytes) of a complete Fts5Colset object with N columns. */
#define SZ_FTS5COLSET(N) (sizeof(i64)*((N+2)/2))
/**************************************************************************
** Interface to code in fts5_config.c. fts5_config.c contains contains code
+1 -1
View File
@@ -667,7 +667,7 @@ static int fts5Bm25GetData(
** under consideration.
**
** The problem with this is that if (N < 2*nHit), the IDF is
** negative. Which is undesirable. So the minimum allowable IDF is
** negative. Which is undesirable. So the mimimum allowable IDF is
** (1e-6) - roughly the same as a term that appears in just over
** half of set of 5,000,000 documents. */
double idf = log( (nRow - nHit + 0.5) / (nHit + 0.5) );
+1 -1
View File
@@ -308,7 +308,7 @@ char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){
** * The 52 upper and lower case ASCII characters, and
** * The 10 integer ASCII characters.
** * The underscore character "_" (0x5F).
** * The unicode "substitute" character (0x1A).
** * The unicode "subsitute" character (0x1A).
*/
int sqlite3Fts5IsBareword(char t){
u8 aBareword[128] = {
+23 -34
View File
@@ -86,13 +86,9 @@ struct Fts5ExprNode {
/* Child nodes. For a NOT node, this array always contains 2 entries. For
** AND or OR nodes, it contains 2 or more entries. */
int nChild; /* Number of child nodes */
Fts5ExprNode *apChild[FLEXARRAY]; /* Array of child nodes */
Fts5ExprNode *apChild[1]; /* Array of child nodes */
};
/* Size (in bytes) of an Fts5ExprNode object that holds up to N children */
#define SZ_FTS5EXPRNODE(N) \
(offsetof(Fts5ExprNode,apChild) + (N)*sizeof(Fts5ExprNode*))
#define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING)
/*
@@ -123,13 +119,9 @@ struct Fts5ExprPhrase {
Fts5ExprNode *pNode; /* FTS5_STRING node this phrase is part of */
Fts5Buffer poslist; /* Current position list */
int nTerm; /* Number of entries in aTerm[] */
Fts5ExprTerm aTerm[FLEXARRAY]; /* Terms that make up this phrase */
Fts5ExprTerm aTerm[1]; /* Terms that make up this phrase */
};
/* Size (in bytes) of an Fts5ExprPhrase object that holds up to N terms */
#define SZ_FTS5EXPRPHRASE(N) \
(offsetof(Fts5ExprPhrase,aTerm) + (N)*sizeof(Fts5ExprTerm))
/*
** One or more phrases that must appear within a certain token distance of
** each other within each matching document.
@@ -138,12 +130,9 @@ struct Fts5ExprNearset {
int nNear; /* NEAR parameter */
Fts5Colset *pColset; /* Columns to search (NULL -> all columns) */
int nPhrase; /* Number of entries in aPhrase[] array */
Fts5ExprPhrase *apPhrase[FLEXARRAY]; /* Array of phrase pointers */
Fts5ExprPhrase *apPhrase[1]; /* Array of phrase pointers */
};
/* Size (in bytes) of an Fts5ExprNearset object covering up to N phrases */
#define SZ_FTS5EXPRNEARSET(N) \
(offsetof(Fts5ExprNearset,apPhrase)+(N)*sizeof(Fts5ExprPhrase*))
/*
** Parse context.
@@ -303,7 +292,7 @@ int sqlite3Fts5ExprNew(
/* If the LHS of the MATCH expression was a user column, apply the
** implicit column-filter. */
if( sParse.rc==SQLITE_OK && iCol<pConfig->nCol ){
int n = SZ_FTS5COLSET(1);
int n = sizeof(Fts5Colset);
Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n);
if( pColset ){
pColset->nCol = 1;
@@ -1661,7 +1650,7 @@ Fts5ExprNearset *sqlite3Fts5ParseNearset(
if( pParse->rc==SQLITE_OK ){
if( pNear==0 ){
sqlite3_int64 nByte;
nByte = SZ_FTS5EXPRNEARSET(SZALLOC+1);
nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*);
pRet = sqlite3_malloc64(nByte);
if( pRet==0 ){
pParse->rc = SQLITE_NOMEM;
@@ -1672,7 +1661,7 @@ Fts5ExprNearset *sqlite3Fts5ParseNearset(
int nNew = pNear->nPhrase + SZALLOC;
sqlite3_int64 nByte;
nByte = SZ_FTS5EXPRNEARSET(nNew+1);
nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*);
pRet = (Fts5ExprNearset*)sqlite3_realloc64(pNear, nByte);
if( pRet==0 ){
pParse->rc = SQLITE_NOMEM;
@@ -1763,12 +1752,12 @@ static int fts5ParseTokenize(
int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0);
pNew = (Fts5ExprPhrase*)sqlite3_realloc64(pPhrase,
SZ_FTS5EXPRPHRASE(nNew+1)
sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew
);
if( pNew==0 ){
rc = SQLITE_NOMEM;
}else{
if( pPhrase==0 ) memset(pNew, 0, SZ_FTS5EXPRPHRASE(1));
if( pPhrase==0 ) memset(pNew, 0, sizeof(Fts5ExprPhrase));
pCtx->pPhrase = pPhrase = pNew;
pNew->nTerm = nNew - SZALLOC;
}
@@ -1876,7 +1865,7 @@ Fts5ExprPhrase *sqlite3Fts5ParseTerm(
if( sCtx.pPhrase==0 ){
/* This happens when parsing a token or quoted phrase that contains
** no token characters at all. (e.g ... MATCH '""'). */
sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, SZ_FTS5EXPRPHRASE(1));
sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase));
}else if( sCtx.pPhrase->nTerm ){
sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix;
}
@@ -1911,18 +1900,19 @@ int sqlite3Fts5ExprClonePhrase(
sizeof(Fts5ExprPhrase*));
}
if( rc==SQLITE_OK ){
pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc, SZ_FTS5EXPRNODE(1));
pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc,
sizeof(Fts5ExprNode));
}
if( rc==SQLITE_OK ){
pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc,
SZ_FTS5EXPRNEARSET(2));
pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc,
sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*));
}
if( rc==SQLITE_OK && ALWAYS(pOrig!=0) ){
Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset;
if( pColsetOrig ){
sqlite3_int64 nByte;
Fts5Colset *pColset;
nByte = SZ_FTS5COLSET(pColsetOrig->nCol);
nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int);
pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte);
if( pColset ){
memcpy(pColset, pColsetOrig, (size_t)nByte);
@@ -1950,7 +1940,7 @@ int sqlite3Fts5ExprClonePhrase(
}else{
/* This happens when parsing a token or quoted phrase that contains
** no token characters at all. (e.g ... MATCH '""'). */
sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, SZ_FTS5EXPRPHRASE(1));
sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
}
}
@@ -2015,8 +2005,7 @@ void sqlite3Fts5ParseSetDistance(
);
return;
}
if( nNear<214748363 ) nNear = nNear * 10 + (p->p[i] - '0');
/* ^^^^^^^^^^^^^^^--- Prevent integer overflow */
nNear = nNear * 10 + (p->p[i] - '0');
}
}else{
nNear = FTS5_DEFAULT_NEARDIST;
@@ -2045,7 +2034,7 @@ static Fts5Colset *fts5ParseColset(
assert( pParse->rc==SQLITE_OK );
assert( iCol>=0 && iCol<pParse->pConfig->nCol );
pNew = sqlite3_realloc64(p, SZ_FTS5COLSET(nCol+1));
pNew = sqlite3_realloc64(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
if( pNew==0 ){
pParse->rc = SQLITE_NOMEM;
}else{
@@ -2080,7 +2069,7 @@ Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset *p){
int nCol = pParse->pConfig->nCol;
pRet = (Fts5Colset*)sqlite3Fts5MallocZero(&pParse->rc,
SZ_FTS5COLSET(nCol+1)
sizeof(Fts5Colset) + sizeof(int)*nCol
);
if( pRet ){
int i;
@@ -2141,7 +2130,7 @@ Fts5Colset *sqlite3Fts5ParseColset(
static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){
Fts5Colset *pRet;
if( pOrig ){
sqlite3_int64 nByte = SZ_FTS5COLSET(pOrig->nCol);
sqlite3_int64 nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int);
pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte);
if( pRet ){
memcpy(pRet, pOrig, (size_t)nByte);
@@ -2309,7 +2298,7 @@ static Fts5ExprNode *fts5ParsePhraseToAnd(
assert( pNear->nPhrase==1 );
assert( pParse->bPhraseToAnd );
nByte = SZ_FTS5EXPRNODE(nTerm+1);
nByte = sizeof(Fts5ExprNode) + nTerm*sizeof(Fts5ExprNode*);
pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
if( pRet ){
pRet->eType = FTS5_AND;
@@ -2319,7 +2308,7 @@ static Fts5ExprNode *fts5ParsePhraseToAnd(
pParse->nPhrase--;
for(ii=0; ii<nTerm; ii++){
Fts5ExprPhrase *pPhrase = (Fts5ExprPhrase*)sqlite3Fts5MallocZero(
&pParse->rc, SZ_FTS5EXPRPHRASE(1)
&pParse->rc, sizeof(Fts5ExprPhrase)
);
if( pPhrase ){
if( parseGrowPhraseArray(pParse) ){
@@ -2388,7 +2377,7 @@ Fts5ExprNode *sqlite3Fts5ParseNode(
if( pRight->eType==eType ) nChild += pRight->nChild-1;
}
nByte = SZ_FTS5EXPRNODE(nChild);
nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1);
pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
if( pRet ){
@@ -3263,7 +3252,7 @@ int sqlite3Fts5ExprInstToken(
}
/*
** Clear the token mappings for all Fts5IndexIter objects managed by
** Clear the token mappings for all Fts5IndexIter objects mannaged by
** the expression passed as the only argument.
*/
void sqlite3Fts5ExprClearTokens(Fts5Expr *pExpr){
+2 -2
View File
@@ -20,7 +20,7 @@ typedef struct Fts5HashEntry Fts5HashEntry;
/*
** This file contains the implementation of an in-memory hash table used
** to accumulate "term -> doclist" content before it is flushed to a level-0
** to accumuluate "term -> doclist" content before it is flused to a level-0
** segment.
*/
@@ -77,7 +77,7 @@ struct Fts5HashEntry {
};
/*
** Equivalent to:
** Eqivalent to:
**
** char *fts5EntryKey(Fts5HashEntry *pEntry){ return zKey; }
*/
+34 -52
View File
@@ -422,13 +422,9 @@ struct Fts5Structure {
u64 nOriginCntr; /* Origin value for next top-level segment */
int nSegment; /* Total segments in this structure */
int nLevel; /* Number of levels in this index */
Fts5StructureLevel aLevel[FLEXARRAY]; /* Array of nLevel level objects */
Fts5StructureLevel aLevel[1]; /* Array of nLevel level objects */
};
/* Size (in bytes) of an Fts5Structure object holding up to N levels */
#define SZ_FTS5STRUCTURE(N) \
(offsetof(Fts5Structure,aLevel) + (N)*sizeof(Fts5StructureLevel))
/*
** An object of type Fts5SegWriter is used to write to segments.
*/
@@ -558,15 +554,11 @@ struct Fts5SegIter {
** Array of tombstone pages. Reference counted.
*/
struct Fts5TombstoneArray {
int nRef; /* Number of pointers to this object */
int nRef; /* Number of pointers to this object */
int nTombstone;
Fts5Data *apTombstone[FLEXARRAY]; /* Array of tombstone pages */
Fts5Data *apTombstone[1]; /* Array of tombstone pages */
};
/* Size (in bytes) of an Fts5TombstoneArray holding up to N tombstones */
#define SZ_FTS5TOMBSTONEARRAY(N) \
(offsetof(Fts5TombstoneArray,apTombstone)+(N)*sizeof(Fts5Data*))
/*
** Argument is a pointer to an Fts5Data structure that contains a
** leaf page.
@@ -635,12 +627,9 @@ struct Fts5Iter {
i64 iSwitchRowid; /* Firstest rowid of other than aFirst[1] */
Fts5CResult *aFirst; /* Current merge state (see above) */
Fts5SegIter aSeg[FLEXARRAY]; /* Array of segment iterators */
Fts5SegIter aSeg[1]; /* Array of segment iterators */
};
/* Size (in bytes) of an Fts5Iter object holding up to N segment iterators */
#define SZ_FTS5ITER(N) (offsetof(Fts5Iter,aSeg)+(N)*sizeof(Fts5SegIter))
/*
** An instance of the following type is used to iterate through the contents
** of a doclist-index record.
@@ -667,13 +656,9 @@ struct Fts5DlidxLvl {
struct Fts5DlidxIter {
int nLvl;
int iSegid;
Fts5DlidxLvl aLvl[FLEXARRAY];
Fts5DlidxLvl aLvl[1];
};
/* Size (in bytes) of an Fts5DlidxIter object with up to N levels */
#define SZ_FTS5DLIDXITER(N) \
(offsetof(Fts5DlidxIter,aLvl)+(N)*sizeof(Fts5DlidxLvl))
static void fts5PutU16(u8 *aOut, u16 iVal){
aOut[0] = (iVal>>8);
aOut[1] = (iVal&0xFF);
@@ -1041,7 +1026,7 @@ int sqlite3Fts5StructureTest(Fts5Index *p, void *pStruct){
static void fts5StructureMakeWritable(int *pRc, Fts5Structure **pp){
Fts5Structure *p = *pp;
if( *pRc==SQLITE_OK && p->nRef>1 ){
i64 nByte = SZ_FTS5STRUCTURE(p->nLevel);
i64 nByte = sizeof(Fts5Structure)+(p->nLevel-1)*sizeof(Fts5StructureLevel);
Fts5Structure *pNew;
pNew = (Fts5Structure*)sqlite3Fts5MallocZero(pRc, nByte);
if( pNew ){
@@ -1115,7 +1100,10 @@ static int fts5StructureDecode(
){
return FTS5_CORRUPT;
}
nByte = SZ_FTS5STRUCTURE(nLevel);
nByte = (
sizeof(Fts5Structure) + /* Main structure */
sizeof(Fts5StructureLevel) * (nLevel-1) /* aLevel[] array */
);
pRet = (Fts5Structure*)sqlite3Fts5MallocZero(&rc, nByte);
if( pRet ){
@@ -1195,7 +1183,10 @@ static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){
if( *pRc==SQLITE_OK ){
Fts5Structure *pStruct = *ppStruct;
int nLevel = pStruct->nLevel;
sqlite3_int64 nByte = SZ_FTS5STRUCTURE(nLevel+2);
sqlite3_int64 nByte = (
sizeof(Fts5Structure) + /* Main structure */
sizeof(Fts5StructureLevel) * (nLevel+1) /* aLevel[] array */
);
pStruct = sqlite3_realloc64(pStruct, nByte);
if( pStruct ){
@@ -1734,7 +1725,7 @@ static Fts5DlidxIter *fts5DlidxIterInit(
int bDone = 0;
for(i=0; p->rc==SQLITE_OK && bDone==0; i++){
sqlite3_int64 nByte = SZ_FTS5DLIDXITER(i+1);
sqlite3_int64 nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl);
Fts5DlidxIter *pNew;
pNew = (Fts5DlidxIter*)sqlite3_realloc64(pIter, nByte);
@@ -1952,7 +1943,7 @@ static void fts5SegIterSetNext(Fts5Index *p, Fts5SegIter *pIter){
static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){
const int nTomb = pIter->pSeg->nPgTombstone;
if( nTomb>0 ){
int nByte = SZ_FTS5TOMBSTONEARRAY(nTomb+1);
int nByte = nTomb * sizeof(Fts5Data*) + sizeof(Fts5TombstoneArray);
Fts5TombstoneArray *pNew;
pNew = (Fts5TombstoneArray*)sqlite3Fts5MallocZero(&p->rc, nByte);
if( pNew ){
@@ -3413,7 +3404,8 @@ static Fts5Iter *fts5MultiIterAlloc(
for(nSlot=2; nSlot<nSeg; nSlot=nSlot*2);
pNew = fts5IdxMalloc(p,
SZ_FTS5ITER(nSlot) + /* pNew + pNew->aSeg[] */
sizeof(Fts5Iter) + /* pNew */
sizeof(Fts5SegIter) * (nSlot-1) + /* pNew->aSeg[] */
sizeof(Fts5CResult) * nSlot /* pNew->aFirst[] */
);
if( pNew ){
@@ -5214,7 +5206,7 @@ static void fts5DoSecureDelete(
int iDelKeyOff = 0; /* Offset of deleted key, if any */
nIdx = nPg-iPgIdx;
aIdx = sqlite3Fts5MallocZero(&p->rc, ((i64)nIdx)+16);
aIdx = sqlite3Fts5MallocZero(&p->rc, nIdx+16);
if( p->rc ) return;
memcpy(aIdx, &aPg[iPgIdx], nIdx);
@@ -5779,7 +5771,7 @@ static Fts5Structure *fts5IndexOptimizeStruct(
Fts5Structure *pStruct
){
Fts5Structure *pNew = 0;
sqlite3_int64 nByte = SZ_FTS5STRUCTURE(1);
sqlite3_int64 nByte = sizeof(Fts5Structure);
int nSeg = pStruct->nSegment;
int i;
@@ -5808,8 +5800,7 @@ static Fts5Structure *fts5IndexOptimizeStruct(
assert( pStruct->aLevel[i].nMerge<=nThis );
}
nByte += (((i64)pStruct->nLevel)+1) * sizeof(Fts5StructureLevel);
assert( nByte==SZ_FTS5STRUCTURE(pStruct->nLevel+2) );
nByte += (pStruct->nLevel+1) * sizeof(Fts5StructureLevel);
pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte);
if( pNew ){
@@ -6386,13 +6377,9 @@ struct Fts5TokenDataIter {
int nIterAlloc;
Fts5PoslistReader *aPoslistReader;
int *aPoslistToIter;
Fts5Iter *apIter[FLEXARRAY];
Fts5Iter *apIter[1];
};
/* Size in bytes of an Fts5TokenDataIter object holding up to N iterators */
#define SZ_FTS5TOKENDATAITER(N) \
(offsetof(Fts5TokenDataIter,apIter) + (N)*sizeof(Fts5Iter))
/*
** The two input arrays - a1[] and a2[] - are in sorted order. This function
** merges the two arrays together and writes the result to output array
@@ -6464,7 +6451,7 @@ static void fts5TokendataIterAppendMap(
/*
** Sort the contents of the pT->aMap[] array.
**
** The sorting algorithm requires a malloc(). If this fails, an error code
** The sorting algorithm requries a malloc(). If this fails, an error code
** is left in Fts5Index.rc before returning.
*/
static void fts5TokendataIterSortMap(Fts5Index *p, Fts5TokenDataIter *pT){
@@ -6655,7 +6642,7 @@ static void fts5SetupPrefixIter(
&& p->pConfig->bPrefixInsttoken
){
s.pTokendata = &s2;
s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, SZ_FTS5TOKENDATAITER(1));
s2.pT = (Fts5TokenDataIter*)fts5IdxMalloc(p, sizeof(*s2.pT));
}
if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
@@ -6701,8 +6688,7 @@ static void fts5SetupPrefixIter(
}
}
pData = fts5IdxMalloc(p, sizeof(*pData)
+ ((i64)s.doclist.n)+FTS5_DATA_ZERO_PADDING);
pData = fts5IdxMalloc(p, sizeof(*pData)+s.doclist.n+FTS5_DATA_ZERO_PADDING);
assert( pData!=0 || p->rc!=SQLITE_OK );
if( pData ){
pData->p = (u8*)&pData[1];
@@ -6783,17 +6769,15 @@ int sqlite3Fts5IndexRollback(Fts5Index *p){
** and the initial version of the "averages" record (a zero-byte blob).
*/
int sqlite3Fts5IndexReinit(Fts5Index *p){
Fts5Structure *pTmp;
u8 tmpSpace[SZ_FTS5STRUCTURE(1)];
Fts5Structure s;
fts5StructureInvalidate(p);
fts5IndexDiscardData(p);
pTmp = (Fts5Structure*)tmpSpace;
memset(pTmp, 0, SZ_FTS5STRUCTURE(1));
memset(&s, 0, sizeof(Fts5Structure));
if( p->pConfig->bContentlessDelete ){
pTmp->nOriginCntr = 1;
s.nOriginCntr = 1;
}
fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
fts5StructureWrite(p, pTmp);
fts5StructureWrite(p, &s);
return fts5IndexReturn(p);
}
@@ -7001,7 +6985,7 @@ static Fts5TokenDataIter *fts5AppendTokendataIter(
if( p->rc==SQLITE_OK ){
if( pIn==0 || pIn->nIter==pIn->nIterAlloc ){
int nAlloc = pIn ? pIn->nIterAlloc*2 : 16;
int nByte = SZ_FTS5TOKENDATAITER(nAlloc+1);
int nByte = nAlloc * sizeof(Fts5Iter*) + sizeof(Fts5TokenDataIter);
Fts5TokenDataIter *pNew = (Fts5TokenDataIter*)sqlite3_realloc(pIn, nByte);
if( pNew==0 ){
@@ -7517,8 +7501,7 @@ static int fts5SetupPrefixIterTokendata(
fts5BufferGrow(&p->rc, &token, nToken+1);
assert( token.p!=0 || p->rc!=SQLITE_OK );
ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc,
SZ_FTS5TOKENDATAITER(1));
ctx.pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*ctx.pT));
if( p->rc==SQLITE_OK ){
@@ -7649,8 +7632,7 @@ int sqlite3Fts5IndexIterWriteTokendata(
if( pIter->nSeg>0 ){
/* This is a prefix term iterator. */
if( pT==0 ){
pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc,
SZ_FTS5TOKENDATAITER(1));
pT = (Fts5TokenDataIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(*pT));
pIter->pTokenDataIter = pT;
}
if( pT ){
@@ -8684,7 +8666,7 @@ static void fts5DecodeRowid(
#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG)
static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){
int iSegid, iHeight, iPgno, bDlidx, bTomb; /* Rowid components */
int iSegid, iHeight, iPgno, bDlidx, bTomb; /* Rowid compenents */
fts5DecodeRowid(iKey, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno);
if( iSegid==0 ){
@@ -8930,7 +8912,7 @@ static void fts5DecodeFunction(
** buffer overreads even if the record is corrupt. */
n = sqlite3_value_bytes(apVal[1]);
aBlob = sqlite3_value_blob(apVal[1]);
nSpace = ((i64)n) + FTS5_DATA_ZERO_PADDING;
nSpace = n + FTS5_DATA_ZERO_PADDING;
a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace);
if( a==0 ) goto decode_out;
if( n>0 ) memcpy(a, aBlob, n);
+4 -6
View File
@@ -170,11 +170,9 @@ struct Fts5Sorter {
i64 iRowid; /* Current rowid */
const u8 *aPoslist; /* Position lists for current row */
int nIdx; /* Number of entries in aIdx[] */
int aIdx[FLEXARRAY]; /* Offsets into aPoslist for current row */
int aIdx[1]; /* Offsets into aPoslist for current row */
};
/* Size (int bytes) of an Fts5Sorter object with N indexes */
#define SZ_FTS5SORTER(N) (offsetof(Fts5Sorter,nIdx)+((N+2)/2)*sizeof(i64))
/*
** Virtual-table cursor object.
@@ -1052,7 +1050,7 @@ static int fts5CursorFirstSorted(
const char *zRankArgs = pCsr->zRankArgs;
nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
nByte = SZ_FTS5SORTER(nPhrase);
nByte = sizeof(Fts5Sorter) + sizeof(int) * (nPhrase-1);
pSorter = (Fts5Sorter*)sqlite3_malloc64(nByte);
if( pSorter==0 ) return SQLITE_NOMEM;
memset(pSorter, 0, (size_t)nByte);
@@ -3803,8 +3801,8 @@ static int fts5Init(sqlite3 *db){
** its entry point to enable the matchinfo() demo. */
#ifdef SQLITE_FTS5_ENABLE_TEST_MI
if( rc==SQLITE_OK ){
extern int sqlite3Fts5TestRegisterMatchinfoAPI(fts5_api*);
rc = sqlite3Fts5TestRegisterMatchinfoAPI(&pGlobal->api);
extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3*);
rc = sqlite3Fts5TestRegisterMatchinfo(db);
}
#endif
+11 -23
View File
@@ -14,7 +14,7 @@
** versions of FTS5. It contains the implementation of an FTS5 auxiliary
** function very similar to the FTS4 function matchinfo():
**
** https://sqlite.org/fts3.html#matchinfo
** https://www.sqlite.org/fts3.html#matchinfo
**
** Known differences are that:
**
@@ -393,13 +393,17 @@ static void fts5MatchinfoFunc(
}
}
/*
** Register "matchinfo" with global API object pApi.
*/
int sqlite3Fts5TestRegisterMatchinfoAPI(fts5_api *pApi){
int rc;
int sqlite3Fts5TestRegisterMatchinfo(sqlite3 *db){
int rc; /* Return code */
fts5_api *pApi; /* FTS5 API functions */
/* If fts5_api_from_db() returned NULL, then either FTS5 is not registered
/* Extract the FTS5 API pointer from the database handle. The
** fts5_api_from_db() function above is copied verbatim from the
** FTS5 documentation. Refer there for details. */
rc = fts5_api_from_db(db, &pApi);
if( rc!=SQLITE_OK ) return rc;
/* If fts5_api_from_db() returns NULL, then either FTS5 is not registered
** with this database handle, or an error (OOM perhaps?) has occurred.
**
** Also check that the fts5_api object is version 2 or newer.
@@ -414,20 +418,4 @@ int sqlite3Fts5TestRegisterMatchinfoAPI(fts5_api *pApi){
return rc;
}
/*
** Register "matchinfo" with database handle db.
*/
int sqlite3Fts5TestRegisterMatchinfo(sqlite3 *db){
int rc; /* Return code */
fts5_api *pApi; /* FTS5 API functions */
/* Extract the FTS5 API pointer from the database handle. The
** fts5_api_from_db() function above is copied verbatim from the
** FTS5 documentation. Refer there for details. */
rc = fts5_api_from_db(db, &pApi);
if( rc!=SQLITE_OK ) return rc;
return sqlite3Fts5TestRegisterMatchinfoAPI(pApi);
}
#endif /* SQLITE_ENABLE_FTS5 */
+1
View File
@@ -778,3 +778,4 @@ void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){
}
aAscii[0] = 0; /* 0x00 is never a token character */
}
+3 -3
View File
@@ -193,12 +193,12 @@ static int fts5VocabInitVtab(
*pzErr = sqlite3_mprintf("wrong number of vtable arguments");
rc = SQLITE_ERROR;
}else{
i64 nByte; /* Bytes of space to allocate */
int nByte; /* Bytes of space to allocate */
const char *zDb = bDb ? argv[3] : argv[1];
const char *zTab = bDb ? argv[4] : argv[3];
const char *zType = bDb ? argv[5] : argv[4];
i64 nDb = strlen(zDb)+1;
i64 nTab = strlen(zTab)+1;
int nDb = (int)strlen(zDb)+1;
int nTab = (int)strlen(zTab)+1;
int eType = 0;
rc = fts5VocabTableType(zType, pzErr, &eType);
-22
View File
@@ -520,26 +520,4 @@ do_execsql_test 15.3 {
{columnsize {1 1} columntext {c d} columntotalsize {2 2} poslist {} tokenize {c d} rowcount 2}
}
#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 16.0 {
CREATE TABLE t1(x);
BEGIN EXCLUSIVE;
}
sqlite3 db2 test.db
do_test 16.1 {
catchsql { SELECT * FROM t1 } db2
} {1 {database is locked}}
do_execsql_test 16.2 {
ROLLBACK;
}
do_test 16.3 {
catchsql { SELECT * FROM t1 } db2
} {0 {}}
finish_test
+1 -1
View File
@@ -81,7 +81,7 @@ do_execsql_test 3.0 {
}
#-------------------------------------------------------------------------
# Test that a crash occurring when the second or subsequent tokens in a
# Test that a crash occuring when the second or subsequent tokens in a
# phrase matched zero rows has been fixed.
#
do_execsql_test 4.0 {
+2 -2
View File
@@ -79,7 +79,7 @@ $(bin.version-info): $(dir.tool)/version-info.c $(sqlite3.h) $(dir.top)/Makefile
$(MAKE) -C $(dir.top) version-info
# Be explicit about which Java files to compile so that we can work on
# in-progress files without requiring them to be in a compilable state.
# in-progress files without requiring them to be in a compilable statae.
JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/annotation/%,\
Experimental.java \
NotNull.java \
@@ -451,7 +451,7 @@ distclean: clean
-rm -fr $(dir.bld.c) $(dir.doc)
########################################################################
# distribution bundle rules...
# disttribution bundle rules...
ifeq (,$(filter snapshot,$(MAKECMDGOALS)))
dist-name-prefix := sqlite-jni
+1 -1
View File
@@ -169,7 +169,7 @@ deliberately return an error code, instead of segfaulting, when passed
a `null`.
Client-defined callbacks _must never throw exceptions_ unless _very
explicitly documented_ as being throw-safe. Exceptions are generally
explitly documented_ as being throw-safe. Exceptions are generally
reserved for higher-level bindings which are constructed to
specifically deal with them and ensure that they do not leak C-level
resources. In some cases, callback handlers are permitted to throw, in
+4 -4
View File
@@ -948,7 +948,7 @@ static JNIEnv * s3jni_env(void){
}
/*
** Fetches the S3JniGlobal.envCache row for the given env, allocating a
** Fetches the S3JniGlobal.envCache row for the given env, allocing a
** row if needed. When a row is allocated, its state is initialized
** insofar as possible. Calls (*env)->FatalError() if allocation of an
** entry fails. That's hypothetically possible but "shouldn't happen."
@@ -1603,7 +1603,7 @@ static void * NativePointerHolder__get(JNIEnv * env, jobject jNph,
** 2023-11-09: testing has not revealed any measurable performance
** difference between the approach of passing type T to C compared to
** passing pointer-to-T to C, and adding support for the latter
** everywhere requires significantly more code. As of this writing, the
** everywhere requires sigificantly more code. As of this writing, the
** older/simpler approach is being applied except for (A) where the
** newer approach has already been applied and (B) hot-spot APIs where
** a difference of microseconds (i.e. below our testing measurement
@@ -3290,7 +3290,7 @@ static void s3jni_rollback_hook_impl(void *pP){
static jobject s3jni_commit_rollback_hook(int isCommit, JNIEnv * const env,
jlong jpDb, jobject jHook){
S3JniDb * ps;
jobject pOld = 0; /* previous hook */
jobject pOld = 0; /* previous hoook */
S3JniHook * pHook; /* ps->hooks.commit|rollback */
S3JniDb_mutex_enter;
@@ -5696,7 +5696,7 @@ JniDeclFtsApi(jint,xCreateFunction)(JniArgsEnvObj, jstring jName,
typedef struct S3JniFts5AuxData S3JniFts5AuxData;
/*
** TODO: this middle-man struct is no longer necessary. Consider
** TODO: this middle-man struct is no longer necessary. Conider
** removing it and passing around jObj itself instead.
*/
struct S3JniFts5AuxData {
+9 -9
View File
@@ -199,16 +199,16 @@ public final class CApi {
}
private static native sqlite3_backup sqlite3_backup_init(
@NotNull long ptrToDbDest, @NotNull String destSchemaName,
@NotNull long ptrToDbSrc, @NotNull String srcSchemaName
@NotNull long ptrToDbDest, @NotNull String destTableName,
@NotNull long ptrToDbSrc, @NotNull String srcTableName
);
public static sqlite3_backup sqlite3_backup_init(
@NotNull sqlite3 dbDest, @NotNull String destSchemaName,
@NotNull sqlite3 dbSrc, @NotNull String srcSchemaName
@NotNull sqlite3 dbDest, @NotNull String destTableName,
@NotNull sqlite3 dbSrc, @NotNull String srcTableName
){
return sqlite3_backup_init( dbDest.getNativePointer(), destSchemaName,
dbSrc.getNativePointer(), srcSchemaName );
return sqlite3_backup_init( dbDest.getNativePointer(), destTableName,
dbSrc.getNativePointer(), srcTableName );
}
private static native int sqlite3_backup_pagecount(@NotNull long ptrToBackup);
@@ -264,7 +264,7 @@ public final class CApi {
}
/**
Convenience overload which is equivalent to passing its arguments
Convenience overload which is equivalant to passing its arguments
to sqlite3_bind_nio_buffer() with the values 0 and -1 for the
final two arguments.
*/
@@ -312,7 +312,7 @@ public final class CApi {
The byte range of the buffer may be restricted by providing a
start index and a number of bytes. beginPos may not be negative.
Negative howMany is interpreted as the remainder of the buffer
Negative howMany is interpretated as the remainder of the buffer
past the given start position, up to the buffer's limit() (as
opposed its capacity()).
@@ -1076,7 +1076,7 @@ public final class CApi {
/**
<p>Works like in the C API with the exception that it only supports
the following subset of configuration flags:
the following subset of configution flags:
<p>SQLITE_CONFIG_SINGLETHREAD
SQLITE_CONFIG_MULTITHREAD
@@ -18,7 +18,7 @@ package org.sqlite.jni.capi;
classes which have a call() method implementing some specific
callback interface on behalf of the C library.
<p>Unless very explicitly documented otherwise, callbacks must
<p>Unless very explicitely documented otherwise, callbacks must
never throw. Any which do throw but should not might trigger debug
output regarding the error, but the exception will not be
propagated. For callback interfaces which support returning error
@@ -20,7 +20,7 @@ public interface PrepareMultiCallback extends CallbackProxy {
/**
Gets passed a sqlite3_stmt which it may handle in arbitrary ways,
transferring ownership of it to this function.
transfering ownership of it to this function.
sqlite3_prepare_multi() will _not_ finalize st - it is up
to the call() implementation how st is handled.
@@ -264,7 +264,7 @@ public class SQLTester {
threw = true;
outln("🔥EXCEPTION: ",e.getClass().getSimpleName(),": ",e.getMessage());
++nAbortedScript;
if( keepGoing ) outln("Continuing anyway because of the keep-going option.");
if( keepGoing ) outln("Continuing anyway becaure of the keep-going option.");
else if( e.isFatal() ) throw e;
}finally{
final long timeEnd = System.currentTimeMillis();
@@ -101,7 +101,7 @@ interpreter is in a "verbose" mode, the interpreter might choose to emit
an informational message along the lines of "test script NAME abandoned
due to unsupported command: --whatever".
The initial implementation will only recognize a few commands. Other
The initial implemention will only recognize a few commands. Other
commands may be added later. The following is the initial set of
commands:
@@ -144,7 +144,7 @@ public interface SqlFunction {
range.
*/
public void setAuxData(int argNdx, Object o){
/* From the API docs: https://sqlite.org/c3ref/get_auxdata.html
/* From the API docs: https://www.sqlite.org/c3ref/get_auxdata.html
The value of the N parameter to these interfaces should be
non-negative. Future enhancements may make use of negative N
@@ -661,7 +661,7 @@ public final class Sqlite implements AutoCloseable {
}
/**
Equivalent to prepareMulti(X,prepFlags,visitor), where X is
Equivallent to prepareMulti(X,prepFlags,visitor), where X is
sql.getBytes(StandardCharsets.UTF_8).
*/
public void prepareMulti(String sql, int prepFlags, PrepareMulti visitor){
+1 -1
View File
@@ -570,7 +570,7 @@ struct FreelistEntry {
/*
** A snapshot of a database. A snapshot contains all the information required
** to read or write a database file on disk. See the description of struct
** Database below for further details.
** Database below for futher details.
*/
struct Snapshot {
Database *pDatabase; /* Database this snapshot belongs to */
+1 -1
View File
@@ -169,7 +169,7 @@
** The argument to this macro must be of type u32. On a little-endian
** architecture, it returns the u32 value that results from interpreting
** the 4 bytes as a big-endian value. On a big-endian architecture, it
** returns the value that would be produced by interpreting the 4 bytes
** returns the value that would be produced by intepreting the 4 bytes
** of the input value as a little-endian integer.
*/
#define BYTESWAP32(x) ( \
+2 -2
View File
@@ -793,7 +793,7 @@ void lsmFsClose(FileSystem *pFS){
**
** This function returns a pointer to an object that can be linked into
** the list described above. The returned object now 'owns' the database
** file descriptor, so that when the FileSystem object is destroyed, it
** file descriptr, so that when the FileSystem object is destroyed, it
** will not be closed.
**
** This function may be called at most once in the life-time of a
@@ -2293,7 +2293,7 @@ int lsmFsMetaPageGet(
);
}
#ifndef NDEBUG
/* pPg->aData causes an uninitialized access via a downstream write().
/* pPg->aData causes an uninitialized access via a downstreadm write().
After discussion on this list, this memory should not, for performance
reasons, be memset. However, tracking down "real" misuse is more
difficult with this "false" positive, so it is set when NDEBUG.
+1 -1
View File
@@ -758,7 +758,7 @@ void lsmLogTell(
}
/*
** Seek (rewind) back to the log file offset stored by an earlier call to
** Seek (rewind) back to the log file offset stored by an ealier call to
** lsmLogTell() in *pMark.
*/
void lsmLogSeek(
+3 -3
View File
@@ -2652,7 +2652,7 @@ int lsmSortedLoadFreelist(
void **ppVal, /* OUT: Blob containing LSM free-list */
int *pnVal /* OUT: Size of *ppVal blob in bytes */
){
MultiCursor *pCsr; /* Cursor used to retrieve free-list */
MultiCursor *pCsr; /* Cursor used to retreive free-list */
int rc = LSM_OK; /* Return Code */
assert( pDb->pWorker );
@@ -2764,7 +2764,7 @@ static int mcursorLocationOk(MultiCursor *pCsr, int bDeleteOk){
}
/* If the cursor points to a system key (free-list entry), and the
** CURSOR_IGNORE_SYSTEM flag is set, skip this entry. */
** CURSOR_IGNORE_SYSTEM flag is set, skip thie entry. */
if( (pCsr->flags & CURSOR_IGNORE_SYSTEM) && rtTopic(eType)!=0 ){
return 0;
}
@@ -3586,7 +3586,7 @@ static int mergeWorkerBtreeWrite(
Hierarchy *p = &pMW->hier;
lsm_db *pDb = pMW->pDb; /* Database handle */
int rc = LSM_OK; /* Return Code */
int iLevel; /* Level of b-tree hierarchy to write to */
int iLevel; /* Level of b-tree hierachy to write to */
int nData; /* Size of aData[] in bytes */
u8 *aData; /* Page data for level iLevel */
int iOff; /* Offset on b-tree page to write record to */
+6 -6
View File
@@ -1,7 +1,7 @@
## Miscellaneous Extensions
This folder contains a collection of smaller loadable extensions.
See <https://sqlite.org/loadext.html> for instructions on how
See <https://www.sqlite.org/loadext.html> for instructions on how
to compile and use loadable extensions.
Each extension in this folder is implemented in a single file of C code.
@@ -10,9 +10,9 @@ header comments for details about each extension. Additional notes are
as follows:
* **carray.c** &mdash; This module implements the
[carray](https://sqlite.org/carray.html) table-valued function.
[carray](https://www.sqlite.org/carray.html) table-valued function.
It is a good example of how to go about implementing a custom
[table-valued function](https://sqlite.org/vtab.html#tabfunc2).
[table-valued function](https://www.sqlite.org/vtab.html#tabfunc2).
* **csv.c** &mdash; A [virtual table](https://sqlite.org/vtab.html)
for reading
@@ -21,7 +21,7 @@ as follows:
* **dbdump.c** &mdash; This is not actually a loadable extension, but
rather a library that implements an approximate equivalent to the
".dump" command of the
[command-line shell](https://sqlite.org/cli.html).
[command-line shell](https://www.sqlite.org/cli.html).
* **json1.c** &mdash; Various SQL functions and table-valued functions
for processing JSON. This extension is already built into the
@@ -29,7 +29,7 @@ as follows:
<https://sqlite.org/json1.html> for additional information.
* **memvfs.c** &mdash; This file implements a custom
[VFS](https://sqlite.org/vfs.html) that stores an entire database
[VFS](https://www.sqlite.org/vfs.html) that stores an entire database
file in a single block of RAM. It serves as a good example of how
to implement a simple custom VFS.
@@ -38,7 +38,7 @@ as follows:
new custom SQL functions for SQLite.
* **series.c** &mdash; This is an implementation of the
"generate_series" [virtual table](https://sqlite.org/vtab.html).
"generate_series" [virtual table](https://www.sqlite.org/vtab.html).
It can make a good template for new custom virtual table implementations.
* **shathree.c** &mdash; An implementation of the sha3() and
+2 -2
View File
@@ -482,9 +482,9 @@ struct amatch_rule {
amatch_rule *pNext; /* Next rule in order of increasing rCost */
char *zFrom; /* Transform from (a string from user input) */
amatch_cost rCost; /* Cost of this transformation */
amatch_langid iLang; /* The language to which this rule belongs */
amatch_langid iLang; /* The langauge to which this rule belongs */
amatch_len nFrom, nTo; /* Length of the zFrom and zTo strings */
char zTo[4]; /* Transform to V.W value (extra space appended) */
char zTo[4]; /* Tranform to V.W value (extra space appended) */
};
/*
+1 -1
View File
@@ -49,7 +49,7 @@
** USAGE EXAMPLES:
**
** Show the table btrees in a schema order with the tables with the most
** rows occurring first:
** rows occuring first:
**
** SELECT name, nEntry
** FROM sqlite_btreeinfo
+1 -1
View File
@@ -137,7 +137,7 @@
** AND closure.idname='groupId'
** AND closure.parentname='parentId';
**
** See the documentation at http://sqlite.org/loadext.html for information
** See the documentation at http://www.sqlite.org/loadext.html for information
** on how to compile and use loadable extensions such as this one.
*/
#include "sqlite3ext.h"
+1 -6
View File
@@ -41,11 +41,6 @@ SQLITE_EXTENSION_INIT1
#ifndef SQLITE_OMIT_VIRTUALTABLE
#ifndef IsAlnum
#define IsAlnum(X) isalnum((unsigned char)X)
#endif
/* completion_vtab is a subclass of sqlite3_vtab which will
** serve as the underlying representation of a completion virtual table
*/
@@ -382,7 +377,7 @@ static int completionFilter(
}
if( pCur->zLine!=0 && pCur->zPrefix==0 ){
int i = pCur->nLine;
while( i>0 && (IsAlnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
i--;
}
pCur->nPrefix = pCur->nLine - i;
+1 -1
View File
@@ -315,7 +315,7 @@ typedef struct CsvTable {
} CsvTable;
/* Allowed values for tstFlags */
#define CSVTEST_FIDX 0x0001 /* Pretend that constrained search cost less*/
#define CSVTEST_FIDX 0x0001 /* Pretend that constrained searchs cost less*/
/* A cursor for the CSV virtual table */
typedef struct CsvCursor {
+2 -5
View File
@@ -27,9 +27,6 @@ SQLITE_EXTENSION_INIT1
# define UNUSED_PARAMETER(X) (void)(X)
#endif
#ifndef IsSpace
#define IsSpace(X) isspace((unsigned char)X)
#endif
/* A decimal object */
typedef struct Decimal Decimal;
@@ -79,7 +76,7 @@ static Decimal *decimalNewFromText(const char *zIn, int n){
p->nFrac = 0;
p->a = sqlite3_malloc64( n+1 );
if( p->a==0 ) goto new_from_text_failed;
for(i=0; IsSpace(zIn[i]); i++){}
for(i=0; isspace(zIn[i]); i++){}
if( zIn[i]=='-' ){
p->sign = 1;
i++;
@@ -734,7 +731,7 @@ static void decimalSubFunc(
decimal_free(pB);
}
/* Aggregate function: decimal_sum(X)
/* Aggregate funcion: decimal_sum(X)
**
** Works like sum() except that it uses decimal arithmetic for unlimited
** precision.
+1 -1
View File
@@ -22,7 +22,7 @@
** The delta format is the Fossil delta format, described in a comment
** on the delete_create() function implementation below, and also at
**
** https://fossil-scm.org/fossil/doc/trunk/www/delta_format.wiki
** https://www.fossil-scm.org/fossil/doc/trunk/www/delta_format.wiki
**
** This delta format is used by the RBU extension, which is the main
** reason that these routines are included in the extension library.
+3 -3
View File
@@ -68,7 +68,7 @@
** AND distance<200;
**
** This first query outputs the string "abcdefg" and all strings that
** can be derived from that string by applying the specified transformations.
** can be derived from that string by appling the specified transformations.
** The strings are output together with their total transformation cost
** (called "distance") and appear in order of increasing cost. No string
** is output more than once. If there are multiple ways to transform the
@@ -97,7 +97,7 @@
** LIMIT 20
**
** The query above gives the 20 closest words to the $word being tested.
** (Note that for good performance, the vocabulary.w column should be
** (Note that for good performance, the vocubulary.w column should be
** indexed.)
**
** A similar query can be used to find all words in the dictionary that
@@ -207,7 +207,7 @@ struct fuzzer_rule {
** Every stem is added to a hash table as it is output. Generation of
** duplicate stems is suppressed.
**
** Active stems (those that might generate new outputs) are kept on a linked
** Active stems (those that might generate new outputs) are kepts on a linked
** list sorted by increasing cost. The cost is the sum of rBaseCost and
** pRule->rCost.
*/
+1 -1
View File
@@ -79,7 +79,7 @@
** WITH c(name,bin) AS (VALUES
** ('minimum positive value', x'0000000000000001'),
** ('maximum subnormal value', x'000fffffffffffff'),
** ('minimum positive normal value', x'0010000000000000'),
** ('mininum positive nornal value', x'0010000000000000'),
** ('maximum value', x'7fefffffffffffff'))
** SELECT c.name, decimal_mul(ieee754_mantissa(c.bin),pow2.v)
** FROM pow2, c WHERE pow2.x=ieee754_exponent(c.bin);
+2 -8
View File
@@ -401,14 +401,8 @@ static sqlite3_module memstatModule = {
#endif /* SQLITE_OMIT_VIRTUALTABLE */
int sqlite3MemstatVtabInit(
sqlite3 *db,
char **NotUsed1,
const sqlite3_api_routines *NotUsed2
){
int sqlite3MemstatVtabInit(sqlite3 *db){
int rc = SQLITE_OK;
(void)NotUsed1;
(void)NotUsed2;
#ifndef SQLITE_OMIT_VIRTUALTABLE
rc = sqlite3_create_module(db, "sqlite_memstat", &memstatModule, 0);
#endif
@@ -427,7 +421,7 @@ int sqlite3_memstat_init(
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
#ifndef SQLITE_OMIT_VIRTUALTABLE
rc = sqlite3MemstatVtabInit(db, 0, 0);
rc = sqlite3MemstatVtabInit(db);
#endif
return rc;
}
+1 -1
View File
@@ -286,7 +286,7 @@ static const unsigned char sqlite3CtypeMap[256] = {
#define TK_VARIABLE TK_LITERAL
#define TK_BLOB TK_LITERAL
/* Disable nuisance warnings about case fall-through */
/* Disable nuisence warnings about case fall-through */
#if !defined(deliberate_fall_through) && defined(__GCC__) && __GCC__>=7
# define deliberate_fall_through __attribute__((fallthrough));
#else
+1 -1
View File
@@ -205,7 +205,7 @@ static int percentBinarySearch(Percentile *p, double y, int bExact){
/*
** Generate an error for a percentile function.
**
** The error format string must have exactly one occurrence of "%%s()"
** The error format string must have exactly one occurrance of "%%s()"
** (with two '%' characters). That substring will be replaced by the name
** of the function.
*/
+24 -51
View File
@@ -60,7 +60,8 @@
** step HIDDEN
** );
**
** The virtual table also has a rowid which is an alias for the value.
** The virtual table also has a rowid, logically equivalent to n+1 where
** "n" is the ascending integer in the aforesaid production definition.
**
** Function arguments in queries against this virtual table are translated
** into equality constraints against successive hidden columns. In other
@@ -115,7 +116,6 @@ SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#include <limits.h>
#include <math.h>
#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
@@ -139,7 +139,7 @@ static sqlite3_int64 genSeqMember(
smBase += (mxI64 - mxI64/2) * smStep;
}
/* Under UBSAN (or on 1's complement machines), must do this last term
* in steps to avoid the dreaded (and harmless) signed multiply overflow. */
* in steps to avoid the dreaded (and harmless) signed multiply overlow. */
if( ix>=2 ){
sqlite3_int64 ix2 = (sqlite3_int64)ix/2;
smBase += ix2*smStep;
@@ -276,7 +276,6 @@ static int seriesConnect(
int rc;
/* Column numbers */
#define SERIES_COLUMN_ROWID (-1)
#define SERIES_COLUMN_VALUE 0
#define SERIES_COLUMN_START 1
#define SERIES_COLUMN_STOP 2
@@ -364,11 +363,13 @@ static int seriesColumn(
#endif
/*
** The rowid is the same as the value.
** Return the rowid for the current row, logically equivalent to n+1 where
** "n" is the ascending integer in the aforesaid production definition.
*/
static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
series_cursor *pCur = (series_cursor*)cur;
*pRowid = pCur->ss.iValueNow;
sqlite3_uint64 n = pCur->ss.uSeqIndexNow;
*pRowid = (sqlite3_int64)((n<LARGEST_UINT64)? n+1 : 0);
return SQLITE_OK;
}
@@ -481,52 +482,25 @@ static int seriesFilter(
** constraints on the "value" column.
*/
if( idxNum & 0x0080 ){
if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){
double r = sqlite3_value_double(argv[i++]);
if( r==ceil(r) ){
iMin = iMax = (sqlite3_int64)r;
}else{
returnNoRows = 1;
}
}else{
iMin = iMax = sqlite3_value_int64(argv[i++]);
}
iMin = iMax = sqlite3_value_int64(argv[i++]);
}else{
if( idxNum & 0x0300 ){
if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){
double r = sqlite3_value_double(argv[i++]);
if( idxNum & 0x0200 && r==ceil(r) ){
iMin = (sqlite3_int64)ceil(r+1.0);
iMin = sqlite3_value_int64(argv[i++]);
if( idxNum & 0x0200 ){
if( iMin==LARGEST_INT64 ){
returnNoRows = 1;
}else{
iMin = (sqlite3_int64)ceil(r);
}
}else{
iMin = sqlite3_value_int64(argv[i++]);
if( idxNum & 0x0200 ){
if( iMin==LARGEST_INT64 ){
returnNoRows = 1;
}else{
iMin++;
}
iMin++;
}
}
}
if( idxNum & 0x3000 ){
if( sqlite3_value_numeric_type(argv[i])==SQLITE_FLOAT ){
double r = sqlite3_value_double(argv[i++]);
if( (idxNum & 0x2000)!=0 && r==floor(r) ){
iMax = (sqlite3_int64)(r-1.0);
iMax = sqlite3_value_int64(argv[i++]);
if( idxNum & 0x2000 ){
if( iMax==SMALLEST_INT64 ){
returnNoRows = 1;
}else{
iMax = (sqlite3_int64)floor(r);
}
}else{
iMax = sqlite3_value_int64(argv[i++]);
if( idxNum & 0x2000 ){
if( iMax==SMALLEST_INT64 ){
returnNoRows = 1;
}else{
iMax--;
}
iMax--;
}
}
}
@@ -545,7 +519,8 @@ static int seriesFilter(
pCur->ss.iBase += ((d+szStep-1)/szStep)*szStep;
}
if( pCur->ss.iTerm>iMax ){
pCur->ss.iTerm = iMax;
sqlite3_uint64 d = pCur->ss.iTerm - iMax;
pCur->ss.iTerm -= ((d+szStep-1)/szStep)*szStep;
}
}else{
sqlite3_int64 szStep = -pCur->ss.iStep;
@@ -555,7 +530,8 @@ static int seriesFilter(
pCur->ss.iBase -= ((d+szStep-1)/szStep)*szStep;
}
if( pCur->ss.iTerm<iMin ){
pCur->ss.iTerm = iMin;
sqlite3_uint64 d = iMin - pCur->ss.iTerm;
pCur->ss.iTerm += ((d+szStep-1)/szStep)*szStep;
}
}
}
@@ -580,7 +556,7 @@ static int seriesFilter(
for(i=0; i<argc; i++){
if( sqlite3_value_type(argv[i])==SQLITE_NULL ){
/* If any of the constraints have a NULL value, then return no rows.
** See ticket https://sqlite.org/src/info/fac496b61722daf2 */
** See ticket https://www.sqlite.org/src/info/fac496b61722daf2 */
returnNoRows = 1;
break;
}
@@ -683,10 +659,7 @@ static int seriesBestIndex(
continue;
}
if( pConstraint->iColumn<SERIES_COLUMN_START ){
if( (pConstraint->iColumn==SERIES_COLUMN_VALUE ||
pConstraint->iColumn==SERIES_COLUMN_ROWID)
&& pConstraint->usable
){
if( pConstraint->iColumn==SERIES_COLUMN_VALUE && pConstraint->usable ){
switch( op ){
case SQLITE_INDEX_CONSTRAINT_EQ:
case SQLITE_INDEX_CONSTRAINT_IS: {
+1 -1
View File
@@ -64,7 +64,7 @@
**
** typeof(Y)='blob' The hash is taken over prefix "Bnnn:" followed
** by the binary content of the blob. The "nnn"
** in the prefix is the minimum-length decimal
** in the prefix is the mimimum-length decimal
** representation of the byte-length of the blob.
**
** According to the rules above, all of the following SELECT statements
+1 -1
View File
@@ -12,7 +12,7 @@
**
** This module implements the spellfix1 VIRTUAL TABLE that can be used
** to search a large vocabulary for close matches. See separate
** documentation (http://sqlite.org/spellfix1.html) for details.
** documentation (http://www.sqlite.org/spellfix1.html) for details.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1

Some files were not shown because too many files have changed in this diff Show More