Compare commits

...

36 Commits

Author SHA1 Message Date
drh
70d390134c Call fflush() on ".echo" output from the shell, so that the output to
stdout is aligned with output to stderr.

FossilOrigin-Name: c38b9db3c4f71706a7d211424da64311e6e5daf64b224565a6d82d4b1a68e261
2024-11-16 18:54:46 +00:00
drh
18689b8fb2 Fix argument expansion in sqlite-tclsh on Windows such that if an argument
does not match a filename even after glob expansion, it is appended to the
argument list verbatim.

FossilOrigin-Name: cd942dce148c9d8f5a94cee61923aad8d1b732b807e004005f78323be30c02e7
2024-11-16 17:39:34 +00:00
stephan
50faa8d17e Handle DESTDIR at an earlier phase in buildtclext.tcl to account for the is-writable-dir check and to filter out //zipfs: dirs as (im)possible installation targets.
FossilOrigin-Name: d2e8c161a14fbbcc52c50dfd9274c9969e3c273e2cb7cbf2f865541af9f39ead
2024-11-16 17:09:55 +00:00
stephan
f6c7cc606e Add the --destdir flag to the tclextension-install makefile target.
FossilOrigin-Name: d1663cf05f7dcaafd479bacf083b6b774f34fd3db89012b49599d30817eb174f
2024-11-16 14:30:43 +00:00
stephan
d8f6222bee Add --destdir flag support to buildtclext.tcl, but do not yet add that to the makefile (so that this change can be cherrypicked to the 3.47 build).
FossilOrigin-Name: 67a3ca0c013b6a9da3b2c50ffc86b96b14454d1e45fa90d3b0a238488a783e79
2024-11-16 14:29:51 +00:00
stephan
4b24cb2a3a Rename tool/tclConfigShToTcl.sh to tool/tclConfigShToAutoDef.sh in the name of pedantic correctness.
FossilOrigin-Name: a7dd196d99ee7c75b92a03915f2b370e3f4c598eb8521b90af1cb5dd7f9ee49c
2024-11-16 10:42:33 +00:00
stephan
d676227f2c configure: tiny simplification of proj-assert.
FossilOrigin-Name: bfdc416b561937aa74483bf96c042e701e6f98997150f1f1a6b165cddd40d8d1
2024-11-16 09:00:31 +00:00
drh
178ce6287b Enhance the vfstrace extension such that the output can be controlled using
the "PRAGMA vfstrace('...');" statement.  See header comment on the source code
for details.

FossilOrigin-Name: 96105d33597765c23dbd490b3aa0c2273731d1970d7041720e9f043dbe3517b3
2024-11-15 20:39:41 +00:00
stephan
1adf87592f In the interest of minimizing downstream disruption, set the soname of libsqlite3.so to (by default) its legacy value of libsqlite3.so.0 and unconditionally create (or replace) a symlink with that name at install-time, in addition to the newer-named symlinks.
FossilOrigin-Name: 0773677b553e032e992266c6c75e10565729238df3ef52b56602a92cf651bea7
2024-11-15 19:42:49 +00:00
stephan
e69b4d757e Generic auto.def cleanups. No functional differences.
FossilOrigin-Name: 02aceb8c138b5b8f38c75aa0792efa12f14b002083df6141cf56ea0602d3174b
2024-11-15 16:35:24 +00:00
stephan
48c8447574 buildtclext.tcl: work around a case, reported in [forum:0683a49cb02f31a1|forum post 0683a49cb0], in which package maintainers edit their copy of tclConfig.sh to change the TCL_SHLIB_LD command.
FossilOrigin-Name: e24a3efec8c168b69d665ab20e8d715210208e6cf291ac93549fdd175a9009d6
2024-11-15 15:31:13 +00:00
stephan
2eb9605e81 configure: add optional pkg-config support for detecting ICU.
FossilOrigin-Name: 3e5b8077c6c6ce72ecab3110eb45943b9765372df789088982dbd6046a7c2523
2024-11-15 10:53:57 +00:00
stephan
ece4bf60ff When checking pkg-config for ICU support use icu-io instead of icu-uc, as that contains all requires libs on Linux and BSD.
FossilOrigin-Name: 6ca457542e1dceac2d68fe3d29ff1f0beb31a77ca3073bd7d8a6c62faabcdc1d
2024-11-15 10:47:11 +00:00
stephan
aa85c8c854 configure script doc additions for the ICU feature check.
FossilOrigin-Name: 1925a68fc2323f0788aac9c3c2bb3005182eb3286037bc383181b6aa150d4270
2024-11-15 10:12:03 +00:00
stephan
75ed9f819f An experiment in optionally using pkg-config to determine the libs to link in for ICU support, but its ldflags is missing one required lib on both Linux and OpenBSD. Keeping this for later reference, as it demonstrates how to use pkg-config from autosetup.
FossilOrigin-Name: 09caa94c9e846f9b3669b3f1acbb26b24b8bfcc9e512f17ea074dd92745c2597
2024-11-15 10:07:57 +00:00
stephan
f121ffbde3 Fix typo in the handling of the new --dev flag which caused it to set the --debug flag instead of the --with-debug flag (the former is for autosetup's internal use).
FossilOrigin-Name: 81202d2ab5963fdcf20555b6d0b31cc955ac27f1cd87656faea5c0611c9a2ee8
2024-11-14 19:34:28 +00:00
stephan
009601d534 Remove $prefix/include from the default -I path because it can cause the build to pick up an unintended copy of sqlite3.h. Extend the ICU configure support (the origin of -I$prefix/include) to enable fetching the -I path from icu-config and apply it only to those objects which need it.
FossilOrigin-Name: f778dfdd6d6a4975c903d8ca0ebfb4fa917d543289136ea0ab740cb47d2510c1
2024-11-14 19:25:23 +00:00
drh
59c80e0533 Add new makefile target "sqlite3d" (where the "d" means either "development" or
"debug") that always uses separate source files, regardless of the 
--disable-amalgmation setting.

FossilOrigin-Name: 91da205beb7e5cab7a76be98e4cfddc4fb4c07022825ea645bc97f331c6bcdaa
2024-11-14 19:06:00 +00:00
stephan
c096d6add6 Add --enable-dev configure flag which sets various other flags.
FossilOrigin-Name: ea79c363a42484357ac4ac3422f3466e5bc5cb56e5b2a06a3dc4ec90fea1c190
2024-11-14 17:52:59 +00:00
stephan
17e7e16b3b Remove unused sqlite_cfg.h.in from the build.
FossilOrigin-Name: bba54e26de56ddf804990f5cd9a1978a14580f06c5771a79803907013df8491e
2024-11-14 16:06:36 +00:00
stephan
98be43ed73 Fix a state makefile dependency which refered to the now-removed sqlite_cfg.h.in.
FossilOrigin-Name: 9a726b4be8ddd4b388478024a0952cfd4f0b9f665ab69119a6de0b996ac72216
2024-11-14 16:00:45 +00:00
drh
ea13658566 Remove some obsolete macros from the CLI.
FossilOrigin-Name: 5c4eb625709eda24b11a0437b150a60fc1497c136a4a2ab2b9d559d893dd397a
2024-11-14 15:55:19 +00:00
stephan
752df4c49b Remove unused sqlite_cfg.h.in (sqlite_cfg.h gets generated without an input template).
FossilOrigin-Name: 6148f2d39237a85edb399e5c2beb305dccd99ca8c0cf143e8c2ddc0fc1d9e916
2024-11-14 15:25:05 +00:00
dan
c87d7bede0 Fix a problem with window functions min() and max() when used with a FILTER clause. Forum post [forum:/forumpost/e9126d554a | e9126d554a].
FossilOrigin-Name: d15fb0f75e64bbfdb8df0c0d0358aafbbd7d5e2048df676dafe1abd5e9917f2a
2024-11-14 14:38:16 +00:00
stephan
f154cef8f2 Document the if block at the end of sqlite-check-tcl.
FossilOrigin-Name: 6bfd09408b9a51c0cbdb28f901a79c9774da755294d7eb67d88e4c42c5652830
2024-11-14 12:23:05 +00:00
stephan
3b56698541 configure: avoid performing multiple checks for -lm on behalf of --enable-fts4 and --enable-fts5.
FossilOrigin-Name: 6940caa192fa0cc84dbd24191a940aec96c304c68e60ead8f239e85d093e01e0
2024-11-14 12:09:09 +00:00
drh
104ab7e81f Enhance the vfstrace.c extension to show symbolic names for the various
SHM locks.

FossilOrigin-Name: c0dd7de8f1e8eb745a8beff086d8b40b289c2dd75fe099a86ccc2bd0581f5e9a
2024-11-13 18:23:18 +00:00
drh
26c080a04b Fix a memory leak in the ".dump" command of the CLI that can occur if an
error other than database corruption is seen while trying to query the
database.

FossilOrigin-Name: 2560cc7072c923f534a5de1e15d2b0dd4ac5faf0a8876d9e3bf9804345585444
2024-11-13 18:04:49 +00:00
drh
31c160ab8f Add the test/fork-test.c test program.
FossilOrigin-Name: 0611e2b0cf3f33c28cc9ff6c5da7ebba2033bcbda5b1072a30021a3e1fb4e738
2024-11-13 16:08:02 +00:00
drh
1b37bc0e66 Add the SQLITE_FCNTL_NULL_IO file-control.
FossilOrigin-Name: f0e917fcf51b59f8ccfe5b9341937341d0e6016eb275d6c33dcb10b0b301a9da
2024-11-13 14:58:35 +00:00
drh
92e9fa6fe8 Ensure that the sqlite3_index_info.idxStr string coming back from FTS5
is always zero-terminated, even if the xBestIndex call fails with an
SQLITE_CONSTRAINT error.

FossilOrigin-Name: a4e976a030851357049e672bbc0ff66d9cc152b3d5f8e03fff36a7c6f060a755
2024-11-12 13:37:00 +00:00
drh
7b32f84ebf Clarify the documentation to make it clear that rows inserted by a
CREATE TABLE AS SELECT statement are not counted by sqlite3_count64().
[forum:/forumpost/1e6cde5648|Forum post 1e6cde5648].

FossilOrigin-Name: 5c5982e3937acdcda43d6c5b46a95b82bc1839c3558a4b9ae9022384e0f13f04
2024-11-11 21:11:02 +00:00
dan
0cd2ffffb7 Fix the fts5 trigram tokenizer so that it handles non-nul-terminated strings.
FossilOrigin-Name: 84f4e37178a65e3128ac0240d37ac40df08b4050ab070d10707e35d11dcbeb10
2024-11-11 19:49:26 +00:00
drh
be46f935dc Add the ".dbtotxt" command to the CLI.
FossilOrigin-Name: b43acf5a8cd4a5efbb90b71af7710084f49bb90ffe4f56de168e8c3a6b679124
2024-11-11 19:07:58 +00:00
stephan
074cad3026 Wrap some exceptionally long lines in main.mk. Add option to override LDFLAGS on the sqlite3.dll target. Audit: all targets for which it is hypothetically relevant can now inherit user-supplied LDFLAGS, but only those provided to the configure script, not at make-time, in order to mimic the historical build's restriction in that regard.
FossilOrigin-Name: 073080cae3ea0d12b133d9c9ae98413bb32870a9738c98b89bc345181be81f23
2024-11-11 18:15:50 +00:00
drh
e4d4d73397 Use Win32 APIs to read/write the console in Windows unless the
SQLITE_USE_STDIO_FOR_CONSOLE option is defined.  This is an attempt to get
the build working on MinGW.

FossilOrigin-Name: abfe488ed67e2e3510c230e656ecf203afa549ebd1d1872442f1fadc97d0817e
2024-11-11 17:02:29 +00:00
25 changed files with 1192 additions and 425 deletions

@ -153,7 +153,8 @@ LDFLAGS.dlopen = @LDFLAGS_DLOPEN@
LDFLAGS.readline = @LDFLAGS_READLINE@
CFLAGS.readline = @CFLAGS_READLINE@
LDFLAGS.icu = @LDFLAGS_ICU@
LDFLAGS.soname.libsqlite3 = @LDFLAGS_SONAME_LIBSQLITE3@
CFLAGS.icu = @CFLAGS_ICU@
LDFLAGS.libsqlite3.soname = @LDFLAGS_LIBSQLITE3_SONAME@
ENABLE_SHARED = @ENABLE_SHARED@
ENABLE_STATIC = @ENABLE_STATIC@
HAVE_WASI_SDK = @HAVE_WASI_SDK@
@ -168,11 +169,6 @@ T.cc.sqlite = $(T.cc) @TARGET_DEBUG@
# all builds.
#
T.cc.sqlite += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite
#
# -I$(prefix)/include is primarily so that the ICU
# headers can be found.
#
T.cc.sqlite += -I$(prefix)/include
#
# $(JIMSH) and $(CFLAGS.jimsh) are documented in main.mk. $(JIMSH)
@ -308,7 +304,7 @@ sqlite3.pc: $(TOP)/sqlite3.pc.in $(AS_AUTO_DEF)
@touch $@
install: install-pc # defined in main.mk
sqlite_cfg.h: $(TOP)/sqlite_cfg.h.in $(AS_AUTO_DEF)
sqlite_cfg.h: $(AS_AUTO_DEF)
$(AS_AUTORECONFIG)
@touch $@

221
auto.def

@ -12,7 +12,7 @@
#
# JimTCL: https://jim.tcl.tk
#
use cc cc-db cc-shared cc-lib proj
use cc cc-db cc-shared cc-lib proj pkg-config
# $DUMP_DEFINES_TXT is the file emitted by --dump-defines, intended
# only for build debugging and not part of the public build interface.
@ -182,7 +182,9 @@ set flags {
# <icu>
with-icu-ldflags:LDFLAGS
=> {Enable SQLITE_ENABLE_ICU and add the given linker flags for the ICU libraries}
with-icu-config:=auto => {Enable SQLITE_ENABLE_ICU and fetch linker flags from the given icu-config binary}
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>
@ -194,13 +196,9 @@ set flags {
test-status => {Enable status of tests}
gcov=0 => {Enable coverage testing using gcov}
linemacros => {Enable #line macros in the amalgamation}
dev => {Enable dev-mode build: automatically enables certain other flags}
dump-defines=0 => {Dump autosetup defines to $DUMP_DEFINES_TXT (for build debugging)}
#soname:=none => {SONAME for libsqlite3.so}
#^^^ we "could", but arguably shouldn't, support clients passing a
# value of libsqlite3.so.0 for compatibility with clients which
# linked against a pre-3.48 build.
# Maybe we should support values of --soname=(none,auto,legacy), where auto means
# to use the 3.48+ value of libsqlite3.so.3..
soname:=legacy => {SONAME for libsqlite3.so. Must be one of: none, auto, legacy}
# </developer>
}
if {"" ne $DUMP_DEFINES_JSON} {
@ -232,7 +230,7 @@ msg-result "Source dir = $srcdir"
msg-result "Build dir = $::autosetup(builddir)"
msg-result "Configuring SQLite version $PACKAGE_VERSION"
if {1} {
apply {{} {
#
# SQLITE_AUTORECONFIG contains make target rules for re-running the
# configure script with the same arguments it was initially invoked
@ -245,13 +243,13 @@ if {1} {
if {[string match {*[ &;$*"]*} $arg]} { return '$arg' }
return $arg
}
define-append SQLITE_AUTORECONFIG cd [squote $::autosetup(builddir)] && [squote $srcdir/configure]
define-append SQLITE_AUTORECONFIG cd [squote $::autosetup(builddir)] && [squote $::srcdir/configure]
#{*}$::autosetup(argv) breaks with --flag='val with spaces', so...
foreach arg $::autosetup(argv) {
define-append SQLITE_AUTORECONFIG [squote $arg]
}
rename squote ""
}
}}
# Are we cross-compiling?
set isCrossCompiling [proj-is-cross-compiling]
@ -319,10 +317,20 @@ if {"" eq [proj-bin-define install]} {
define CFLAGS [proj-get-env CFLAGS {-g -O2}]
define BUILD_CFLAGS [proj-get-env BUILD_CFLAGS {-g}]
proj-if-opt-truthy dev {
# --enable-dev needs to come early so that the downstream tests
# which check for these flags will show the user their updated
# state.
proj-opt-set all 1
proj-opt-set with-debug 1
proj-opt-set amalgamation 0
define CFLAGS [get-env CFLAGS {-O0 -g}]
}
########################################################################
# Handle --with-wasi-sdk=DIR
#
# This MUST be run early on because it may change the toolchain and
# This must be run early on because it may change the toolchain and
# disable a number of config options.
proc sqlite-check-wasi-sdk {} {
set wasiSdkDir [opt-val with-wasi-sdk] ; # ??? [lindex [opt-val with-wasi-sdk] end]
@ -340,7 +348,7 @@ proc sqlite-check-wasi-sdk {} {
# Disable numerous options which we know either can't work or are
# not useful in this build...
msg-result "Using wasi-sdk clang. Disabling CLI shell modifying config flags:"
# Boolean flags which must be switched off:
# Boolean (--enable-/--disable-) flags which must be switched off:
foreach opt {
editline
gcov
@ -361,6 +369,7 @@ proc sqlite-check-wasi-sdk {} {
with-emsdk
with-icu-config
with-icu-ldflags
with-icu-cflags
with-linenoise
with-tcl
} {
@ -438,36 +447,49 @@ proj-check-rpath ; # Determine proper rpath-handling flag
# It's not yet clear whether we gain anything from setting -soname,
# but not having it has been a source of anxiety for some users.
# Setting it to any value other than its historical value of
# libsqlite3.so.0 may (this is not certain) break dynamic linking of
# clients which initially linked against a legacy build.
# libsqlite3.so.0 may break dynamic linking of clients which initially
# linked against a legacy build (with its SONAME of libsqlite3.so.0).
#
# To be clear: the ABI has not changed between pre-3.48 and post-3.47
# builds, but version number 0 (pre-3.48) was a historical remnant
# from libtool which "should" have always been version number 3 but
# was not, for reasons lost to history.
#
# If the goal is to reduce downstream disruption then we need to
# retain the SONAME libsqlite3.so.0. If the goal is to "pull the
# bandaid off" then switching libsqlite3.so.3 is arguably the right
# thing to do (at the very real risk of causing a fair amount of
# downstream disruption for package maintainers).
#
# See discussion in/around:
# https://sqlite.org/forum/forumpost/0c6fc6f46b2cb3
proc sqlite-check-soname {} {
define LDFLAGS_SONAME_LIBSQLITE3 ""
apply {{} {
define LDFLAGS_LIBSQLITE3_SONAME ""
if {[proj-opt-was-provided soname]} {
set soname [opt-val soname]
} else {
return 0
set soname legacy
}
switch -exact -- $soname {
none { return 0 }
auto - 3 { set soname libsqlite3.so.3 }
legacy - 0 { set soname libsqlite3.so.0 }
none { return 0 }
auto { set soname libsqlite3.so.3 }
legacy { set soname libsqlite3.so.0 }
default {
proj-fatal "Invalid value for --soname. Use one of (none, auto, legacy)."
}
}
msg-debug "soname=$soname"
if {[proj-check-soname $soname]} {
define LDFLAGS_SONAME_LIBSQLITE3 [get-define LDFLAGS_SONAME_PREFIX]$soname
msg-result "Setting SONAME: [get-define LDFLAGS_SONAME_LIBSQLITE3]"
} else {
define LDFLAGS_LIBSQLITE3_SONAME [get-define LDFLAGS_SONAME_PREFIX]$soname
msg-result "Setting SONAME: [get-define LDFLAGS_LIBSQLITE3_SONAME]"
} elseif {[proj-opt-was-provided soname]} {
# --soname was explicitly requested but not available, so fail fatally
proj-fatal "This environment does not support SONAME."
} else {
msg-result "This environment does not support SONAME."
}
return sqlite-check-soname ""
}
sqlite-check-soname
}}
proj-define-for-opt shared ENABLE_SHARED "Build shared library?"
@ -630,7 +652,7 @@ proc sqlite-check-tcl {} {
# Export a subset of tclConfig.sh to the current TCL-space. If $cfg
# is an empty string, this emits empty-string entries for the
# various options we're interested in.
eval [exec "${srcdir}/tool/tclConfigShToTcl.sh" "$cfg"]
eval [exec "${srcdir}/tool/tclConfigShToAutoDef.sh" "$cfg"]
if {"" eq $with_tclsh && $cfg ne ""} {
# We have tclConfig.sh but no tclsh. Attempt to locate a tclsh
@ -686,6 +708,10 @@ proc sqlite-check-tcl {} {
}
}
show-notices
# If TCL is not found: if it was explicitly requested then fail
# fatally, else just emit a warning. If we can find the APIs needed
# to generate a working JimTCL then that will suffice for build-time
# TCL purposes (see: proc sqlite-determine-codegen-tcl).
if {![get-define HAVE_TCL] &&
([proj-opt-was-provided tcl] || [proj-opt-was-provided with-tcl])} {
proj-fatal "TCL support was requested but no tclConfig.sh could be found."
@ -700,7 +726,6 @@ proc sqlite-check-tcl {} {
}
}
}; # sqlite-check-tcl
sqlite-check-tcl
########################################################################
@ -718,7 +743,7 @@ sqlite-check-tcl
# to an unexpanded makefile var name.
#
# - CFLAGS_JIMSH = any flags needed for buildng a BTCLSH-compatible
# jimsh. The defaults may be pass on to configure as
# jimsh. The defaults may be passed on to configure as
# CFLAGS_JIMSH=...
set useJimForCodeGen 0 ; # Set to 1 when using jimsh for code generation.
# May affect later decisions.
@ -818,7 +843,7 @@ proj-if-opt-truthy threadsafe {
########################################################################
# Do we want temporary databases in memory?
#
if {1} {
apply {{} {
set ts [opt-val with-tempstore no]
set tsn 1
msg-checking "Use an in-RAM database for temporary tables? "
@ -833,8 +858,7 @@ if {1} {
}
msg-result $ts
define TEMP_STORE $tsn
unset ts tsn
}
}}
########################################################################
# sqlite-check-line-editing jumps through proverbial hoops to try to
@ -1108,47 +1132,85 @@ proj-if-opt-truthy math {
# Handles these flags:
#
# --with-icu-ldflags=LDFLAGS
# --with-icu-config[=/path/to/icu-config]
# --with-icu-cflags=CFLAGS
# --with-icu-config[=auto | pkg-config | /path/to/icu-config]
# --enable-icu-collations
#
# If both icu-ldflags and 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.
# --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 can automatically enable ICU if the
# icu-config binary is found, we specifically do not. ICU is always an
# opt-in feature.
# icu-config binary or (pkg-config icu-io) are found, we specifically
# do not. ICU is always an opt-in feature.
#
# Maintenance reminder: check-in 09caa94c9e84 added pkg-config support
# to this but the result fails to link on both Linux and OpenBSD
# (other systems were untested) because the pkg-config results are
# missing a required library.
proc sqlite-check-icu {} {
define LDFLAGS_ICU [join [opt-val with-icu-ldflags ""]]
define CFLAGS_ICU [join [opt-val with-icu-cflags ""]]
# Flags sets seen in the wild for ICU:
# - -licui18n -licuuc -licudata
# - -licui18n -licuuc
# - /usr/local/bin/icu-config --ldflags
#
if {[proj-opt-was-provided with-icu-config]} {
set bin [opt-val with-icu-config]
if {"auto" eq $bin} {
set bin [proj-first-bin-of \
[get-define prefix]/bin/icu-config \
/usr/local/bin/icu-config \
/usr/bin/icu-config]
if {"" eq $bin} {
proj-fatal "--with-icu-config=auto cannot find icu-config binary"
set icuConfigBin [opt-val with-icu-config]
set tryIcuConfigBin 1; # set to 0 if we end up using pkg-config
if {"auto" eq $icuConfigBin || "pkg-config" eq $icuConfigBin} {
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_ICU [get-define PKG_ICU_IO_LDFLAGS]
define-append LDFLAGS_ICU [get-define PKG_ICU_IO_LIBS]
define CFLAGS_ICU [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 {[file-isexec $bin]} {
set x [exec $bin --ldflags]
if {"" eq $x} {
proj-fatal "$bin --ldflags returned no data"
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-fatal "--with-icu-config=auto cannot find (pkg-config icu-io) or icu-config binary"
}
}
if {[file-isexec $icuConfigBin]} {
set x [exec $icuConfigBin --ldflags]
if {"" eq $x} {
proj-fatal "$icuConfigBin --ldflags returned no data"
}
define-append LDFLAGS_ICU $x
set x [exec $icuConfigBin --cppflags]
define-append CFLAGS_ICU $x
} else {
proj-fatal "--with-icu-config=$bin does not refer to an executable"
}
define-append LDFLAGS_ICU $x
} else {
proj-fatal "--with-icu-config=$bin does not refer to an executable"
}
}
set flags [define LDFLAGS_ICU [string trim [get-define LDFLAGS_ICU]]]
if {"" ne $flags} {
set ldflags [define LDFLAGS_ICU [string trim [get-define LDFLAGS_ICU]]]
set cflags [define CFLAGS_ICU [string trim [get-define CFLAGS_ICU]]]
if {"" ne $ldflags} {
sqlite-add-feature-flag -shell -DSQLITE_ENABLE_ICU
msg-result "Enabling ICU support with libs: $flags"
msg-result "Enabling ICU support with flags: $ldflags $cflags"
if {[opt-bool icu-collations]} {
msg-result "Enabling ICU collations."
sqlite-add-feature-flag -shell -DSQLITE_ENABLE_ICU_COLLATIONS
@ -1163,9 +1225,9 @@ proc sqlite-check-icu {} {
sqlite-check-icu
########################################################################
# Emscripten SDK for building the web-based wasm components.
#
proc sqlite-check-emsdk {} {
# Check for the Emscripten SDK for building the web-based wasm
# components.
apply {{} {
set emccsh $::srcdir/tool/emcc.sh
if {![get-define HAVE_WASI_SDK] && [proj-check-emsdk]} {
define EMCC_WRAPPER $emccsh
@ -1175,8 +1237,7 @@ proc sqlite-check-emsdk {} {
define EMCC_WRAPPER ""
file delete -force $emccsh
}
}
sqlite-check-emsdk
}}
########################################################################
# Check for log(3) in libm and die with an error if it is not
@ -1185,11 +1246,13 @@ sqlite-check-emsdk
# the required linker flags (which may be empty even if the math APIs
# are found, depending on the OS).
proc affirm-have-math {featureName} {
if {![msg-quiet proj-check-function-in-lib log m]} {
user-error "Missing math APIs for $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
}
define LDFLAGS_MATH [get-define lib_log ""]
undefine lib_log
}
########################################################################
@ -1197,6 +1260,7 @@ proc affirm-have-math {featureName} {
msg-result "Feature flags..."
foreach {boolFlag featureFlag ifSetEvalThis} {
all {} {
# The 'all' option must be first in this list.
proj-opt-set fts4
proj-opt-set fts5
proj-opt-set geopoly
@ -1249,7 +1313,7 @@ foreach {boolFlag featureFlag} {
#########################################################################
# Show the final feature flag sets:
if {1} {
apply {{} {
set oFF [get-define OPT_FEATURE_FLAGS]
if {"" ne $oFF} {
define OPT_FEATURE_FLAGS [lsort -unique $oFF]
@ -1261,7 +1325,7 @@ if {1} {
msg-result "Shell options: [get-define OPT_SHELL]"
}
unset oFF
}
}}
########################################################################
# "Re-export" the autoconf-conventional --XYZdir flags into something
@ -1280,20 +1344,13 @@ proj-remap-autoconf-dir-vars
# Potential TODO (unclear): in sqlite3.pc.in, do we need to include
# any CFLAGS_READLINE, CFLAGS_ZLIB, etc in its "Cflags:" section?
proj-make-from-dot-in -touch Makefile sqlite3.pc
if {0} {
# Requires a hand-written sqlite_cfg.h.in...
proj-make-from-dot-in sqlite_cfg.h
# vs...
} else {
# Requires no input template...
make-config-header sqlite_cfg.h \
-bare {SIZEOF_* HAVE_DECL_*} \
-none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTORECONFIG
TARGET_* USE_GCOV TCL_*} \
-auto {HAVE_* PACKAGE_*} \
-none *
proj-touch sqlite_cfg.h ; # help avoid frequent unnecessary @SQLITE_AUTORECONFIG@
}
make-config-header sqlite_cfg.h \
-bare {SIZEOF_* HAVE_DECL_*} \
-none {HAVE_CFLAG_* LDFLAGS_* SH_* SQLITE_AUTORECONFIG
TARGET_* USE_GCOV TCL_*} \
-auto {HAVE_* PACKAGE_*} \
-none *
proj-touch sqlite_cfg.h ; # help avoid frequent unnecessary @SQLITE_AUTORECONFIG@
########################################################################
# Some build-dev/debug-only output

@ -85,8 +85,7 @@ proc proj-assert {script {descr ""}} {
if {1 == [get-env proj-assert 0]} {
msg-result [proj-bold "asserting: $script"]
}
set x {expr }
append x \{ $script \}
set x "expr \{ $script \}"
if {![uplevel 1 $x]} {
if {"" eq $descr} {
set descr $script
@ -947,7 +946,7 @@ proc proj-check-rpath {} {
#
# Checks whether CC supports the -Wl,soname,lib... flag. If so, it
# returns 1 and defines LDFLAGS_SONAME_PREFIX to the flag's prefix, to
# which the client would need to append "libwhatever.N". If not, it
# which the client would need to append "libwhatever.N". If not, it
# returns 0 and defines LDFLAGS_SONAME_PREFIX to an empty string.
#
# The libname argument is only for purposes of running the flag
@ -1207,10 +1206,9 @@ proc proj-which-linenoise {dotH} {
proc proj-remap-autoconf-dir-vars {} {
set prefix [get-define prefix]
set exec_prefix [get-define exec_prefix $prefix]
# Note that the ${...} here refers to make-side var derefs, not
# TCL-side vars. They must be formulated such that they are legal
# for use in (A) makefiles, (B) pkgconfig files, and (C) TCL's
# [subst] command. i.e. they must use the form ${X}.
# The following var derefs must be formulated such that they are
# legal for use in (A) makefiles, (B) pkgconfig files, and (C) TCL's
# [subst] command. i.e. they must use the form ${X}.
foreach {flag makeVar makeDeref} {
exec-prefix exec_prefix ${prefix}
datadir datadir ${prefix}/share

@ -632,6 +632,7 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
if( p->usable==0 || iCol<0 ){
/* As there exists an unusable MATCH constraint this is an
** unusable plan. Return SQLITE_CONSTRAINT. */
idxStr[iIdxStr] = 0;
return SQLITE_CONSTRAINT;
}else{
if( iCol==nCol+1 ){

@ -730,8 +730,9 @@ static int SQLITE_TCLAPI f5tTokenize(
int objc,
Tcl_Obj *CONST objv[]
){
char *zText;
Tcl_Size nText;
char *pCopy = 0;
char *zText = 0;
Tcl_Size nText = 0;
sqlite3 *db = 0;
fts5_api *pApi = 0;
Fts5Tokenizer *pTok = 0;
@ -778,22 +779,33 @@ static int SQLITE_TCLAPI f5tTokenize(
return TCL_ERROR;
}
if( nText>0 ){
pCopy = sqlite3_malloc(nText);
if( pCopy==0 ){
tokenizer.xDelete(pTok);
Tcl_AppendResult(interp, "error in sqlite3_malloc()", (char*)0);
return TCL_ERROR;
}else{
memcpy(pCopy, zText, nText);
}
}
pRet = Tcl_NewObj();
Tcl_IncrRefCount(pRet);
ctx.bSubst = (objc==5);
ctx.pRet = pRet;
ctx.zInput = zText;
ctx.zInput = pCopy;
rc = tokenizer.xTokenize(
pTok, (void*)&ctx, FTS5_TOKENIZE_DOCUMENT, zText,(int)nText, xTokenizeCb2
pTok, (void*)&ctx, FTS5_TOKENIZE_DOCUMENT, pCopy,(int)nText, xTokenizeCb2
);
tokenizer.xDelete(pTok);
sqlite3_free(pCopy);
if( rc!=SQLITE_OK ){
Tcl_AppendResult(interp, "error in tokenizer.xTokenize()", (char*)0);
Tcl_DecrRefCount(pRet);
return TCL_ERROR;
}
Tcl_Free((void*)azArg);
Tcl_SetObjResult(interp, pRet);
Tcl_DecrRefCount(pRet);

@ -1354,7 +1354,7 @@ static int fts5TriTokenize(
int ii;
const unsigned char *zIn = (const unsigned char*)pText;
const unsigned char *zEof = &zIn[nText];
u32 iCode;
u32 iCode = 0;
int aStart[3]; /* Input offset of each character in aBuf[] */
UNUSED_PARAM(unusedFlags);
@ -1363,8 +1363,8 @@ static int fts5TriTokenize(
for(ii=0; ii<3; ii++){
do {
aStart[ii] = zIn - (const unsigned char*)pText;
if( zIn>=zEof ) return SQLITE_OK;
READ_UTF8(zIn, zEof, iCode);
if( iCode==0 ) return SQLITE_OK;
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam);
}while( iCode==0 );
WRITE_UTF8(zOut, iCode);
@ -1385,8 +1385,11 @@ static int fts5TriTokenize(
/* Read characters from the input up until the first non-diacritic */
do {
iNext = zIn - (const unsigned char*)pText;
if( zIn>=zEof ){
iCode = 0;
break;
}
READ_UTF8(zIn, zEof, iCode);
if( iCode==0 ) break;
if( p->bFold ) iCode = sqlite3Fts5UnicodeFold(iCode, p->iFoldParam);
}while( iCode==0 );

@ -350,5 +350,17 @@ do_execsql_test 11.1 {
INSERT INTO t4 VALUES( str('') );
}
do_test 12.0 {
sqlite3_fts5_tokenize db trigram "abcd"
} {abc 0 3 bcd 1 4}
do_test 12.1 {
sqlite3_fts5_tokenize db trigram "a"
} {}
do_test 12.2 {
sqlite3_fts5_tokenize db trigram ""
} {}
finish_test

@ -148,10 +148,20 @@ char *sqlite3_fgets(char *buf, int sz, FILE *in){
*/
wchar_t *b1 = sqlite3_malloc( sz*sizeof(wchar_t) );
if( b1==0 ) return 0;
_setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT);
if( fgetws(b1, sz/4, in)==0 ){
sqlite3_free(b1);
return 0;
#ifndef SQLITE_USE_STDIO_FOR_CONSOLE
DWORD nRead = 0;
if( IsConsole(in)
&& ReadConsoleW(GetStdHandle(STD_INPUT_HANDLE), b1, sz, &nRead, 0)
){
b1[nRead] = 0;
}else
#endif
{
_setmode(_fileno(in), IsConsole(in) ? _O_WTEXT : _O_U8TEXT);
if( fgetws(b1, sz/4, in)==0 ){
sqlite3_free(b1);
return 0;
}
}
WideCharToMultiByte(CP_UTF8, 0, b1, -1, buf, sz, 0, 0);
sqlite3_free(b1);
@ -207,20 +217,33 @@ int sqlite3_fputs(const char *z, FILE *out){
** any translation. */
return fputs(z, out);
}else{
/* When writing to the command-prompt in Windows, it is necessary
** to use O_U8TEXT to render Unicode U+0080 and greater. Go ahead
** use O_U8TEXT for everything in text mode.
/* One must use UTF16 in order to get unicode support when writing
** to the console on Windows.
*/
int sz = (int)strlen(z);
wchar_t *b1 = sqlite3_malloc( (sz+1)*sizeof(wchar_t) );
if( b1==0 ) return 0;
sz = MultiByteToWideChar(CP_UTF8, 0, z, sz, b1, sz);
b1[sz] = 0;
_setmode(_fileno(out), _O_U8TEXT);
if( UseBinaryWText(out) ){
piecemealOutput(b1, sz, out);
}else{
fputws(b1, out);
#ifndef SQLITE_STDIO_FOR_CONSOLE
DWORD nWr = 0;
if( IsConsole(out)
&& WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),b1,sz,&nWr,0)
){
/* If writing to the console, then the WriteConsoleW() is all we
** need to do. */
}else
#endif
{
/* For non-console I/O, or if SQLITE_USE_STDIO_FOR_CONSOLE is defined
** then write using the standard library. */
_setmode(_fileno(out), _O_U8TEXT);
if( UseBinaryWText(out) ){
piecemealOutput(b1, sz, out);
}else{
fputws(b1, out);
}
}
sqlite3_free(b1);
return 0;

@ -105,7 +105,27 @@
** invariants are (1) you must have -DSQLITE_ENABLE_VFSTRACE so that
** the shell.c source file will know to include the -vfstrace command-line
** option and (2) you must compile and link the three source files
** shell,c, test_vfstrace.c, and sqlite3.c.
** shell,c, test_vfstrace.c, and sqlite3.c.
**
** RUNTIME CONTROL OF VFSTRACE OUTPUT
**
** The application can use the "vfstrace" pragma to control which VFS
** APIs are traced. To disable all output:
**
** PRAGMA vfstrace('-all');
**
** To enable all output (which is the default setting):
**
** PRAGMA vfstrace('+all');
**
** Individual APIs can be enabled or disabled by name, with or without
** the initial "x" character. For example, to set up for tracing lock
** primatives only:
**
** PRAGMA vfstrace('-all, +Lock,Unlock,ShmLock');
**
** The argument to the vfstrace pragma ignores capitalization and any
** characters other than alphabetics, '+', and '-'.
*/
#include <stdlib.h>
#include <string.h>
@ -119,6 +139,8 @@ typedef struct vfstrace_info vfstrace_info;
struct vfstrace_info {
sqlite3_vfs *pRootVfs; /* The underlying real VFS */
int (*xOut)(const char*, void*); /* Send output here */
unsigned int mTrace; /* Mask of interfaces to trace */
u8 bOn; /* Tracing on/off */
void *pOutArg; /* First argument to xOut */
const char *zVfsName; /* Name of this trace-VFS */
sqlite3_vfs *pTraceVfs; /* Pointer back to the trace VFS */
@ -135,6 +157,38 @@ struct vfstrace_file {
sqlite3_file *pReal; /* The real underlying file */
};
/*
** Bit values for vfstrace_info.mTrace.
*/
#define VTR_CLOSE 0x00000001
#define VTR_READ 0x00000002
#define VTR_WRITE 0x00000004
#define VTR_TRUNC 0x00000008
#define VTR_SYNC 0x00000010
#define VTR_FSIZE 0x00000020
#define VTR_LOCK 0x00000040
#define VTR_UNLOCK 0x00000080
#define VTR_CRL 0x00000100
#define VTR_FCTRL 0x00000200
#define VTR_SECSZ 0x00000400
#define VTR_DEVCHAR 0x00000800
#define VTR_SHMLOCK 0x00001000
#define VTR_SHMMAP 0x00002000
#define VTR_SHMBAR 0x00004000
#define VTR_SHMUNMAP 0x00008000
#define VTR_OPEN 0x00010000
#define VTR_DELETE 0x00020000
#define VTR_ACCESS 0x00040000
#define VTR_FULLPATH 0x00080000
#define VTR_DLOPEN 0x00100000
#define VTR_DLERR 0x00200000
#define VTR_DLSYM 0x00400000
#define VTR_DLCLOSE 0x00800000
#define VTR_RAND 0x01000000
#define VTR_SLEEP 0x02000000
#define VTR_CURTIME 0x04000000
#define VTR_LASTERR 0x08000000
/*
** Method declarations for vfstrace_file.
*/
@ -199,11 +253,13 @@ static void vfstrace_printf(
){
va_list ap;
char *zMsg;
va_start(ap, zFormat);
zMsg = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
pInfo->xOut(zMsg, pInfo->pOutArg);
sqlite3_free(zMsg);
if( pInfo->bOn ){
va_start(ap, zFormat);
zMsg = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
pInfo->xOut(zMsg, pInfo->pOutArg);
sqlite3_free(zMsg);
}
}
/*
@ -302,6 +358,13 @@ static void strappend(char *z, int *pI, const char *zAppend){
*pI = i;
}
/*
** Turn tracing output on or off according to mMask.
*/
static void vfstraceOnOff(vfstrace_info *pInfo, unsigned int mMask){
pInfo->bOn = (pInfo->mTrace & mMask)!=0;
}
/*
** Close an vfstrace-file.
*/
@ -309,6 +372,7 @@ static int vfstraceClose(sqlite3_file *pFile){
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
int rc;
vfstraceOnOff(pInfo, VTR_CLOSE);
vfstrace_printf(pInfo, "%s.xClose(%s)", pInfo->zVfsName, p->zFName);
rc = p->pReal->pMethods->xClose(p->pReal);
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
@ -331,6 +395,7 @@ static int vfstraceRead(
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
int rc;
vfstraceOnOff(pInfo, VTR_READ);
vfstrace_printf(pInfo, "%s.xRead(%s,n=%d,ofst=%lld)",
pInfo->zVfsName, p->zFName, iAmt, iOfst);
rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
@ -350,6 +415,7 @@ static int vfstraceWrite(
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
int rc;
vfstraceOnOff(pInfo, VTR_WRITE);
vfstrace_printf(pInfo, "%s.xWrite(%s,n=%d,ofst=%lld)",
pInfo->zVfsName, p->zFName, iAmt, iOfst);
rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
@ -364,6 +430,7 @@ static int vfstraceTruncate(sqlite3_file *pFile, sqlite_int64 size){
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
int rc;
vfstraceOnOff(pInfo, VTR_TRUNC);
vfstrace_printf(pInfo, "%s.xTruncate(%s,%lld)", pInfo->zVfsName, p->zFName,
size);
rc = p->pReal->pMethods->xTruncate(p->pReal, size);
@ -388,6 +455,7 @@ static int vfstraceSync(sqlite3_file *pFile, int flags){
if( flags & ~(SQLITE_SYNC_FULL|SQLITE_SYNC_DATAONLY) ){
sqlite3_snprintf(sizeof(zBuf)-i, &zBuf[i], "|0x%x", flags);
}
vfstraceOnOff(pInfo, VTR_SYNC);
vfstrace_printf(pInfo, "%s.xSync(%s,%s)", pInfo->zVfsName, p->zFName,
&zBuf[1]);
rc = p->pReal->pMethods->xSync(p->pReal, flags);
@ -402,6 +470,7 @@ static int vfstraceFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
int rc;
vfstraceOnOff(pInfo, VTR_FSIZE);
vfstrace_printf(pInfo, "%s.xFileSize(%s)", pInfo->zVfsName, p->zFName);
rc = p->pReal->pMethods->xFileSize(p->pReal, pSize);
vfstrace_print_errcode(pInfo, " -> %s,", rc);
@ -430,6 +499,7 @@ static int vfstraceLock(sqlite3_file *pFile, int eLock){
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
int rc;
vfstraceOnOff(pInfo, VTR_LOCK);
vfstrace_printf(pInfo, "%s.xLock(%s,%s)", pInfo->zVfsName, p->zFName,
lockName(eLock));
rc = p->pReal->pMethods->xLock(p->pReal, eLock);
@ -444,6 +514,7 @@ static int vfstraceUnlock(sqlite3_file *pFile, int eLock){
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
int rc;
vfstraceOnOff(pInfo, VTR_UNLOCK);
vfstrace_printf(pInfo, "%s.xUnlock(%s,%s)", pInfo->zVfsName, p->zFName,
lockName(eLock));
rc = p->pReal->pMethods->xUnlock(p->pReal, eLock);
@ -458,6 +529,7 @@ static int vfstraceCheckReservedLock(sqlite3_file *pFile, int *pResOut){
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
int rc;
vfstraceOnOff(pInfo, VTR_CRL);
vfstrace_printf(pInfo, "%s.xCheckReservedLock(%s,%d)",
pInfo->zVfsName, p->zFName);
rc = p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
@ -477,6 +549,7 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){
char zBuf2[100];
char *zOp;
char *zRVal = 0;
vfstraceOnOff(pInfo, VTR_FCTRL);
switch( op ){
case SQLITE_FCNTL_LOCKSTATE: zOp = "LOCKSTATE"; break;
case SQLITE_GET_LOCKPROXYFILE: zOp = "GET_LOCKPROXYFILE"; break;
@ -505,6 +578,79 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){
case SQLITE_FCNTL_POWERSAFE_OVERWRITE: zOp = "POWERSAFE_OVERWRITE"; break;
case SQLITE_FCNTL_PRAGMA: {
const char *const* a = (const char*const*)pArg;
if( a[1] && strcmp(a[1],"vfstrace")==0 && a[2] ){
const u8 *zArg = (const u8*)a[2];
if( zArg[0]>='0' && zArg[0]<=9 ){
pInfo->mTrace = (sqlite3_uint64)strtoll(a[2], 0, 0);
}else{
static const struct {
const char *z;
unsigned int m;
} aKw[] = {
{ "all", 0xffffffff },
{ "close", VTR_CLOSE },
{ "read", VTR_READ },
{ "write", VTR_WRITE },
{ "truncate", VTR_TRUNC },
{ "sync", VTR_SYNC },
{ "filesize", VTR_FSIZE },
{ "lock", VTR_LOCK },
{ "unlock", VTR_UNLOCK },
{ "checkreservedlock", VTR_CRL },
{ "filecontrol", VTR_FCTRL },
{ "sectorsize", VTR_SECSZ },
{ "devicecharacteristics", VTR_DEVCHAR },
{ "shmlock", VTR_SHMLOCK },
{ "shmmap", VTR_SHMMAP },
{ "shmummap", VTR_SHMUNMAP },
{ "shmbarrier", VTR_SHMBAR },
{ "open", VTR_OPEN },
{ "delete", VTR_DELETE },
{ "access", VTR_ACCESS },
{ "fullpathname", VTR_FULLPATH },
{ "dlopen", VTR_DLOPEN },
{ "dlerror", VTR_DLERR },
{ "dlsym", VTR_DLSYM },
{ "dlclose", VTR_DLCLOSE },
{ "randomness", VTR_RAND },
{ "sleep", VTR_SLEEP },
{ "currenttime", VTR_CURTIME },
{ "currenttimeint64", VTR_CURTIME },
{ "getlasterror", VTR_LASTERR },
};
int onOff = 1;
while( zArg[0] ){
int jj, n;
while( zArg[0]!=0 && zArg[0]!='-' && zArg[0]!='+'
&& !isalpha(zArg[0]) ) zArg++;
if( zArg[0]==0 ) break;
if( zArg[0]=='-' ){
onOff = 0;
zArg++;
}else if( zArg[0]=='+' ){
onOff = 1;
zArg++;
}
while( !isalpha(zArg[0]) ){
if( zArg[0]==0 ) break;
zArg++;
}
if( zArg[0]=='x' && isalpha(zArg[1]) ) zArg++;
for(n=0; isalpha(zArg[n]); n++){}
for(jj=0; jj<sizeof(aKw)/sizeof(aKw[0]); jj++){
if( sqlite3_strnicmp(aKw[jj].z,(const char*)zArg,n)==0 ){
if( onOff ){
pInfo->mTrace |= aKw[jj].m;
}else{
pInfo->mTrace &= ~aKw[jj].m;
}
break;
}
}
zArg += n;
}
}
}
sqlite3_snprintf(sizeof(zBuf), zBuf, "PRAGMA,[%s,%s]",a[1],a[2]);
zOp = zBuf;
break;
@ -600,6 +746,7 @@ static int vfstraceSectorSize(sqlite3_file *pFile){
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
int rc;
vfstraceOnOff(pInfo, VTR_SECSZ);
vfstrace_printf(pInfo, "%s.xSectorSize(%s)", pInfo->zVfsName, p->zFName);
rc = p->pReal->pMethods->xSectorSize(p->pReal);
vfstrace_printf(pInfo, " -> %d\n", rc);
@ -613,6 +760,7 @@ static int vfstraceDeviceCharacteristics(sqlite3_file *pFile){
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
int rc;
vfstraceOnOff(pInfo, VTR_DEVCHAR);
vfstrace_printf(pInfo, "%s.xDeviceCharacteristics(%s)",
pInfo->zVfsName, p->zFName);
rc = p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
@ -624,11 +772,22 @@ static int vfstraceDeviceCharacteristics(sqlite3_file *pFile){
** Shared-memory operations.
*/
static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
static const char *azLockName[] = {
"WRITE",
"CKPT",
"RECOVER",
"READ0",
"READ1",
"READ2",
"READ3",
"READ4",
};
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
int rc;
char zLck[100];
int i = 0;
vfstraceOnOff(pInfo, VTR_SHMLOCK);
memcpy(zLck, "|0", 3);
if( flags & SQLITE_SHM_UNLOCK ) strappend(zLck, &i, "|UNLOCK");
if( flags & SQLITE_SHM_LOCK ) strappend(zLck, &i, "|LOCK");
@ -637,8 +796,15 @@ static int vfstraceShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
if( flags & ~(0xf) ){
sqlite3_snprintf(sizeof(zLck)-i, &zLck[i], "|0x%x", flags);
}
vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d,n=%d,%s)",
pInfo->zVfsName, p->zFName, ofst, n, &zLck[1]);
if( ofst>=0 && ofst<sizeof(azLockName)/sizeof(azLockName[0]) ){
vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=%d(%s),n=%d,%s)",
pInfo->zVfsName, p->zFName, ofst, azLockName[ofst],
n, &zLck[1]);
}else{
vfstrace_printf(pInfo, "%s.xShmLock(%s,ofst=5d,n=%d,%s)",
pInfo->zVfsName, p->zFName, ofst,
n, &zLck[1]);
}
rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
vfstrace_print_errcode(pInfo, " -> %s\n", rc);
return rc;
@ -653,6 +819,7 @@ static int vfstraceShmMap(
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
int rc;
vfstraceOnOff(pInfo, VTR_SHMMAP);
vfstrace_printf(pInfo, "%s.xShmMap(%s,iRegion=%d,szRegion=%d,isWrite=%d,*)",
pInfo->zVfsName, p->zFName, iRegion, szRegion, isWrite);
rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
@ -662,6 +829,7 @@ static int vfstraceShmMap(
static void vfstraceShmBarrier(sqlite3_file *pFile){
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
vfstraceOnOff(pInfo, VTR_SHMBAR);
vfstrace_printf(pInfo, "%s.xShmBarrier(%s)\n", pInfo->zVfsName, p->zFName);
p->pReal->pMethods->xShmBarrier(p->pReal);
}
@ -669,6 +837,7 @@ static int vfstraceShmUnmap(sqlite3_file *pFile, int delFlag){
vfstrace_file *p = (vfstrace_file *)pFile;
vfstrace_info *pInfo = p->pInfo;
int rc;
vfstraceOnOff(pInfo, VTR_SHMUNMAP);
vfstrace_printf(pInfo, "%s.xShmUnmap(%s,delFlag=%d)",
pInfo->zVfsName, p->zFName, delFlag);
rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
@ -696,6 +865,7 @@ static int vfstraceOpen(
p->zFName = zName ? fileTail(zName) : "<temp>";
p->pReal = (sqlite3_file *)&p[1];
rc = pRoot->xOpen(pRoot, zName, p->pReal, flags, pOutFlags);
vfstraceOnOff(pInfo, VTR_OPEN);
vfstrace_printf(pInfo, "%s.xOpen(%s,flags=0x%x)",
pInfo->zVfsName, p->zFName, flags);
if( p->pReal->pMethods ){
@ -741,6 +911,7 @@ static int vfstraceDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
sqlite3_vfs *pRoot = pInfo->pRootVfs;
int rc;
vfstraceOnOff(pInfo, VTR_DELETE);
vfstrace_printf(pInfo, "%s.xDelete(\"%s\",%d)",
pInfo->zVfsName, zPath, dirSync);
rc = pRoot->xDelete(pRoot, zPath, dirSync);
@ -761,6 +932,7 @@ static int vfstraceAccess(
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
sqlite3_vfs *pRoot = pInfo->pRootVfs;
int rc;
vfstraceOnOff(pInfo, VTR_ACCESS);
vfstrace_printf(pInfo, "%s.xAccess(\"%s\",%d)",
pInfo->zVfsName, zPath, flags);
rc = pRoot->xAccess(pRoot, zPath, flags, pResOut);
@ -783,6 +955,7 @@ static int vfstraceFullPathname(
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
sqlite3_vfs *pRoot = pInfo->pRootVfs;
int rc;
vfstraceOnOff(pInfo, VTR_FULLPATH);
vfstrace_printf(pInfo, "%s.xFullPathname(\"%s\")",
pInfo->zVfsName, zPath);
rc = pRoot->xFullPathname(pRoot, zPath, nOut, zOut);
@ -797,6 +970,7 @@ static int vfstraceFullPathname(
static void *vfstraceDlOpen(sqlite3_vfs *pVfs, const char *zPath){
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
sqlite3_vfs *pRoot = pInfo->pRootVfs;
vfstraceOnOff(pInfo, VTR_DLOPEN);
vfstrace_printf(pInfo, "%s.xDlOpen(\"%s\")\n", pInfo->zVfsName, zPath);
return pRoot->xDlOpen(pRoot, zPath);
}
@ -809,6 +983,7 @@ static void *vfstraceDlOpen(sqlite3_vfs *pVfs, const char *zPath){
static void vfstraceDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
sqlite3_vfs *pRoot = pInfo->pRootVfs;
vfstraceOnOff(pInfo, VTR_DLERR);
vfstrace_printf(pInfo, "%s.xDlError(%d)", pInfo->zVfsName, nByte);
pRoot->xDlError(pRoot, nByte, zErrMsg);
vfstrace_printf(pInfo, " -> \"%s\"", zErrMsg);
@ -830,6 +1005,7 @@ static void (*vfstraceDlSym(sqlite3_vfs *pVfs,void *p,const char *zSym))(void){
static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
sqlite3_vfs *pRoot = pInfo->pRootVfs;
vfstraceOnOff(pInfo, VTR_DLCLOSE);
vfstrace_printf(pInfo, "%s.xDlOpen()\n", pInfo->zVfsName);
pRoot->xDlClose(pRoot, pHandle);
}
@ -841,6 +1017,7 @@ static void vfstraceDlClose(sqlite3_vfs *pVfs, void *pHandle){
static int vfstraceRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
sqlite3_vfs *pRoot = pInfo->pRootVfs;
vfstraceOnOff(pInfo, VTR_RAND);
vfstrace_printf(pInfo, "%s.xRandomness(%d)\n", pInfo->zVfsName, nByte);
return pRoot->xRandomness(pRoot, nByte, zBufOut);
}
@ -852,6 +1029,8 @@ static int vfstraceRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
static int vfstraceSleep(sqlite3_vfs *pVfs, int nMicro){
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
sqlite3_vfs *pRoot = pInfo->pRootVfs;
vfstraceOnOff(pInfo, VTR_SLEEP);
vfstrace_printf(pInfo, "%s.xSleep(%d)\n", pInfo->zVfsName, nMicro);
return pRoot->xSleep(pRoot, nMicro);
}
@ -861,21 +1040,37 @@ static int vfstraceSleep(sqlite3_vfs *pVfs, int nMicro){
static int vfstraceCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
sqlite3_vfs *pRoot = pInfo->pRootVfs;
return pRoot->xCurrentTime(pRoot, pTimeOut);
int rc;
vfstraceOnOff(pInfo, VTR_CURTIME);
vfstrace_printf(pInfo, "%s.xCurrentTime()", pInfo->zVfsName);
rc = pRoot->xCurrentTime(pRoot, pTimeOut);
vfstrace_printf(pInfo, " -> %.17g\n", *pTimeOut);
return rc;
}
static int vfstraceCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
sqlite3_vfs *pRoot = pInfo->pRootVfs;
return pRoot->xCurrentTimeInt64(pRoot, pTimeOut);
int rc;
vfstraceOnOff(pInfo, VTR_CURTIME);
vfstrace_printf(pInfo, "%s.xCurrentTimeInt64()", pInfo->zVfsName);
rc = pRoot->xCurrentTimeInt64(pRoot, pTimeOut);
vfstrace_printf(pInfo, " -> %lld\n", *pTimeOut);
return rc;
}
/*
** Return th3 most recent error code and message
** Return the most recent error code and message
*/
static int vfstraceGetLastError(sqlite3_vfs *pVfs, int iErr, char *zErr){
static int vfstraceGetLastError(sqlite3_vfs *pVfs, int nErr, char *zErr){
vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData;
sqlite3_vfs *pRoot = pInfo->pRootVfs;
return pRoot->xGetLastError(pRoot, iErr, zErr);
int rc;
vfstraceOnOff(pInfo, VTR_LASTERR);
vfstrace_printf(pInfo, "%s.xGetLastError(%d,zBuf)", pInfo->zVfsName, nErr);
if( nErr ) zErr[0] = 0;
rc = pRoot->xGetLastError(pRoot, nErr, zErr);
vfstrace_printf(pInfo, " -> zBuf[] = \"%s\", rc = %d\n", nErr?zErr:"", rc);
return rc;
}
/*
@ -969,6 +1164,8 @@ int vfstrace_register(
pInfo->pOutArg = pOutArg;
pInfo->zVfsName = pNew->zName;
pInfo->pTraceVfs = pNew;
pInfo->mTrace = 0xffffffff;
pInfo->bOn = 1;
vfstrace_printf(pInfo, "%s.enabled_for(\"%s\")\n",
pInfo->zVfsName, pRoot->zName);
return sqlite3_vfs_register(pNew, makeDefault);

118
main.mk

@ -162,6 +162,7 @@ LDFLAGS.pthread ?= -lpthread
LDFLAGS.dlopen ?= -ldl
LDFLAGS.shobj ?= -shared
LDFLAGS.icu ?= # -licui18n -licuuc -licudata
CFLAGS.icu ?=
LDFLAGS.soname.libsqlite3 ?=
# libreadline (or a workalike):
# To activate readline in the shell: SHELL_OPT = -DHAVE_READLINE=1
@ -1334,7 +1335,8 @@ tclsqlite-stubs.o: $(T.tcl.env.sh) $(TOP)/src/tclsqlite.c $(DEPS_OBJ_COMMON)
tclsqlite3$(T.exe): $(T.tcl.env.sh) tclsqlite-shell.o $(libsqlite3.SO)
$(T.link.tcl) -o $@ tclsqlite-shell.o \
$(libsqlite3.SO) $$TCL_INCLUDE_SPEC $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3)
$(libsqlite3.SO) $$TCL_INCLUDE_SPEC $$TCL_LIB_SPEC \
$(LDFLAGS.libsqlite3)
tclsqlite3$(T.exe)-1: tclsqlite3$(T.exe)
tclsqlite3$(T.exe)-0 tclsqlite3$(T.exe)-:
tcl: tclsqlite3$(T.exe)-$(HAVE_TCL)
@ -1387,7 +1389,8 @@ all: lib
# Dynamic libsqlite3
#
$(libsqlite3.SO): $(LIBOBJ)
$(T.link.shared) -o $@ $(LIBOBJ) $(LDFLAGS.soname.libsqlite3) $(LDFLAGS.libsqlite3)
$(T.link.shared) -o $@ $(LIBOBJ) $(LDFLAGS.soname.libsqlite3) \
$(LDFLAGS.libsqlite3) $(LDFLAGS.libsqlite3.soname)
$(libsqlite3.SO)-1: $(libsqlite3.SO)
$(libsqlite3.SO)-0 $(libsqlite3.SO)-:
so: $(libsqlite3.SO)-$(ENABLE_SHARED)
@ -1399,9 +1402,13 @@ all: so
#
# - libsqlite3.so.$(PACKAGE_VERSION)
# - libsqlite3.so.3 =symlink-> libsqlite3.so.$(PACKAGE_VERSION)
# - libsqlite3.so.0 =symlink-> libsqlite3.so.$(PACKAGE_VERSION) (see below)
# - libsqlite3.so =symlink-> libsqlite3.so.3
#
# Regarding the historcal installation name of libsqlite3.so.0.8.6:
# The link named libsqlite3.so.0 is provided in an attempt to reduce
# downstream disruption when performing upgrades from pre-3.48 to a
# version 3.48 or higher. That name is considered a legacy remnant
# and will eventually be removed from this installation process.
#
# Historically libtool installed the library like so:
#
@ -1415,13 +1422,12 @@ all: so
# compatibility for systems which have libraries installed using those
# conventions:
#
# 1) If libsqlite3.so.0 is found in the target installation directory
# then it and libsqlite3.so.0.8.6 are re-linked to point to the
# newer-style names. We cannot retain both the old and new
# installation because they both share the high-level name
# $(libsqlite3.SO). The down-side of this is that it may well upset
# packaging tools when we replace libsqlite3.so (from a legacy
# package) with a new symlink.
# 1) If libsqlite3.so.0.8.6 is found in the target installation
# directory then it is re-linked to point to the newer-style
# names. We cannot retain both the old and new installation because
# they both share the high-level name $(libsqlite3.SO). The
# down-side of this is that it may upset packaging tools when we
# replace libsqlite3.so (from a legacy package) with a new symlink.
#
# 2) If INSTALL_SO_086_LINKS=1 and point (1) does not apply then links
# to the legacy-style names are created. The primary intent of this
@ -1435,25 +1441,24 @@ all: so
#
install-so-1: $(install-dir.lib) $(libsqlite3.SO)
$(INSTALL) $(libsqlite3.SO) "$(install-dir.lib)"
@echo "Setting up SO symlinks..."; \
@echo "Setting up $(libsqlite3.SO) symlinks..."; \
cd "$(install-dir.lib)" || exit $$?; \
rm -f $(libsqlite3.SO).3 $(libsqlite3.SO).$(PACKAGE_VERSION) || exit $$?; \
rm -f $(libsqlite3.SO).3 $(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).3 || exit $$?; \
ln -s $(libsqlite3.SO).3 $(libsqlite3.SO) || exit $$?; \
ls -la $(libsqlite3.SO) $(libsqlite3.SO).3*; \
if [ -e $(libsqlite3.SO).0 ]; then \
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* || exit $$?; \
ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0 || exit $$?; \
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*; \
ls -la $(libsqlite3.SO).0.8.6; \
elif [ x1 = "x$(INSTALL_SO_086_LINKS)" ]; then \
echo "ACHTUNG: installing legacy libtool-style links because INSTALL_SO_086_LINKS=1"; \
rm -f libsqlite3.la $(libsqlite3.SO).0* || exit $$?; \
ln -s $(libsqlite3.SO).$(PACKAGE_VERSION) $(libsqlite3.SO).0 || exit $$?; \
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*; \
ls -la $(libsqlite3.SO).0.8.6; \
fi
install-so-0 install-so-:
install-so: install-so-$(ENABLE_SHARED)
@ -1531,7 +1536,7 @@ tclextension: tclsqlite3.c
# to find it.
#
tclextension-install: tclsqlite3.c
$(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --cc "$(T.cc)" $(CFLAGS.tclextension)
$(TCLSH_CMD) $(TOP)/tool/buildtclext.tcl --destdir "$(DESTDIR)" --cc "$(T.cc)" $(CFLAGS.tclextension)
#
# Uninstall the SQLite TCL extension that is used by $TCLSH_CMD.
@ -1731,7 +1736,8 @@ sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl \
$(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c
sqlite3_analyzer$(T.exe): $(T.tcl.env.sh) sqlite3_analyzer.c
$(T.link.tcl) sqlite3_analyzer.c -o $@ $$TCL_LIB_SPEC $$TCL_INCLUDE_SPEC $(LDFLAGS.libsqlite3)
$(T.link.tcl) sqlite3_analyzer.c -o $@ $$TCL_LIB_SPEC $$TCL_INCLUDE_SPEC \
$(LDFLAGS.libsqlite3)
sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \
$(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl \
@ -1739,14 +1745,15 @@ sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl \
$(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c
sqltclsh$(T.exe): $(T.tcl.env.sh) sqltclsh.c
$(T.link.tcl) sqltclsh.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3)
$(T.link.tcl) sqltclsh.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) \
$$TCL_LIB_SPEC $(LDFLAGS.libsqlite3)
# xbin: target for generic binaries which aren't usually built. It is
# used primarily for testing the build process.
xbin: sqltclsh$(T.exe) sqlite3_analyzer$(T.exe)
sqlite3_expert$(T.exe): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \
$(TOP)/ext/expert/expert.c sqlite3.c
$(T.link) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \
$(T.link) $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c \
$(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(LDFLAGS.libsqlite3)
xbin: sqlite3_expert$(T.exe)
@ -1764,16 +1771,17 @@ sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85
$(B.tclsh) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@
sqlite3_checker$(T.exe): $(T.tcl.env.sh) sqlite3_checker.c
$(T.link.tcl) sqlite3_checker.c -o $@ $$TCL_INCLUDE_SPEC $(CFLAGS.libsqlite3) $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3)
$(T.link.tcl) sqlite3_checker.c -o $@ $$TCL_INCLUDE_SPEC \
$(CFLAGS.libsqlite3) $$TCL_LIB_SPEC $(LDFLAGS.libsqlite3)
xbin: sqlite3_checker$(T.exe)
dbdump$(T.exe): $(TOP)/ext/misc/dbdump.c sqlite3.o
$(T.link) -DDBDUMP_STANDALONE -o $@ \
$(TOP)/ext/misc/dbdump.c sqlite3.o $(LDFLAGS.libsqlite3)
$(TOP)/ext/misc/dbdump.c sqlite3.o $(LDFLAGS.libsqlite3)
xbin: dbdump$(T.exe)
dbtotxt$(T.exe): $(TOP)/tool/dbtotxt.c
$(T.link)-o $@ $(TOP)/tool/dbtotxt.c
$(T.link)-o $@ $(TOP)/tool/dbtotxt.c $(LDFLAGS.configure)
xbin: dbtotxt$(T.exe)
showdb$(T.exe): $(TOP)/tool/showdb.c sqlite3.o
@ -1793,20 +1801,23 @@ showwal$(T.exe): $(TOP)/tool/showwal.c sqlite3.o
xbin: showwal$(T.exe)
showshm$(T.exe): $(TOP)/tool/showshm.c
$(T.link) -o $@ $(TOP)/tool/showshm.c
$(T.link) -o $@ $(TOP)/tool/showshm.c $(LDFLAGS.configure)
xbin: showshm$(T.exe)
index_usage$(T.exe): $(TOP)/tool/index_usage.c sqlite3.o
$(T.link) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.o $(LDFLAGS.libsqlite3)
$(T.link) $(SHELL_OPT) -o $@ $(TOP)/tool/index_usage.c sqlite3.o \
$(LDFLAGS.libsqlite3)
xbin: index_usage$(T.exe)
# Reminder: changeset does not build without -DSQLITE_ENABLE_SESSION
changeset$(T.exe): $(TOP)/ext/session/changeset.c sqlite3.o
$(T.link) -o $@ $(TOP)/ext/session/changeset.c sqlite3.o $(LDFLAGS.libsqlite3)
$(T.link) -o $@ $(TOP)/ext/session/changeset.c sqlite3.o \
$(LDFLAGS.libsqlite3)
xbin: changeset$(T.exe)
changesetfuzz$(T.exe): $(TOP)/ext/session/changesetfuzz.c sqlite3.o
$(T.link) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.o $(LDFLAGS.libsqlite3)
$(T.link) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.o \
$(LDFLAGS.libsqlite3)
xbin: changesetfuzz$(T.exe)
rollback-test$(T.exe): $(TOP)/tool/rollback-test.c sqlite3.o
@ -1818,7 +1829,7 @@ atrc$(T.exe): $(TOP)/test/atrc.c sqlite3.o
xbin: atrc$(T.exe)
LogEst$(T.exe): $(TOP)/tool/logest.c sqlite3.h
$(T.link) -I. -o $@ $(TOP)/tool/logest.c
$(T.link) -I. -o $@ $(TOP)/tool/logest.c $(LDFLAGS.configure)
xbin: LogEst$(T.exe)
wordcount$(T.exe): $(TOP)/test/wordcount.c sqlite3.o
@ -1826,17 +1837,20 @@ wordcount$(T.exe): $(TOP)/test/wordcount.c sqlite3.o
xbin: wordcount$(T.exe)
speedtest1$(T.exe): $(TOP)/test/speedtest1.c sqlite3.c Makefile
$(T.link) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c $(LDFLAGS.libsqlite3)
$(T.link) $(ST_OPT) -o $@ $(TOP)/test/speedtest1.c sqlite3.c \
$(LDFLAGS.libsqlite3)
xbin: speedtest1$(T.exe)
startup$(T.exe): $(TOP)/test/startup.c sqlite3.c
$(T.link) -Os -g -USQLITE_THREADSAFE -DSQLITE_THREADSAFE=0 -o $@ $(TOP)/test/startup.c sqlite3.c $(LDFLAGS.libsqlite3)
$(T.link) -Os -g -USQLITE_THREADSAFE -DSQLITE_THREADSAFE=0 \
-o $@ $(TOP)/test/startup.c sqlite3.c $(LDFLAGS.libsqlite3)
xbin: startup$(T.exe)
KV_OPT += -DSQLITE_DIRECT_OVERFLOW_READ
kvtest$(T.exe): $(TOP)/test/kvtest.c sqlite3.c
$(T.link) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c $(LDFLAGS.libsqlite3)
$(T.link) $(KV_OPT) -o $@ $(TOP)/test/kvtest.c sqlite3.c \
$(LDFLAGS.libsqlite3)
xbin: kvtest$(T.exe)
#
@ -1847,7 +1861,8 @@ rbu$(T.exe): $(TOP)/ext/rbu/rbu.c $(TOP)/ext/rbu/sqlite3rbu.c sqlite3.o
$(T.link) -I. -o $@ $(TOP)/ext/rbu/rbu.c sqlite3.o $(LDFLAGS.libsqlite3)
loadfts$(T.exe): $(TOP)/tool/loadfts.c $(libsqlite3.LIB)
$(T.link) $(TOP)/tool/loadfts.c $(libsqlite3.LIB) -o $@ $(LDFLAGS.libsqlite3)
$(T.link) $(TOP)/tool/loadfts.c $(libsqlite3.LIB) \
-o $@ $(LDFLAGS.libsqlite3)
xbin: loadfts$(T.exe)
# This target will fail if the SQLite amalgamation contains any exported
@ -1893,7 +1908,8 @@ THREADTEST3_SRC = $(TOP)/test/threadtest3.c \
$(TOP)/test/tt3_lookaside1.c
threadtest3$(T.exe): sqlite3.o $(THREADTEST3_SRC)
$(T.link) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.o -o $@ $(LDFLAGS.libsqlite3)
$(T.link) $(TOP)/test/threadtest3.c $(TOP)/src/test_multiplex.c sqlite3.o \
-o $@ $(LDFLAGS.libsqlite3)
xbin: threadtest3$(T.exe)
threadtest: threadtest3$(T.exe)
@ -1903,9 +1919,22 @@ threadtest5: sqlite3.c $(TOP)/test/threadtest5.c
$(T.link) $(TOP)/test/threadtest5.c sqlite3.c -o $@ $(LDFLAGS.libsqlite3)
xbin: threadtest5
# The standard CLI is built using the amalgamation since it uses
# special compile-time options that are interpreted by individual
# source files within the amalgamation.
#
sqlite3$(T.exe): shell.c sqlite3.c
$(T.link) -o $@ \
shell.c sqlite3.c \
$(CFLAGS.readline) $(SHELL_OPT) $(CFLAGS.icu) \
$(LDFLAGS.libsqlite3) $(LDFLAGS.readline)
# The "sqlite3d" CLI is build using separate source files. This
# is useful during development and debugging.
#
sqlite3d$(T.exe): shell.c $(LIBOBJS0)
$(T.link) -o $@ \
shell.c $(LIBOBJS0) \
$(CFLAGS.readline) $(SHELL_OPT) \
$(LDFLAGS.libsqlite3) $(LDFLAGS.readline)
@ -1983,7 +2012,7 @@ verify-source: ./src-verify$(B.exe)
fuzzershell$(T.exe): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
$(T.link) -o $@ $(FUZZERSHELL_OPT) \
$(TOP)/tool/fuzzershell.c sqlite3.c $(LDFLAGS.libsqlite3)
$(TOP)/tool/fuzzershell.c sqlite3.c $(LDFLAGS.libsqlite3)
fuzzy: fuzzershell$(T.exe)
xbin: fuzzershell$(T.exe)
@ -2021,7 +2050,7 @@ run-fuzzcheck: fuzzcheck$(T.exe) fuzzcheck-asan$(T.exe) fuzzcheck-ubsan$(T.exe)
ossshell$(T.exe): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h
$(T.link) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \
$(TOP)/test/ossfuzz.c sqlite3.c $(LDFLAGS.libsqlite3)
$(TOP)/test/ossfuzz.c sqlite3.c $(LDFLAGS.libsqlite3)
fuzzy: ossshell$(T.exe)
xbin: ossshell$(T.exe)
@ -2030,7 +2059,8 @@ sessionfuzz$(T.exe): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h
fuzzy: sessionfuzz$(T.exe)
dbfuzz$(T.exe): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h
$(T.link) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(LDFLAGS.libsqlite3)
$(T.link) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c \
$(LDFLAGS.libsqlite3)
fuzzy: dbfuzz$(T.exe)
xbin: dbfuzz$(T.exe)
@ -2111,7 +2141,7 @@ shell.c: $(SHELL_DEP) $(TOP)/tool/mkshellc.tcl $(B.tclsh) # has_tclsh84
#
DEPS_EXT_COMMON = $(DEPS_OBJ_COMMON) $(EXTHDR)
icu.o: $(TOP)/ext/icu/icu.c $(DEPS_EXT_COMMON)
$(T.cc.extension) -c $(TOP)/ext/icu/icu.c
$(T.cc.extension) -c $(TOP)/ext/icu/icu.c $(CFLAGS.icu)
fts3.o: $(TOP)/ext/fts3/fts3.c $(DEPS_EXT_COMMON)
$(T.cc.extension) -c $(TOP)/ext/fts3/fts3.c
@ -2126,7 +2156,7 @@ fts3_hash.o: $(TOP)/ext/fts3/fts3_hash.c $(DEPS_EXT_COMMON)
$(T.cc.extension) -c $(TOP)/ext/fts3/fts3_hash.c
fts3_icu.o: $(TOP)/ext/fts3/fts3_icu.c $(DEPS_EXT_COMMON)
$(T.cc.extension) -c $(TOP)/ext/fts3/fts3_icu.c
$(T.cc.extension) -c $(TOP)/ext/fts3/fts3_icu.c $(CFLAGS.icu)
fts3_porter.o: $(TOP)/ext/fts3/fts3_porter.c $(DEPS_EXT_COMMON)
$(T.cc.extension) -c $(TOP)/ext/fts3/fts3_porter.c
@ -2172,7 +2202,7 @@ sqlite3.def: $(LIBOBJ)
sqlite3.dll: $(LIBOBJ) sqlite3.def
$(T.cc.sqlite) $(LDFLAGS.shobj) -o $@ sqlite3.def \
-Wl,"--strip-all" $(LIBOBJ)
-Wl,"--strip-all" $(LIBOBJ) $(LDFLAGS.configure)
#
# Emit a list of commonly-used targets

@ -1,9 +1,9 @@
C Doc\supdate\sto\saccount\sfor\s[05073350087b].
D 2024-11-11T09:53:40.171
C Call\sfflush()\son\s".echo"\soutput\sfrom\sthe\sshell,\sso\sthat\sthe\soutput\sto\nstdout\sis\saligned\swith\soutput\sto\sstderr.
D 2024-11-16T18:54:46.664
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md e108e1e69ae8e8a59e93c455654b8ac9356a11720d3345df2a4743e9590fb20d
F Makefile.in 580a60aa8deb37060c7973d9399c51c4388f1e0ad0be6555dcd44bc8d2ac3260
F Makefile.in 2c90ab3183f810086878a784c323b7816238a5e6943d267c25a71edc623a05a3
F Makefile.linux-generic bd3e3cacd369821a6241d4ea1967395c962dfe3057e38cb0a435cee0e8b789d0
F Makefile.msc a92237976eb92c5efaa0dd2524746aec12c196e12df8d4dbff9543a4648c3312
F README.md c3c0f19532ce28f6297a71870f3c7b424729f0e6d9ab889616d3587dd2332159
@ -13,7 +13,7 @@ F art/icon-80x90.gif 65509ce3e5f86a9cd64fe7fca2d23954199f31fe44c1e09e208c80fb83d
F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2
F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90
F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2
F auto.def dd7d48438426327c37f51f8e289492058744656e2da03197c31e4fb76398050c
F auto.def 94f0f4a697e8221d5c7ca561771a3afabb0e707922daad89b60908b87a8e399b
F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903
F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347
F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac
@ -49,7 +49,7 @@ F autosetup/cc-shared.tcl 4f024e94a47f427ba61de1739f6381ef0080210f9fae89112d5c1d
F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e45f
F autosetup/jimsh0.c d40e381ea4526a067590e7b91bd4b2efa6d4980d286f908054c647b3df4aee14
F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba
F autosetup/proj.tcl 9772d3f89634089add92e2238551a59a5c764d501327f6eb433dca7f98138802
F autosetup/proj.tcl 96fe16b87c9feb9c1cf2682280f678c659bc52c09fca5de02afc2f7ec5bfb154
F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9
F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
@ -111,12 +111,12 @@ F ext/fts5/fts5_config.c a6633d88596758941c625b526075b85d3d9fd1089d8d9eab5db6e8a
F ext/fts5/fts5_expr.c 9a56f53700d1860f0ee2f373c2b9074eaf2a7aa0637d0e27a6476de26a3fee33
F ext/fts5/fts5_hash.c adda4272be401566a6e0ba1acbe70ee5cb97fce944bc2e04dc707152a0ec91b1
F ext/fts5/fts5_index.c 368a968570ce12ba40223e284a588d9f93ee23a0133727f0df1fcd64086b1fb6
F ext/fts5/fts5_main.c 50eb059e51d730e8e0c77df4e568b018079e112a755c094488b0d5b1aa06afbb
F ext/fts5/fts5_main.c 0b60324001e26d79e8a12e544883792f59a58717f6dce9fb1f8878f0e0196530
F ext/fts5/fts5_storage.c 337b05e4c66fc822d031e264d65bde807ec2fab08665ca2cc8aaf9c5fa06792c
F ext/fts5/fts5_tcl.c aee6ae6d0c6968564c392bf0d09aaabb4d8bea9ca69fd224dc9b44243324acbf
F ext/fts5/fts5_tcl.c 7fb5a3d3404099075aaa2457307cb459bbc257c0de3dbd52b1e80a5b503e0329
F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee
F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b
F ext/fts5/fts5_tokenize.c 033e2e43b8e852c0ef6cecc611266d61e2346e52ec7dcfb76a428fe56a07efa9
F ext/fts5/fts5_tokenize.c 87ab719f0556172da3414f1741c11bb4d333ebecde157945a55478bfe6e46c44
F ext/fts5/fts5_unicode2.c 6f9b0fb79a8facaed76628ffd4eb9c16d7f2b84b52872784f617cf3422a9b043
F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80
F ext/fts5/fts5_vocab.c e4830b00809e5da53bc10f93adc59e321407b0f801c7f4167c0e47f5552267e0
@ -248,7 +248,7 @@ F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2
F ext/fts5/test/fts5tokenizer.test 7937cec672b148223fff8746d21d3e7ed0965fd7caf35ccdc888a005bb452f98
F ext/fts5/test/fts5tokenizer2.test ddb8b10fbe4b84b2a75812671f127774c1d2e3e2bf82d2e0e4f0bb1cd8a2b2d6
F ext/fts5/test/fts5tokenizer3.test eea778f7bb7024c3e904e28915f9d53286141671b138722148be22a9c758bdc3
F ext/fts5/test/fts5trigram.test 9927c9e9b35116ea00748c8e41d9cbc2b95a6c90845cd82a59c11fedfd16404a
F ext/fts5/test/fts5trigram.test a55fde7065ae69a0f82c5a7a5bf5286a97de11ae4bff6537fd3e27ca9a01416f
F ext/fts5/test/fts5trigram2.test 6fde9de7f63a6b4aa18dc731be56dbd6be4e755c9b13dcd55479e200d1df0e61
F ext/fts5/test/fts5ubsan.test 9a2dcf399dc8d0e0de661f0d93884d1d27e5b7f0693cfceb97dd24d818df5dd2
F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602
@ -438,7 +438,7 @@ F ext/misc/shathree.c 1821d90a0040c9accdbe3e3527d378d30569475d758aa70f6848924c0b
F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52
F ext/misc/spellfix.c bcc42ef3fd29429bc01a83e751332b8d4690e65d45008449bdffe7656371487f
F ext/misc/sqlar.c a6175790482328171da47095f87608b48a476d4fac78d8a9ff18b03a2454f634
F ext/misc/sqlite3_stdio.c c34b4aba8aec6c1ca7058a7a6319a37ab629135091600aee202390a8cd20e842
F ext/misc/sqlite3_stdio.c 5657afb6ec81bef31790973528980af778e0e1388a93db780d33007336efe6e6
F ext/misc/sqlite3_stdio.h f05eaf5e0258f0573910324a789a9586fc360a57678c57a6d63cfaa2245b6176
F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321
F ext/misc/stmtrand.c 59cffa5d8e158943ff1ce078956d8e208e8c04e67307e8f249dece2436dcb7fc
@ -450,7 +450,7 @@ F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917
F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf
F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20
F ext/misc/vfsstat.c a85df08654743922a19410d7b1e3111de41bb7cd07d20dd16eda4e2b808d269d
F ext/misc/vfstrace.c ac76a4ac4d907774fd423cc2b61410c756f9d0782e27cf6032e058594accaaca
F ext/misc/vfstrace.c 2f68da859f87be350ede0e8eb94f754219d406161c1595250fc0ca55907460f6
F ext/misc/vtablog.c 1100250ce8782db37c833e3a9a5c9a3ecf1af5e15b8325572b82e6e0a138ffb5
F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd
F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668
@ -696,7 +696,7 @@ F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65a
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
F ext/wasm/wasmfs.make bc8bb227f35d5bd3863a7bd2233437c37472a0d81585979f058f9b9b503bef35
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
F main.mk efb8f627c5793126ff7a86d698676f4e6509a296b0b113ec284e6f723561f0bc
F main.mk e2287ed82f924c9d54493634dc7bb10797b8ef69ce7becef62d6a453337d5a45
F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271
F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504
F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421
@ -706,7 +706,6 @@ F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc
F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03
F sqlite_cfg.h.in be1d075cf77134d53fdf5cc2c0919842e7e02a648c66a56e735af25ccdcaff91
F src/alter.c aa93e37e4a36a0525bbb2a2aeda20d2018f0aa995542c7dc658e031375e3f532
F src/analyze.c 9a8b67239d899ac12289db5db3f5bfe7f7a0ad1277f80f87ead1d048085876eb
F src/attach.c f35bb8cc1fcdde8f6815a7ef09ae413bcac71821d530796800ba24b3c7da1e80
@ -759,8 +758,8 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a
F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107
F src/os_unix.c c84a3add1e480499261a41d77d3f87d18f27aaebec6376655c177a3886a5b67c
F src/os_win.c 69fa1aaff68270423c85cff4327ba17ef99a1eb017e1a2bfb97416d9b8398b05
F src/os_unix.c d2edbd92b07a3f778c2defa8a2e9d75acceb6267bda56948c41e8cdda65224d6
F src/os_win.c db4baa8f62bbfe3967c71b008cea31a8f2ff337c1667ff4d8a677e697315ff0d
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 9656ad4e8331efb8a4f94f7a0c6440b98caea073950a367ea0c728a53b8e62c9
F src/pager.h 4b1140d691860de0be1347474c51fee07d5420bd7f802d38cbab8ea4ab9f538a
@ -776,15 +775,15 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c c8a5372b97b2a2e972a280676f06ddb5b74e885d3b1f5ce383f839907b57ef68
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 4b14337a2742f0c0beeba490e9a05507e9b4b12184b9cd12773501d08d48e3fe
F src/shell.c.in bb97e0afcc4a73b73f38cc868330854a2df109095a7a10182ddfdd261fbec312
F src/sqlite.h.in 599203aa6cf3a662f879e7581f4b7f2678738c0b7c71ddda3c0cb5c59867c399
F src/shell.c.in 469039a2a09603bf32f47b5c4ddc61e8b980139919db1f46000241357f5f3588
F src/sqlite.h.in 4d93768709c53b7c653a63817a82d5a8625264ca0d8cdf99967ba147bdcf2aa6
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
F src/sqliteInt.h 77be043f8694f4a8702d0ee882022b2e5a6489a0493e77c5d9a73f1efc5a2cc1
F src/sqliteLimit.h 6993c9cfe3af5b8169ae0e5f15627fc15596726d4f1dc90a221309f79715ce88
F src/status.c cb11f8589a6912af2da3bb1ec509a94dd8ef27df4d4c1a97e0bcf2309ece972b
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
F src/tclsqlite.c ff2dc3ec1bd318ee7a45d6b246a367703d5fb2a4c8da99d675ee7eb987b3a153
F src/tclsqlite.c c4b0b27b0ad34e4af085040a1ebe94a35ad5161663cd905d1b947f7884691bff
F src/tclsqlite.h 65e2c761446e1c9fa0342b7d2612a703483643c8b6a316d12a65b745a4727395
F src/test1.c 2d507751bfb4aa254dc22588ef1e3c5c5cfcb2e636d0e6e1fa0bbd307669c2a8
F src/test2.c 7ebc518e6735939d8979273a6f7b1d9b5702babf059f6ad62499f7f60a9eb9a3
@ -863,7 +862,7 @@ F src/where.c 4de9e7ca5f49e4a21c1d733e2b2fbbc8b62b1a157a58a562c569da84cfcb005b
F src/whereInt.h 1e36ec50392f7cc3d93d1152d4338064cd522b87156a0739388b7e273735f0ca
F src/wherecode.c 81b9af89f4f85c8097d0da6a31499f015eabc4d3584963d30ba7b7b782e26514
F src/whereexpr.c 0f93a29cabd3a338d09a1f5c6770620a1ac51ec1157f3229502a7e7767c60b6f
F src/window.c 499d48f315a09242dc68f2fac635ed27dcf6bbb0d9ab9084857898c64489e975
F src/window.c 6c386af5972a58f9a9847bba9d7ca70c4c682391ab8478d94a6e046b22a0dbb3
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
F test/affinity3.test f094773025eddf31135c7ad4cde722b7696f8eb07b97511f98585addf2a510a9
@ -1154,6 +1153,7 @@ F test/fkey7.test 64fb28da03da5dfe3cdef5967aa7e832c2507bf7fb8f0780cacbca1f2338d0
F test/fkey8.test 51deda7f1a1448bca95875e4a6e1a3a75b4bd7215e924e845bd60de60e4d84bf
F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749
F test/fordelete.test ba98f14446b310f9c9d935b97ec748753d0144a28b356ba30d1f4f6958fdde5c
F test/fork-test.c 9ac2e6423a1d38df3d6be0e8ac15608b545de21e2b19d9d876254c5931b63edb
F test/format4.test eeae341953db8b6bda7f549044797c3278a6cc345d11ada81471671b654f8ef4
F test/fp-speed-1.c b37de94eba034e1703668816225f54510ec60fb0685406608cc707afe6b8234d
F test/fpconv1.test d5d8aa0c427533006c112fb1957cdd1ea68c1d0709470dabb9ca02c2e4c06ad8
@ -2066,9 +2066,9 @@ F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652
F test/window6.test 311de885bd7e453134fa6747680bfb4a1be87c91720bf58703db945891e7d30b
F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d76108f
F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd
F test/window8.tcl 5e02e41d9d9a80f597063aed1a381eb19d1d0ef677a4f0df352c5365cf23f79c
F test/window8.test 4ab16817414af0c904abe2ebdf88eb6c2b00058b84f9748c6174ff11fc45f1ed
F test/window9.test 349c71eab4288a1ffc19e2f65872ec2c37e6cf8a1dda2ad300364b7450ae4836
F test/window8.tcl c57364e64d816f6e26df60437e1202e2c1031c7b818a1a67535d1006862a026a
F test/window8.test 3d931e58802b8ab8063da00f0cf30aa3351640238a952c0efb5a129e2349a4bb
F test/window9.test 7b98a7916dd87763ea35f56ea023e3b29e99744582204ccf2937a3bac411cd4d
F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be
F test/windowB.test aad7c31739999f68a98a813cfd78390918fc70f56d2d925317a1523cab548ecf
F test/windowC.test 6fd75f5bb2f1343d34e470e36e68f0ff638d8a42f6aa7d99471261b31a0d42f2
@ -2105,7 +2105,7 @@ F tool/GetTclKit.bat d84033c6a93dfe735d247f48ba00292a1cc284dcf69963e5e672444e045
F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91
F tool/build-all-msvc.bat c817b716e0edeecaf265a6775b63e5f45c34a6544f1d4114a222701ed5ac79ab x
F tool/build-shell.sh 369c4b171cc877ad974fef691e4da782b4c1e99fe8f4361316c735f64d49280f
F tool/buildtclext.tcl b64d250517b148e644d26fcbc097851867a0df52cd4bafe9bcd94b8421e1428a
F tool/buildtclext.tcl 12b49ae392006251d110f051d22036f7807d7ea1602780f4c165154b12567397
F tool/cg_anno.tcl c1f875f5a4c9caca3d59937b16aff716f8b1883935f1b4c9ae23124705bc8099 x
F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
F tool/cktclsh.sh 6075eef9c6b9ba4b38fef2ca2a66d25f2311bd3c610498d18a9b01f861629cca
@ -2189,8 +2189,8 @@ F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
F tool/stripccomments.c 20b8aabc4694d0d4af5566e42da1f1a03aff057689370326e9269a9ddcffdc37
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
F tool/symbols.sh 1612bd947750e21e7b47befad5f6b3825b06cce0705441f903bf35ced65ae9b9
F tool/tclConfigShToAutoDef.sh 44ec55046d86a3febb2cb3e099399b41794e80e9cd138eee7b9b016f819e882b x
F tool/tclConfigShToMake.sh 7c065d81c2d178e15e45a77372c6e5a38b5a1b08755301cd6f20a3a862db7312 x
F tool/tclConfigShToTcl.sh 44ec55046d86a3febb2cb3e099399b41794e80e9cd138eee7b9b016f819e882b x
F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003
F tool/vdbe-compress.tcl fa2f37ab39b2a0087fafb6a7f3ce19503e25e624ffa8ed9951717ab72920c088
F tool/vdbe_profile.tcl 3ac5a4a9449f4baf77059358ea050db3e34395ccf59c5464d29b91746d5b961e
@ -2198,8 +2198,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 05073350087b368312515134bdf9a266eb8289a065f208421fe08aa38b562d4b
R 3e7bc73740255e6a3248a16815c573a3
U stephan
Z 9ae48f5cefd523f44e5eeeffcff1033d
P cd942dce148c9d8f5a94cee61923aad8d1b732b807e004005f78323be30c02e7
R c6e3e7808022fc93197afc8ff5529a17
U drh
Z 8206467963ac0d5803b490ec391283d6
# Remove this line to create a well-formed Fossil manifest.

@ -1 +1 @@
b81976c520fbad0bbdbbb877fe85691bcda25c12cf5597cfe224fb6306cd65b3
c38b9db3c4f71706a7d211424da64311e6e5daf64b224565a6d82d4b1a68e261

@ -1,194 +0,0 @@
/* sqlite_cfg.h.in - autosetup input template for sqlite_cfg.h. */
/* Define to 1 if you have the <dlfcn.h> header file. */
/*#undef HAVE_DLFCN_H*/
@if HAVE_DLFCN_H
#define HAVE_DLFCN_H @HAVE_DLFCN_H@
@endif
/* Define to 1 if you have the `fdatasync' function. */
/*#undef HAVE_FDATASYNC*/
#define HAVE_FDATASYNC @HAVE_FDATASYNC@
/* Define to 1 if you have the `gmtime_r' function. */
/*#undef HAVE_GMTIME_R*/
#define HAVE_GMTIME_R @HAVE_GMTIME_R@
/* Define to 1 if the system has the type `int16_t'. */
/*#undef HAVE_INT16_T*/
#define HAVE_INT16_T @HAVE_INT16_T@
/* Define to 1 if the system has the type `int32_t'. */
/*#undef HAVE_INT32_T*/
#define HAVE_INT32_T @HAVE_INT32_T@
/* Define to 1 if the system has the type `int64_t'. */
/*#undef HAVE_INT64_T*/
#define HAVE_INT64_T @HAVE_INT64_T@
/* Define to 1 if the system has the type `int8_t'. */
/*#undef HAVE_INT8_T*/
#define HAVE_INT8_T @HAVE_INT8_T@
/* Define to 1 if the system has the type `intptr_t'. */
/*#undef HAVE_INTPTR_T*/
#define HAVE_INTPTR_T @HAVE_INTPTR_T@
/* Define to 1 if you have the <inttypes.h> header file. */
/*#undef HAVE_INTTYPES_H*/
#define HAVE_INTTYPES_H @HAVE_INTTYPES_H@
/* Define to 1 if you have the `isnan' function. */
/*#undef HAVE_ISNAN*/
#define HAVE_ISNAN @HAVE_ISNAN@
/* Define to 1 if you have the `localtime_r' function. */
/*#undef HAVE_LOCALTIME_R*/
#define HAVE_LOCALTIME_R @HAVE_LOCALTIME_R@
/* Define to 1 if you have the `localtime_s' function. */
/*#undef HAVE_LOCALTIME_S*/
#define HAVE_LOCALTIME_S @HAVE_LOCALTIME_S@
/* Define to 1 if you have the <malloc.h> header file. */
/*#undef HAVE_MALLOC_H*/
#define HAVE_MALLOC_H @HAVE_MALLOC_H@
/* Define to 1 if you have the `malloc_usable_size' function. */
/*#undef HAVE_MALLOC_USABLE_SIZE*/
#define HAVE_MALLOC_USABLE_SIZE @HAVE_MALLOC_USABLE_SIZE@
/* Define to 1 if you have the <memory.h> header file. */
/*#undef HAVE_MEMORY_H*/
#define HAVE_MEMORY_H @HAVE_MEMORY_H@
/* Define to 1 if you have the `pread' function. */
/*#undef HAVE_PREAD*/
#define HAVE_PREAD @HAVE_PREAD@
/* Define to 1 if you have the `pread64' function. */
/*#undef HAVE_PREAD64*/
#define HAVE_PREAD64 @HAVE_PREAD64@
/* Define to 1 if you have the `pwrite' function. */
/*#undef HAVE_PWRITE*/
#define HAVE_PWRITE @HAVE_PWRITE@
/* Define to 1 if you have the `pwrite64' function. */
/*#undef HAVE_PWRITE64*/
#define HAVE_PWRITE64 @HAVE_PWRITE64@
/* Define to 1 if you have the <stdint.h> header file. */
/*#undef HAVE_STDINT_H*/
#define HAVE_STDINT_H @HAVE_STDINT_H@
/* Define to 1 if you have the <stdlib.h> header file. */
/*#undef HAVE_STDLIB_H*/
#define HAVE_STDLIB_H @HAVE_STDLIB_H@
/* Define to 1 if you have the `strchrnul' function. */
/*#undef HAVE_STRCHRNUL*/
#define HAVE_STRCHRNUL @HAVE_STRCHRNUL@
/* Define to 1 if you have the <strings.h> header file. */
/*#undef HAVE_STRINGS_H*/
#define HAVE_STRINGS_H @HAVE_STRINGS_H@
/* Define to 1 if you have the <string.h> header file. */
/*#undef HAVE_STRING_H*/
#define HAVE_STRING_H @HAVE_STRING_H@
/* Define to 1 if you have the <sys/stat.h> header file. */
/*#undef HAVE_SYS_STAT_H*/
#define HAVE_SYS_STAT_H @HAVE_SYS_STAT_H@
/* Define to 1 if you have the <sys/types.h> header file. */
/*#undef HAVE_SYS_TYPES_H*/
#define HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@
/* Define to 1 if the system has the type `uint16_t'. */
/*#undef HAVE_UINT16_T*/
#define HAVE_UINT16_T @HAVE_UINT16_T@
/* Define to 1 if the system has the type `uint32_t'. */
/*#undef HAVE_UINT32_T*/
#define HAVE_UINT32_T @HAVE_UINT32_T@
/* Define to 1 if the system has the type `uint64_t'. */
/*#undef HAVE_UINT64_T*/
#define HAVE_UINT64_T @HAVE_UINT64_T@
/* Define to 1 if the system has the type `uint8_t'. */
/*#undef HAVE_UINT8_T*/
#define HAVE_UINT8_T @HAVE_UINT8_T@
/* Define to 1 if the system has the type `uintptr_t'. */
/*#undef HAVE_UINTPTR_T*/
#define HAVE_UINTPTR_T @HAVE_UINTPTR_T@
/* Define to 1 if you have the <unistd.h> header file. */
/*#undef HAVE_UNISTD_H*/
#define HAVE_UNISTD_H @HAVE_UNISTD_H@
/* Define to 1 if you have the `usleep' function. */
/*#undef HAVE_USLEEP*/
#define HAVE_USLEEP @HAVE_USLEEP@
/* Define to 1 if you have the `utime' function. */
/*#undef HAVE_UTIME*/
#define HAVE_UTIME @HAVE_UTIME@
/* Define to 1 if you have the <zlib.h> header file. */
/*#undef HAVE_ZLIB_H*/
#define HAVE_ZLIB_H @HAVE_ZLIB_H@
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
/*#undef LT_OBJDIR*/
/*#define LT_OBJDIR @LT_OBJDIR@*/
/* Define to the address where bug reports for this package should be sent. */
/*#undef PACKAGE_BUGREPORT*/
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
/*#undef PACKAGE_NAME*/
#define PACKAGE_NAME "sqlite"
/* Define to the full name and version of this package. */
/*#undef PACKAGE_STRING*/
#define PACKAGE_STRING "sqlite @RELEASE@"
/* Define to the one symbol short name of this package. */
/*#undef PACKAGE_TARNAME*/
#define PACKAGE_TARNAME "sqlite"
/* Define to the home page for this package. */
/*#undef PACKAGE_URL*/
#define PACKAGE_URL @PACKAGE_URL@
/* Define to the version of this package. */
/*#undef PACKAGE_VERSION*/
#define PACKAGE_VERSION @VERSION@
/* Define to 1 if you have the ANSI C header files. */
/*#undef STDC_HEADERS*/
#define STDC_HEADERS 1 /* @STDC_HEADERS@ */
/* Enable large inode numbers on Mac OS X 10.5. */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif
/* Number of bits in a file offset, on hosts where this is settable. */
/*#undef _FILE_OFFSET_BITS*/
/*#define _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@*/
/*@if _FILE_OFFSET_BITS != ""*/
/*#define _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@*/
/*@endif*/
/* Define for large files, on AIX-style hosts. */
/*#undef _LARGE_FILES*/
/*@if _LARGE_FILES*/
/*#define _LARGE_FILES @_LARGE_FILES@*/
/*@endif*/

@ -3987,6 +3987,11 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
}
#endif /* __linux__ && SQLITE_ENABLE_BATCH_ATOMIC_WRITE */
case SQLITE_FCNTL_NULL_IO: {
osClose(pFile->h);
pFile->h = -1;
return SQLITE_OK;
}
case SQLITE_FCNTL_LOCKSTATE: {
*(int*)pArg = pFile->eFileLock;
return SQLITE_OK;

@ -3599,6 +3599,11 @@ static int winFileControl(sqlite3_file *id, int op, void *pArg){
return SQLITE_OK;
}
#endif
case SQLITE_FCNTL_NULL_IO: {
(void)osCloseHandle(pFile->h);
pFile->h = NULL;
return SQLITE_OK;
}
case SQLITE_FCNTL_TEMPFILENAME: {
char *zTFile = 0;
int rc = winGetTempname(pFile->pVfs, &zTFile);

@ -4886,9 +4886,9 @@ static int run_schema_dump_query(
}else{
rc = SQLITE_CORRUPT;
}
sqlite3_free(zErr);
free(zQ2);
}
sqlite3_free(zErr);
return rc;
}
@ -4951,6 +4951,7 @@ static const char *(azHelp[]) = {
#if SQLITE_SHELL_HAVE_RECOVER
".dbinfo ?DB? Show status information about the database",
#endif
".dbtotxt Hex dump of the database file",
".dump ?OBJECTS? Render database content as SQL",
" Options:",
" --data-only Output only INSERT statements",
@ -6622,6 +6623,101 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
}
#endif /* SQLITE_SHELL_HAVE_RECOVER */
/*
** Implementation of the ".dbtotxt" command.
**
** Return 1 on error, 2 to exit, and 0 otherwise.
*/
static int shell_dbtotxt_command(ShellState *p, int nArg, char **azArg){
sqlite3_stmt *pStmt = 0;
sqlite3_int64 nPage = 0;
int pgSz = 0;
const char *zFilename;
const char *zTail;
char *zName = 0;
int rc, i, j;
unsigned char bShow[256]; /* Characters ok to display */
memset(bShow, '.', sizeof(bShow));
for(i=' '; i<='~'; i++){
if( i!='{' && i!='}' && i!='"' && i!='\\' ) bShow[i] = (unsigned char)i;
}
rc = sqlite3_prepare_v2(p->db, "PRAGMA page_size", -1, &pStmt, 0);
if( rc ) goto dbtotxt_error;
rc = 0;
if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error;
pgSz = sqlite3_column_int(pStmt, 0);
sqlite3_finalize(pStmt);
pStmt = 0;
if( pgSz<512 || pgSz>65536 || (pgSz&(pgSz-1))!=0 ) goto dbtotxt_error;
rc = sqlite3_prepare_v2(p->db, "PRAGMA page_count", -1, &pStmt, 0);
if( rc ) goto dbtotxt_error;
rc = 0;
if( sqlite3_step(pStmt)!=SQLITE_ROW ) goto dbtotxt_error;
nPage = sqlite3_column_int64(pStmt, 0);
sqlite3_finalize(pStmt);
pStmt = 0;
if( nPage<1 ) goto dbtotxt_error;
rc = sqlite3_prepare_v2(p->db, "PRAGMA databases", -1, &pStmt, 0);
if( rc ) goto dbtotxt_error;
rc = 0;
if( sqlite3_step(pStmt)!=SQLITE_ROW ){
zTail = zFilename = "unk.db";
}else{
zFilename = (const char*)sqlite3_column_text(pStmt, 2);
if( zFilename==0 || zFilename[0]==0 ) zFilename = "unk.db";
zTail = strrchr(zFilename, '/');
#if defined(_WIN32)
if( zTail==0 ) zTail = strrchr(zFilename, '\\');
#endif
if( zTail ) zFilename = zTail;
}
zName = strdup(zTail);
shell_check_oom(zName);
sqlite3_fprintf(p->out, "| size %lld pagesize %d filename %s\n",
nPage*pgSz, pgSz, zName);
sqlite3_finalize(pStmt);
pStmt = 0;
rc = sqlite3_prepare_v2(p->db,
"SELECT pgno, data FROM sqlite_dbpage ORDER BY pgno", -1, &pStmt, 0);
if( rc ) goto dbtotxt_error;
rc = 0;
while( sqlite3_step(pStmt)==SQLITE_ROW ){
sqlite3_int64 pgno = sqlite3_column_int64(pStmt, 0);
const u8 *aData = sqlite3_column_blob(pStmt, 1);
int seenPageLabel = 0;
for(i=0; i<pgSz; i+=16){
const u8 *aLine = aData+i;
for(j=0; j<16 && aLine[j]==0; j++){}
if( j==16 ) continue;
if( !seenPageLabel ){
sqlite3_fprintf(p->out, "| page %lld offset %lld\n", pgno, pgno*pgSz);
seenPageLabel = 1;
}
sqlite3_fprintf(p->out, "| %5d:", i);
for(j=0; j<16; j++) sqlite3_fprintf(p->out, " %02x", aLine[j]);
sqlite3_fprintf(p->out, " ");
for(j=0; j<16; j++){
unsigned char c = (unsigned char)aLine[j];
sqlite3_fprintf(p->out, "%c", bShow[c]);
}
sqlite3_fprintf(p->out, "\n");
}
}
sqlite3_finalize(pStmt);
sqlite3_fprintf(p->out, "| end %s\n", zName);
free(zName);
return 0;
dbtotxt_error:
if( rc ){
sqlite3_fprintf(stderr, "ERROR: %s\n", sqlite3_errmsg(p->db));
}
sqlite3_finalize(pStmt);
free(zName);
return 1;
}
/*
** Print the given string as an error message.
*/
@ -8799,6 +8895,10 @@ static int do_meta_command(char *zLine, ShellState *p){
}
}else
if( c=='d' && n>=3 && cli_strncmp(azArg[0], "dbtotxt", n)==0 ){
rc = shell_dbtotxt_command(p, nArg, azArg);
}else
if( c=='e' && cli_strncmp(azArg[0], "eqp", n)==0 ){
if( nArg==2 ){
p->autoEQPtest = 0;
@ -12137,7 +12237,10 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
}
static void echo_group_input(ShellState *p, const char *zDo){
if( ShellHasFlag(p, SHFLG_Echo) ) sqlite3_fprintf(p->out, "%s\n", zDo);
if( ShellHasFlag(p, SHFLG_Echo) ){
sqlite3_fprintf(p->out, "%s\n", zDo);
fflush(p->out);
}
}
#ifdef SQLITE_SHELL_FIDDLE
@ -13176,15 +13279,10 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
char *zHome;
char *zHistory;
int nHistory;
#if CIO_WIN_WC_XLATE
# define SHELL_CIO_CHAR_SET (stdout_is_console? " (UTF-16 console I/O)" : "")
#else
# define SHELL_CIO_CHAR_SET ""
#endif
sqlite3_fprintf(stdout,
"SQLite version %s %.19s%s\n" /*extra-version-info*/
"SQLite version %s %.19s\n" /*extra-version-info*/
"Enter \".help\" for usage hints.\n",
sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET);
sqlite3_libversion(), sqlite3_sourceid());
if( warnInmemoryDb ){
sputz(stdout, "Connected to a ");
printBold("transient in-memory database");

@ -1100,6 +1100,11 @@ struct sqlite3_io_methods {
** pointed to by the pArg argument. This capability is used during testing
** and only needs to be supported when SQLITE_TEST is defined.
**
** <li>[[SQLITE_FCNTL_NULL_IO]]
** The [SQLITE_FCNTL_NULL_IO] opcode sets the low-level file descriptor
** or file handle for the [sqlite3_file] object such that it will no longer
** read or write to the database file.
**
** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
** be advantageous to block on the next WAL lock if the lock is not immediately
@ -1253,6 +1258,7 @@ struct sqlite3_io_methods {
#define SQLITE_FCNTL_EXTERNAL_READER 40
#define SQLITE_FCNTL_CKSM_FILE 41
#define SQLITE_FCNTL_RESET_CACHE 42
#define SQLITE_FCNTL_NULL_IO 43
/* deprecated names */
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
@ -2631,10 +2637,14 @@ void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
** deleted by the most recently completed INSERT, UPDATE or DELETE
** statement on the database connection specified by the only parameter.
** The two functions are identical except for the type of the return value
** and that if the number of rows modified by the most recent INSERT, UPDATE
** and that if the number of rows modified by the most recent INSERT, UPDATE,
** or DELETE is greater than the maximum value supported by type "int", then
** the return value of sqlite3_changes() is undefined. ^Executing any other
** type of SQL statement does not modify the value returned by these functions.
** For the purposes of this interface, a CREATE TABLE AS SELECT statement
** does not count as an INSERT, UPDATE or DELETE statement and hence the rows
** added to the new table by the CREATE TABLE AS SELECT statement are not
** counted.
**
** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
** considered - auxiliary changes caused by [CREATE TRIGGER | triggers],

@ -4037,9 +4037,12 @@ static const char *tclsh_main_loop(void){
"if {[file exists $arg]} {\n"
"lappend new $arg\n"
"} else {\n"
"set once 0\n"
"foreach match [lsort [glob -nocomplain $arg]] {\n"
"lappend new $match\n"
"set once 1\n"
"}\n"
"if {!$once} {lappend new $arg}\n"
"}\n"
"}\n"
"set argv $new\n"

@ -1670,6 +1670,7 @@ static void windowAggStep(
int regArg;
int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin);
int i;
int addrIf = 0;
assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED );
@ -1686,6 +1687,18 @@ static void windowAggStep(
}
regArg = reg;
if( pWin->pFilter ){
int regTmp;
assert( ExprUseXList(pWin->pOwner) );
assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr );
assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 );
regTmp = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, regTmp);
}
if( pMWin->regStartRowid==0
&& (pFunc->funcFlags & SQLITE_FUNC_MINMAX)
&& (pWin->eStart!=TK_UNBOUNDED)
@ -1705,25 +1718,13 @@ static void windowAggStep(
}
sqlite3VdbeJumpHere(v, addrIsNull);
}else if( pWin->regApp ){
assert( pWin->pFilter==0 );
assert( pFunc->zName==nth_valueName
|| pFunc->zName==first_valueName
);
assert( bInverse==0 || bInverse==1 );
sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
}else if( pFunc->xSFunc!=noopStepFunc ){
int addrIf = 0;
if( pWin->pFilter ){
int regTmp;
assert( ExprUseXList(pWin->pOwner) );
assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr );
assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 );
regTmp = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
VdbeCoverage(v);
sqlite3ReleaseTempReg(pParse, regTmp);
}
if( pWin->bExprArgs ){
int iOp = sqlite3VdbeCurrentAddr(v);
int iEnd;
@ -1754,8 +1755,9 @@ static void windowAggStep(
if( pWin->bExprArgs ){
sqlite3ReleaseTempRange(pParse, regArg, nArg);
}
if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
}
if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
}
}

310
test/fork-test.c Normal file

@ -0,0 +1,310 @@
/*
** The program demonstrates how a child process created using fork()
** can continue to use SQLite for a database that the parent had opened and
** and was writing into when the fork() occurred.
**
** This program executes the following steps:
**
** 1. Create a new database file. Open it, and populate it.
** 2. Start a transaction and make changes.
** ^-- close the transaction prior to fork() if --commit-before-fork
** 3. Fork()
** 4. In the child, close the database connection. Special procedures
** are needed to close the database connection in the child. See the
** implementation below.
** 5. Commit the transaction in the parent.
** 6. Verify that the transaction committed in the parent.
** 7. In the child, after a delay to allow time for (5) and (6),
** open a new database connection and verify that the transaction
** committed by (5) is seen.
** 8. Add make further changes and commit them in the child, using the
** new database connection.
** 9. In the parent, after a delay to account for (8), verify that
** the new transaction added by (8) can be seen.
**
** Usage:
**
** fork-test FILENAME [options]
**
** Options:
**
** --wal Run the database in WAL mode
** --vfstrace Enable VFS tracing for debugging
** --commit-before-fork COMMIT prior to the fork() in step 3
** --delay-after-4 N Pause for N seconds after step 4
**
** How To Compile:
**
** gcc -O0 -g -Wall -I$(SQLITESRC) \
** f1.c $(SQLITESRC)/ext/misc/vfstrace.c $(SQLITESRC/sqlite3.c \
** -ldl -lpthread -lm
**
** Test procedure:
**
** (1) Run "fork-test x1.db". Verify no I/O errors occur and that
** both parent and child see all three rows in the t1 table.
**
** (2) Repeat (1) adding the --wal option.
**
** (3) Repeat (1) and (2) adding the --commit-before-fork option.
**
** (4) Repeat all prior steps adding the --delay-after-4 option with
** a timeout of 15 seconds or so. Then, while both parent and child
** are paused, run the CLI against the x1.db database from a separate
** window and verify that all the correct file locks are still working
** correctly.
**
** Take-Aways:
**
** * If a process has open SQLite database connections when it fork()s,
** the child can call exec() and all it well. Nothing special needs
** to happen.
**
** * If a process has open SQLite database connections when it fork()s,
** the child can do anything that does not involve using SQLite without
** causing problems in the parent. No special actions are needed in
** the child.
**
** * If a process has open SQLite database connections when it fork()s,
** the child can call sqlite3_close() on those database connections
** as long as there were no pending write transactions when the fork()
** occurred.
**
** * If a process has open SQLite database connections that are in the
** middle of a write transaction and then the processes fork()s, the
** child process should close the database connections using the
** procedures demonstrated in Step 4 below before trying to do anything
** else with SQLite.
**
** * If a child process can safely close SQLite database connections that
** it inherited via fork() using the procedures shown in Step 4 below
** even if the database connections were not involved in a write
** transaction at the time of the fork(). The special procedures are
** required if a write transaction was active. They are optional
** otherwise. No harm results from using the special procedures when
** they are not necessary.
**
** * Child processes that use SQLite should open their own database
** connections. They should not attempt to use a database connection
** that is inherited from the parent.
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include "sqlite3.h"
/*
** Process ID of the parent
*/
static pid_t parentPid = 0;
/*
** Return either "parent" or "child", as appropriate.
*/
static const char *whoAmI(void){
return getpid()==parentPid ? "parent" : "child";
}
/*
** This is an sqlite3_exec() callback routine that prints all results.
*/
static int execCallback(void *pNotUsed, int nCol, char **aVal, char **aCol){
int i;
const char *zWho = whoAmI();
for(i=0; i<nCol; i++){
const char *zVal = aVal[i];
const char *zCol = aCol[i];
if( zVal==0 ) zVal = "NULL";
if( zCol==0 ) zCol = "NULL";
printf("%s: %s = %s\n", zWho, zCol, zVal);
fflush(stdout);
}
return 0;
}
/*
** Execute one or more SQL statements.
*/
static void sqlExec(sqlite3 *db, const char *zSql, int bCallback){
int rc;
char *zErr = 0;
printf("%s: %s\n", whoAmI(), zSql);
fflush(stdout);
rc = sqlite3_exec(db, zSql, bCallback ? execCallback : 0, 0, &zErr);
if( rc || zErr!=0 ){
printf("%s: %s: rc=%d: %s\n",
whoAmI(), zSql, rc, zErr);
exit(1);
}
}
/*
** Trace callback for the vfstrace extension.
*/
static int vfsTraceCallback(const char *zMsg, void *pNotUsed){
printf("%s: %s", whoAmI(), zMsg);
fflush(stdout);
return 0;
}
/* External VFS module provided by ext/misc/vfstrace.c
*/
extern int vfstrace_register(
const char *zTraceName, // Name of the newly constructed VFS
const char *zOldVfsName, // Name of the underlying VFS
int (*xOut)(const char*,void*), // Output routine. ex: fputs
void *pOutArg, // 2nd argument to xOut. ex: stderr
int makeDefault // Make the new VFS the default
);
int main(int argc, char **argv){
sqlite3 *db;
int rc;
int i;
int useWal = 0;
const char *zFilename = 0;
pid_t child = 0, c2;
int status;
int bCommitBeforeFork = 0;
int nDelayAfter4 = 0;
for(i=1; i<argc; i++){
const char *z = argv[i];
if( z[0]=='-' && z[1]=='-' && z[2]!=0 ) z++;
if( strcmp(z, "-wal")==0 ){
useWal = 1;
}else if( strcmp(z, "-commit-before-fork")==0 ){
bCommitBeforeFork = 1;
}else if( strcmp(z, "-delay-after-4")==0 && i+1<argc ){
i++;
nDelayAfter4 = atoi(argv[i]);
}else if( strcmp(z, "-vfstrace")==0 ){
vfstrace_register("vfstrace", 0, vfsTraceCallback, 0, 1);
}else if( z[0]=='-' ){
printf("unknown option: \"%s\"\n", argv[i]);
exit(1);
}else if( zFilename!=0 ){
printf("unknown argument: \"%s\"\n", argv[i]);
exit(1);
}else{
zFilename = argv[i];
}
}
if( zFilename==0 ){
printf("Usage: %s FILENAME\n", argv[0]);
return 1;
}
/** Step 1 **/
printf("Step 1:\n");
parentPid = getpid();
unlink(zFilename);
rc = sqlite3_open(zFilename, &db);
if( rc ){
printf("sqlite3_open() returns %d\n", rc);
exit(1);
}
if( useWal ){
sqlExec(db, "PRAGMA journal_mode=WAL;", 0);
}
sqlExec(db, "CREATE TABLE t1(x);", 0);
sqlExec(db, "INSERT INTO t1 VALUES('First row');", 0);
sqlExec(db, "SELECT x FROM t1;", 1);
/** Step 2 **/
printf("Step 2:\n");
sqlExec(db, "BEGIN IMMEDIATE;", 0);
sqlExec(db, "INSERT INTO t1 VALUES('Second row');", 0);
sqlExec(db, "SELECT x FROM t1;", 1);
if( bCommitBeforeFork ) sqlExec(db, "COMMIT", 0);
/** Step 3 **/
printf("Step 3:\n"); fflush(stdout);
child = fork();
if( child!=0 ){
printf("Parent = %d\nChild = %d\n", getpid(), child);
}
/** Step 4 **/
if( child==0 ){
int k;
printf("Step 4:\n"); fflush(stdout);
/***********************************************************************
** The following block of code closes the database connection without
** rolling back or changing any files on disk. This is necessary to
** preservce the pending transaction in the parent.
*/
for(k=0; 1/*exit-by-break*/; k++){
const char *zDbName = sqlite3_db_name(db, k);
sqlite3_file *pJrnl = 0;
if( k==1 ) continue;
if( zDbName==0 ) break;
sqlite3_file_control(db, zDbName, SQLITE_FCNTL_NULL_IO, 0);
sqlite3_file_control(db, zDbName, SQLITE_FCNTL_JOURNAL_POINTER, &pJrnl);
if( pJrnl && pJrnl->pMethods && pJrnl->pMethods->xFileControl ){
pJrnl->pMethods->xFileControl(pJrnl, SQLITE_FCNTL_NULL_IO, 0);
}
}
sqlite3_close(db);
/*
** End of special close procedures for SQLite database connections
** inherited via fork().
***********************************************************************/
printf("%s: database connection closed\n", whoAmI()); fflush(stdout);
}else{
/* Pause the parent briefly to give the child a chance to close its
** database connection */
sleep(1);
}
if( nDelayAfter4>0 ){
printf("%s: Delay for %d seconds\n", whoAmI(), nDelayAfter4);
fflush(stdout);
sleep(nDelayAfter4);
printf("%s: Continue after %d delay\n", whoAmI(), nDelayAfter4);
fflush(stdout);
}
/** Step 5 **/
if( child!=0 ){
printf("Step 5:\n");
if( !bCommitBeforeFork ) sqlExec(db, "COMMIT", 0);
sqlExec(db, "SELECT x FROM t1;", 1);
}
/** Step 7 **/
if( child==0 ){
sleep(2);
printf("Steps 7 and 8:\n");
rc = sqlite3_open(zFilename, &db);
if( rc ){
printf("Child unable to reopen the database. rc = %d\n", rc);
exit(1);
}
sqlExec(db, "SELECT * FROM t1;", 1);
/** Step 8 **/
sqlExec(db, "INSERT INTO t1 VALUES('Third row');", 0);
sqlExec(db, "SELECT * FROM t1;", 1);
sleep(1);
return 0;
}
c2 = wait(&status);
printf("Process %d finished with status %d\n", c2, status);
/** Step 9 */
if( child!=0 ){
printf("Step 9:\n");
sqlExec(db, "SELECT * FROM t1;", 1);
}
return 0;
}

@ -489,6 +489,68 @@ execsql_test 9.2 {
FROM t1
}
==========
execsql_test 10.0 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a INTEGER, b INTEGER);
INSERT INTO t1 VALUES (10, 1),
(20, -1),
(5, 2),
(15, 0),
(25, 3);
}
execsql_test 10.1 {
SELECT
a, b, MIN(a) FILTER(WHERE b > 0) OVER win
FROM t1
WINDOW win AS (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING);
}
execsql_test 10.2 {
SELECT
a, b, MIN(a) FILTER(WHERE b > 0) OVER win
FROM t1
WINDOW win AS ();
}
execsql_test 10.3 {
SELECT
a, b, MIN(a) FILTER(WHERE b > 0) OVER win
FROM t1
WINDOW win AS (ORDER BY a);
}
execsql_test 10.4 {
SELECT
a, b, MIN(a) OVER win
FROM t1
WINDOW win AS (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING);
}
==========
execsql_test 11.0 {
DROP TABLE IF EXISTS t2;
CREATE TABLE t2(a INTEGER, b INTEGER);
INSERT INTO t2 VALUES(1, 12);
INSERT INTO t2 VALUES(2, 10);
INSERT INTO t2 VALUES(3, 15);
INSERT INTO t2 VALUES(4, 22);
INSERT INTO t2 VALUES(5, 1);
INSERT INTO t2 VALUES(6, 4);
INSERT INTO t2 VALUES(7, 7);
INSERT INTO t2 VALUES(8, 6);
INSERT INTO t2 VALUES(9, 22);
INSERT INTO t2 VALUES(10, 2);
}
execsql_test 11.1 {
SELECT a, min(b) FILTER (WHERE a%2 != 0) OVER win
FROM t2
WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING);
}
finish_test

@ -6540,4 +6540,67 @@ do_execsql_test 9.2 {
FROM t1
} {}
#==========================================================================
do_execsql_test 10.0 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a INTEGER, b INTEGER);
INSERT INTO t1 VALUES (10, 1),
(20, -1),
(5, 2),
(15, 0),
(25, 3);
} {}
do_execsql_test 10.1 {
SELECT
a, b, MIN(a) FILTER(WHERE b > 0) OVER win
FROM t1
WINDOW win AS (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING);
} {5 2 5 10 1 5 15 0 10 20 -1 25 25 3 25}
do_execsql_test 10.2 {
SELECT
a, b, MIN(a) FILTER(WHERE b > 0) OVER win
FROM t1
WINDOW win AS ();
} {10 1 5 20 -1 5 5 2 5 15 0 5 25 3 5}
do_execsql_test 10.3 {
SELECT
a, b, MIN(a) FILTER(WHERE b > 0) OVER win
FROM t1
WINDOW win AS (ORDER BY a);
} {5 2 5 10 1 5 15 0 5 20 -1 5 25 3 5}
do_execsql_test 10.4 {
SELECT
a, b, MIN(a) OVER win
FROM t1
WINDOW win AS (ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING);
} {5 2 5 10 1 5 15 0 10 20 -1 15 25 3 20}
#==========================================================================
do_execsql_test 11.0 {
DROP TABLE IF EXISTS t2;
CREATE TABLE t2(a INTEGER, b INTEGER);
INSERT INTO t2 VALUES(1, 12);
INSERT INTO t2 VALUES(2, 10);
INSERT INTO t2 VALUES(3, 15);
INSERT INTO t2 VALUES(4, 22);
INSERT INTO t2 VALUES(5, 1);
INSERT INTO t2 VALUES(6, 4);
INSERT INTO t2 VALUES(7, 7);
INSERT INTO t2 VALUES(8, 6);
INSERT INTO t2 VALUES(9, 22);
INSERT INTO t2 VALUES(10, 2);
} {}
do_execsql_test 11.1 {
SELECT a, min(b) FILTER (WHERE a%2 != 0) OVER win
FROM t2
WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING);
} {1 12 2 12 3 1 4 1 5 1 6 1 7 1 8 7 9 7 10 22}
finish_test

@ -282,4 +282,62 @@ do_catchsql_test 9.1 {
FROM t1
} {1 {frame ending offset must be a non-negative number}}
#--------------------------------------------------------------------------
reset_db
do_execsql_test 10.0 {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 'a');
INSERT INTO t1 VALUES(2, 'b');
INSERT INTO t1 VALUES(3, 'c');
INSERT INTO t1 VALUES(4, 'd');
INSERT INTO t1 VALUES(5, 'e');
INSERT INTO t1 VALUES(6, 'f');
}
do_execsql_test 10.1 {
SELECT a, min(b) OVER win
FROM t1
WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING)
} {
1 a
2 a
3 a
4 b
5 c
6 d
}
do_execsql_test 10.2 {
SELECT a, min(b) FILTER (WHERE a%2) OVER win
FROM t1
WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING)
} {
1 a
2 a
3 a
4 c
5 c
6 e
}
do_execsql_test 10.3 {
SELECT a, min(b) FILTER (WHERE (a%2)=0) OVER win
FROM t1
WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING)
} {
1 b
2 b
3 b
4 b
5 d
6 d
}
do_catchsql_test 10.4 {
SELECT a, nth_value(b, 1) FILTER (WHERE (a%2)=0) OVER win
FROM t1
WINDOW win AS (ORDER BY a ROWS BETWEEN 2 PRECEDING AND 1 FOLLOWING)
} {1 {FILTER clause may only be used with aggregate window functions}}
finish_test

@ -15,6 +15,7 @@ Options:
--info Show info on existing SQLite TCL extension installs
--install-only Install an extension previously build
--uninstall Uninstall the extension
--destdir DIR Installation root (used by "make install DESTDIR=...")
Other options are retained and passed through into the compiler.}
@ -25,6 +26,7 @@ set uninstall 0
set infoonly 0
set CC {}
set OPTS {}
set DESTDIR ""; # --destdir "$(DESTDIR)"
for {set ii 0} {$ii<[llength $argv]} {incr ii} {
set a0 [lindex $argv $ii]
if {$a0=="--install-only"} {
@ -42,6 +44,9 @@ for {set ii 0} {$ii<[llength $argv]} {incr ii} {
} elseif {$a0=="--cc" && $ii+1<[llength $argv]} {
incr ii
set CC [lindex $argv $ii]
} elseif {$a0=="--destdir" && $ii+1<[llength $argv]} {
incr ii
set DESTDIR [lindex $argv $ii]
} elseif {[string match -* $a0]} {
append OPTS " $a0"
} else {
@ -107,7 +112,7 @@ if {$tcl_platform(platform)=="windows"} {
set fd [open $LIBDIR/tclConfig.sh rb]
set tclConfig [read $fd]
close $fd
# Extract parameter we will need from the tclConfig.sh file
#
set TCLMAJOR 8
@ -140,14 +145,17 @@ if {$tcl_platform(platform)=="windows"} {
if {[string length $OPTS]>1} {
append LDFLAGS $OPTS
}
set CMD [subst $cmd]
if {$TCLMAJOR>8} {
set OUT libtcl9sqlite$VERSION.$SUFFIX
} else {
set OUT libsqlite$VERSION.$SUFFIX
}
set @ $OUT; # Workaround for https://sqlite.org/forum/forumpost/0683a49cb02f31a1
# in which Gentoo edits their tclConfig.sh to include an soname
# linker flag which includes ${@} (the target file's name).
set CMD [subst $cmd]
}
# Show information about prior installs
#
if {$infoonly} {
@ -193,7 +201,15 @@ if {$install} {
#
set DEST {}
foreach dir $auto_path {
if {[file writable $dir]} {
if {[string match //*:* $dir]} {
# We can't install to //zipfs: paths
continue
} elseif {"" ne $DESTDIR && ![file writable $DESTDIR]} {
continue
}
set dir ${DESTDIR}$dir
if {[file writable $dir] || "" ne $DESTDIR} {
# the dir will be created later ^^^^^^^^
set DEST $dir
break
} elseif {[glob -nocomplain $dir/sqlite3*/pkgIndex.tcl]!=""} {
@ -211,7 +227,7 @@ if {$install} {
puts "to work around this problem.\n"
puts "These are the (unwritable) \$auto_path directories:\n"
foreach dir $auto_path {
puts " * $dir"
puts " * ${DESTDIR}$dir"
}
exit 1
}