1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Merge recent trunk changes into the wal2 branch.

FossilOrigin-Name: 720d175478e05921d97c561ca6883d0531188804009f388954fdb54642dec1e5
This commit is contained in:
drh
2025-05-19 16:52:04 +00:00
36 changed files with 881 additions and 636 deletions

View File

@@ -1,5 +1,9 @@
all:
#
# Unless this file is named Makefile.in, you are probably looking
# at an automatically generated/filtered copy and should probably not
# edit it.
#
# This makefile is part of the teaish framework, a tool for building
# Tcl extensions, conceptually related to TEA/tclconfig but using the
# Autosetup configuration system instead of the GNU Autotools.
@@ -47,6 +51,12 @@ tx.dll8 = @TEAISH_DLL8@
tx.dll9 = @TEAISH_DLL9@
tx.dll = $(tx.dll$(TCL_MAJOR_VERSION))
tx.dir = @TEAISH_EXT_DIR@
@if TEAISH_TM_TCL
# Input filename for tcl::tm-style module
tx.tm = @TEAISH_TM_TCL@
# Target filename for tcl::tm-style installation
tx.tm.tgt = $(tx.name.pkg)-$(tx.version).tm
@endif
@if TEAISH_DIST_NAME
tx.name.dist = @TEAISH_DIST_NAME@
@@ -157,23 +167,12 @@ tx.LDFLAGS =
#
tx.dist.files = @TEAISH_DIST_FILES@
#
# May get amended with generated file names. They are cleaned up by
# the 'clean' rules. Client code which wants to clean up extra stuff
# should do so by adding their cleanup target (e.g. clean-extension)
# as a dependency to the 'clean' target, like so:
#
# clean: distclean-extension
# distclean: distclean-extension
#
teaish__cleanExtra =
# List of deps which may trigger an auto-reconfigure.
#
teaish__autogen.deps = \
$(tx.makefile.in) $(teaish.makefile.in) \
$(tx.tcl) \
@TEAISH_PKGINDEX_TCL_IN@ \
@TEAISH_PKGINDEX_TCL_IN@ @TEAISH_TM_TCL_IN@ \
@AUTODEPS@
@if TEAISH_MAKEFILE_IN
@@ -271,10 +270,10 @@ test: test-post
# Cleanup rules...
#
#.PHONY: clean-pre clean-core clean-post clean-extension
clean-extension: # this name is reserved for use by teaish.make
#
clean-pre:
clean-core: clean-pre
rm -f $(tx.dll8) $(tx.dll9) tclsh $(teaish__cleanExtra)
rm -f $(tx.dll8) $(tx.dll9) tclsh
clean-post: clean-core
clean: clean-post
@@ -300,26 +299,59 @@ distclean-core: distclean-pre
@if TEAISH_TEST_TCL_IN
rm -f @TEAISH_TEST_TCL@
@endif
distclean-extension: # this name is reserved for use by teaish.make
distclean-post: distclean-core
distclean: distclean-post
#
# The (dist)clean-extension targets are reserved for use by
# client-side teaish.make.
#
# Client code which wants to clean up extra stuff should do so by
# adding their cleanup target (e.g. clean-extension) as a dependency
# to the 'clean' target, like so:
#
# clean: distclean-extension
# distclean: distclean-extension
#
distclean-extension:
clean-extension:
#
# Installation rules...
#
@if TEAISH_ENABLE_INSTALL
.PHONY: install-pre install-core install-post install-test install-prepre install-extension
install-extension: # this name is reserved for use by teaish.make
@if TEAISH_ENABLE_DLL
install-prepre: $(tx.dll)
@else
install-prepre:
@endif
@if TEAISH_TM_TCL
install-core.tmdir = $(DESTDIR)@TEAISH_TCL_TM_DIR@
@endif
install-pre: install-prepre
install-core: install-pre
@if [ ! -d "$(DESTDIR)$(TCLLIBDIR)" ]; then \
set -x; $(INSTALL) -d "$(DESTDIR)$(TCLLIBDIR)"; \
fi
# ^^^^ on some platforms, install -d fails if the target already exists.
@if TEAISH_ENABLE_DLL
$(INSTALL) $(tx.dll) "$(DESTDIR)$(TCLLIBDIR)"
$(INSTALL.noexec) pkgIndex.tcl "$(DESTDIR)$(TCLLIBDIR)"
@endif
@if TEAISH_PKGINDEX_TCL
$(INSTALL.noexec) "@TEAISH_PKGINDEX_TCL@" "$(DESTDIR)$(TCLLIBDIR)"
@endif
@if TEAISH_PKGINIT_TCL
$(INSTALL.noexec) @TEAISH_PKGINIT_TCL@ "$(DESTDIR)$(TCLLIBDIR)"
$(INSTALL.noexec) "@TEAISH_PKGINIT_TCL@" "$(DESTDIR)$(TCLLIBDIR)"
@endif
@if TEAISH_TM_TCL
@if [ ! -d "$(install-core.tmdir)" ]; then \
set -x; $(INSTALL) -d "$(install-core.tmdir)"; \
fi
$(INSTALL.noexec) "@TEAISH_TM_TCL@" "$(install-core.tmdir)/$(tx.tm.tgt)"
@endif
install-test: install-core
@echo "Post-install test of [package require $(tx.name.pkg) $(tx.version)]..."; \
@@ -344,10 +376,17 @@ install: install-post
uninstall-extension: # this name is reserved for use by teaish.make
uninstall-pre:
uninstall-core: uninstall-pre
@if TEAISH_ENABLE_DLL
rm -fr "$(DESTDIR)$(TCLLIBDIR)"
@endif
@if TEAISH_TM_TCL
rm -f "$(DESTDIR)$(install-core.tmdir)/$(tx.tm.tgt)"
@endif
uninstall-post: uninstall-core
@echo "Uninstalled Tcl extension $(tx.name) $(tx.version)"
uninstall: uninstall-post
@endif # TEAISH_ENABLE_INSTALL
@if TEAISH_MAKEFILE_IN
Makefile: $(tx.makefile.in)

View File

@@ -1,6 +1,6 @@
# -*- tcl -*-
#
# Unless this file is named teaish.tester.tcl.in, you are probably
# Unless this file is named _teaish.tester.tcl.in, you are probably
# looking at an automatically generated/filtered copy and should
# probably not edit it.
#
@@ -28,6 +28,12 @@ apply {{file} {
source -encoding utf-8 $file
}} [join {@TEAISH_PKGINIT_TCL@}]
@endif
@if TEAISH_TM_TCL
apply {{file} {
set dir [file dirname $::argv0]
source -encoding utf-8 $file
}} [join {@TEAISH_TM_TCL@}]
@endif
@if TEAISH_TEST_TCL
apply {{file} {
# Populate state for [tester.tcl::teaish-build-flag*]

View File

@@ -117,7 +117,7 @@ proc teaish-options {} {
# work needed for this extension.
#
proc teaish-configure {} {
use teaish/feature-tests
use teaish/feature
teaish-src-add -dist -dir generic/tclsqlite3.c

View File

@@ -60,8 +60,8 @@
# $proj__Config is an internal-use-only array for storing whatever generic
# internal stuff we need stored.
#
array set proj__Config {
self-tests 0
array set ::proj__Config {
self-tests 1
}
@@ -74,8 +74,8 @@ array set proj__Config {
#
# See: proj-dot-ins-append and proj-dot-ins-process
#
set proj__Config(dot-in-files) [list]
set proj__Config(isatty) [isatty? stdout]
set ::proj__Config(dot-in-files) [list]
set ::proj__Config(isatty) [isatty? stdout]
#
# @proj-warn msg
@@ -88,6 +88,25 @@ proc proj-warn {args} {
puts stderr [join [list "WARNING: \[[proj-scope 1]\]: " {*}$args] " "]
}
# Internal impl of [proj-fatal] and [proj-error]. It must be called
# using tailcall.
proc proj__faterr {failMode argv} {
show-notices
set lvl 1
while {"-up" eq [lindex $argv 0]} {
set argv [lassign $argv -]
incr lvl
}
if {$failMode} {
puts stderr [join [list "FATAL: \[[proj-scope $lvl]]: " {*}$argv]]
exit 1
} else {
error [join [list "\[[proj-scope $lvl]]:" {*}$argv]]
}
}
#
# @proj-fatal ?-up...? msg...
#
@@ -99,31 +118,19 @@ proc proj-warn {args} {
# additional level.
#
proc proj-fatal {args} {
show-notices
set lvl 1
while {"-up" eq [lindex $args 0]} {
set args [lassign $args -]
incr lvl
}
puts stderr [join [list "FATAL: \[[proj-scope $lvl]]: " {*}$args]]
exit 1
tailcall proj__faterr 1 $args
}
#
# @proj-error ?-up...? msg...
#
# Works like prop-fatal but uses [error] intead of [exit].
# Works like proj-fatal but uses [error] intead of [exit].
#
proc proj-error {args} {
show-notices
set lvl 1
while {"-up" eq [lindex $args 0]} {
set args [lassign $args -]
incr lvl
}
error [join [list "\[[proj-scope $lvl]]:" {*}$args]]
tailcall proj__faterr 0 $args
}
set ::proj__Config(verbose-assert) [get-env proj-assert-verbose 0]
#
# @proj-assert script ?message?
#
@@ -133,7 +140,7 @@ proc proj-error {args} {
# used instead.
#
proc proj-assert {script {msg ""}} {
if {1 == [get-env proj-assert 0]} {
if {1 eq $::proj__Config(verbose-assert)} {
msg-result [proj-bold "asserting: $script"]
}
if {![uplevel 1 [list expr $script]]} {
@@ -162,7 +169,9 @@ proc proj-bold {args} {
# @proj-indented-notice ?-error? ?-notice? msg
#
# Takes a multi-line message and emits it with consistent indentation.
# It does not perform any line-wrapping of its own.
# It does not perform any line-wrapping of its own. Which output
# routine it uses depends on its flags, defaulting to msg-result.
# For -error and -notice it uses user-notice.
#
# If the -notice flag it used then it emits using [user-notice], which
# means its rendering will (A) go to stderr and (B) be delayed until
@@ -176,7 +185,7 @@ proc proj-bold {args} {
#
proc proj-indented-notice {args} {
set fErr ""
set outFunc "puts"
set outFunc "msg-result"
while {[llength $args] > 1} {
switch -exact -- [lindex $args 0] {
-error {
@@ -632,7 +641,7 @@ proc proj-no-check-module-loader {} {
}
#
# @proj-file-conent ?-trim? filename
# @proj-file-content ?-trim? filename
#
# Opens the given file, reads all of its content, and returns it. If
# the first arg is -trim, the contents of the file named by the second
@@ -701,10 +710,10 @@ proc proj-file-write {args} {
# argument it is assumed to be the name of an autosetup boolean config
# which controls whether to run/skip this check.
#
# Returns 1 if supported, else 0. Defines MAKE_COMPILATION_DB to "yes"
# if supported, "no" if not. The use of MAKE_COMPILATION_DB is
# deprecated/discouraged. It also sets HAVE_COMPILE_COMMANDS to 0 or
# 1, and that's the preferred usage.
# Returns 1 if supported, else 0, and defines HAVE_COMPILE_COMMANDS to
# that value. Defines MAKE_COMPILATION_DB to "yes" if supported, "no"
# if not. The use of MAKE_COMPILATION_DB is deprecated/discouraged:
# HAVE_COMPILE_COMMANDS is preferred.
#
# ACHTUNG: this test has a long history of false positive results
# because of compilers reacting differently to the -MJ flag.
@@ -713,6 +722,7 @@ proc proj-check-compile-commands {{configFlag {}}} {
msg-checking "compile_commands.json support... "
if {"" ne $configFlag && ![proj-opt-truthy $configFlag]} {
msg-result "explicitly disabled"
define HAVE_COMPILE_COMMANDS 0
define MAKE_COMPILATION_DB no
return 0
} else {
@@ -787,7 +797,12 @@ proc proj-make-from-dot-in {args} {
catch { exec chmod u+w $fOut }
}
#puts "making template: $fIn ==> $fOut"
make-template $fIn $fOut
#define-push {top_srcdir} {
#puts "--- $fIn $fOut top_srcdir=[get-define top_srcdir]"
make-template $fIn $fOut
#puts "--- $fIn $fOut top_srcdir=[get-define top_srcdir]"
# make-template modifies top_srcdir
#}
if {$touch} {
proj-touch $fOut
}
@@ -1220,7 +1235,7 @@ proc proj-quote-str_ {value} {
# the formatted value or the value $::proj__Config(defs-skip) if the caller
# should skip emitting that value.
#
set proj__Config(defs-skip) "-proj-defs-format_ sentinel"
set ::proj__Config(defs-skip) "-proj-defs-format_ sentinel"
proc proj-defs-format_ {type value} {
switch -exact -- $type {
-bare {
@@ -1258,6 +1273,8 @@ proc proj-defs-format_ {type value} {
return $value
}
#
# @proj-dump-defs-json outfile ...flags
#
# This function works almost identically to autosetup's
# make-config-header but emits its output in JSON form. It is not a
@@ -1954,10 +1971,12 @@ if {0} {
array set proj__Cache {}
#
# @proj-cache-key ?addLevel? arg
# @proj-cache-key arg {addLevel 0}
#
# Helper to generate cache keys for [proj-cache-*].
#
# $addLevel should almost always be 0.
#
# Returns a cache key for the given argument:
#
# integer: relative call stack levels to get the scope name of for
@@ -1965,12 +1984,9 @@ array set proj__Cache {}
# then used to generate the key. i.e. the default of 0 uses the
# calling scope's name as the key.
#
# "-": same as 0
#
# Anything else: returned as-is
#
proc proj-cache-key {{addLevel 0} arg} {
if {"-" eq $arg} {set arg 0}
proc proj-cache-key {arg {addLevel 0}} {
if {[string is integer -strict $arg]} {
return [proj-scope [expr {$arg + $addLevel + 1}]]
}
@@ -1978,14 +1994,19 @@ proc proj-cache-key {{addLevel 0} arg} {
}
#
# @proj-cache-set ?key? ?addLevel? value
# @proj-cache-set ?-key KEY? ?-level 0? value
#
# Sets a feature-check cache entry with the given key.
#
# See proj-cache-key for $key's and $addLevel's semantics, noting that
# this function adds one to $addLevel for purposes of that call.
proc proj-cache-set {{key 0} {addLevel 0} val} {
set key [proj-cache-key [expr {1 + $addLevel}] $key]
# See proj-cache-key for -key's and -level's semantics, noting that
# this function adds one to -level for purposes of that call.
proc proj-cache-set {args} {
proj-parse-simple-flags args flags {
-key => 0
-level => 0
}
lassign $args val
set key [proj-cache-key $flags(-key) [expr {1 + $flags(-level)}]]
#puts "** fcheck set $key = $val"
set ::proj__Cache($key) $val
}
@@ -1995,7 +2016,7 @@ proc proj-cache-set {{key 0} {addLevel 0} val} {
#
# Removes an entry from the proj-cache.
proc proj-cache-remove {{key 0} {addLevel 0}} {
set key [proj-cache-key [expr {1 + $addLevel}] $key]
set key [proj-cache-key $key [expr {1 + $addLevel}]]
set rv ""
if {[info exists ::proj__Cache($key)]} {
set rv $::proj__Cache($key)
@@ -2005,7 +2026,7 @@ proc proj-cache-remove {{key 0} {addLevel 0}} {
}
#
# @proj-cache-check ?$key? ?addLevel? tgtVarName
# @proj-cache-check ?-key KEY? ?-level LEVEL? tgtVarName
#
# Checks for a feature-check cache entry with the given key.
#
@@ -2015,10 +2036,15 @@ proc proj-cache-remove {{key 0} {addLevel 0}} {
#
# See proj-cache-key for $key's and $addLevel's semantics, noting that
# this function adds one to $addLevel for purposes of that call.
proc proj-cache-check {{key 0} {addLevel 0} tgtVar} {
proc proj-cache-check {args} {
proj-parse-simple-flags args flags {
-key => 0
-level => 0
}
lassign $args tgtVar
upvar $tgtVar tgt
set rc 0
set key [proj-cache-key [expr {1 + $addLevel}] $key]
set key [proj-cache-key $flags(-key) [expr {1 + $flags(-level)}]]
#puts "** fcheck get key=$key"
if {[info exists ::proj__Cache($key)]} {
set tgt $::proj__Cache($key)
@@ -2046,8 +2072,6 @@ proc proj-coalesce {args} {
#
# @proj-parse-simple-flags ...
#
# An experiment. Do not use.
#
# A helper to parse flags from proc argument lists.
#
# Expects a list of arguments to parse, an array name to store any
@@ -2097,19 +2121,20 @@ proc proj-coalesce {args} {
#
# Example:
#
# set args [list -foo -bar {blah} 8 9 10]
# set args [proj-parse-simple-flags args flags {
# set args [list -foo -bar {blah} 8 9 10 -theEnd]
# proj-parse-simple-flags args flags {
# -foo 0 {expr 1}
# -bar => 0
# -no-baz 2 {return 0}
# }
#
# After that $flags would contain {-foo 1 -bar {blah} -no-baz 2}
# and $args would be {8 9 10}.
# and $args would be {8 9 10 -theEnd}.
#
# Potential TODOs: consider using lappend instead of set so that any
# given flag can be used more than once. Or add a syntax to indicate
# that.
# that multiples are allowed. Also consider searching the whole
# argv list, rather than stopping at the first non-flag
#
proc proj-parse-simple-flags {argvName tgtArrayName prototype} {
upvar $argvName argv
@@ -2187,16 +2212,16 @@ proc proj-parse-simple-flags {argvName tgtArrayName prototype} {
if {$::proj__Config(self-tests)} {
apply {{} {
proj-warn "Test code for proj-cache"
proj-assert {![proj-cache-check here check]}
#proj-warn "Test code for proj-cache"
proj-assert {![proj-cache-check -key here check]}
proj-assert {"here" eq [proj-cache-key here]}
proj-assert {"" eq $check}
proj-cache-set here thevalue
proj-assert {[proj-cache-check here check]}
proj-cache-set -key here thevalue
proj-assert {[proj-cache-check -key here check]}
proj-assert {"thevalue" eq $check}
proj-assert {![proj-cache-check check]}
#puts "*** key = ([proj-cache-key -])"
#puts "*** key = ([proj-cache-key 0])"
proj-assert {"" eq $check}
proj-cache-set abc
proj-assert {[proj-cache-check check]}

View File

@@ -36,11 +36,13 @@ array set teaish__Config [proj-strip-hash-comments {
debug-enabled 0
#
# 0 = don't yet have extension's pkgindex
# 0x01 = found TEAISH_EXT_DIR/pkgIndex.tcl.in
# 0x02 = found srcdir/pkgIndex.tcl.in
# 0x10 = found TEAISH_EXT_DIR/pkgIndex.tcl (static file)
# 0x20 = static-pkgIndex.tcl pragma: behave as if 0x10
# 0 = don't yet have extension's pkgindex
# 0x01 = found TEAISH_EXT_DIR/pkgIndex.tcl.in
# 0x02 = found srcdir/pkgIndex.tcl.in
# 0x10 = found TEAISH_EXT_DIR/pkgIndex.tcl (static file)
# 0x20 = static-pkgIndex.tcl pragma: behave as if 0x10
# 0x100 = disabled by -tm.tcl.in
# 0x200 = disabled by -tm.tcl
#
# Reminder: it's significant that the bottom 4 bits be
# cases where teaish manages ./pkgIndex.tcl.
@@ -60,6 +62,11 @@ array set teaish__Config [proj-strip-hash-comments {
# the (generated) pkginit file.
#
pkginit-policy 0
#
# 0 = no tm.tcl
# 0x01 = tm.tcl.in
# 0x10 = static tm.tcl
tm-policy 0
#
# If 1+ then teaish__verbose will emit messages.
@@ -68,7 +75,7 @@ array set teaish__Config [proj-strip-hash-comments {
#
# Mapping of pkginfo -flags to their TEAISH_xxx define (if any).
# This must not be modified.
# This must not be modified after initialization.
#
pkginfo-f2d {
-name TEAISH_NAME
@@ -81,6 +88,8 @@ array set teaish__Config [proj-strip-hash-comments {
-pkgInit.tcl TEAISH_PKGINIT_TCL
-pkgInit.tcl.in TEAISH_PKGINIT_TCL_IN
-url TEAISH_URL
-tm.tcl TEAISH_TM_TCL
-tm.tcl.in TEAISH_TM_TCL_IN
-options {}
-pragmas {}
}
@@ -95,6 +104,10 @@ array set teaish__Config [proj-strip-hash-comments {
# when building from an extension's dir, disabled when building
# elsewhere.
dist-enabled 1
# Whether or not "make install" parts are enabled. By default
# they are, but we have a single use case where they're
# both unnecessary and unhelpful, so...
install-enabled 1
# By default we enable compilation of a native extension but if the
# extension has no native code or the user wants to take that over
@@ -272,40 +285,52 @@ proc teaish-configure-core {} {
}]; # main options.
if {$gotExt} {
# We found an extension. Source it...
set ttcl $::teaish__Config(teaish.tcl)
proj-assert {"" ne [teaish-pkginfo-get -name]}
proj-assert {[file exists $::teaish__Config(teaish.tcl)]} \
"Expecting to have found teaish.tcl by now"
uplevel 1 {source $::teaish__Config(teaish.tcl)}
proj-assert {[file exists $ttcl]} \
"Expecting to have found teaish.(tcl|config) by now"
if {[string match *.tcl $ttcl]} {
uplevel 1 {source $::teaish__Config(teaish.tcl)}
} else {
teaish-pkginfo-set {*}[proj-file-content -trim $ttcl]
}
unset ttcl
# Set up some default values if the extension did not set them.
# This must happen _after_ it's sourced but before
# teaish-configure is called.
array set f2d $::teaish__Config(pkginfo-f2d)
foreach {pflag key type val} {
- TEAISH_CFLAGS -v ""
- TEAISH_LDFLAGS -v ""
- TEAISH_MAKEFILE -v ""
- TEAISH_MAKEFILE_CODE -v ""
- TEAISH_MAKEFILE_IN -v ""
- TEAISH_PKGINDEX_TCL -v ""
- TEAISH_PKGINDEX_TCL_IN -v ""
- TEAISH_TEST_TCL -v ""
- TEAISH_TEST_TCL_IN -v ""
- TEAISH_CFLAGS -v ""
- TEAISH_LDFLAGS -v ""
- TEAISH_MAKEFILE -v ""
- TEAISH_MAKEFILE_CODE -v ""
- TEAISH_MAKEFILE_IN -v ""
- TEAISH_PKGINDEX_TCL -v ""
- TEAISH_PKGINDEX_TCL_IN -v ""
- TEAISH_PKGINIT_TCL -v ""
- TEAISH_PKGINIT_TCL_IN -v ""
- TEAISH_PKGINIT_TCL_TAIL -v ""
- TEAISH_TEST_TCL -v ""
- TEAISH_TEST_TCL_IN -v ""
-version :f2d: -v 0.0.0
-name.pkg :f2d: -e {teaish-pkginfo-get -name}
-name.dist :f2d: -e {teaish-pkginfo-get -name}
-libDir :f2d: -e {
-version - -v 0.0.0
-name.pkg - -e {set ::teaish__PkgInfo(-name)}
-name.dist - -e {set ::teaish__PkgInfo(-name)}
-libDir - -e {
join [list \
[teaish-pkginfo-get -name.pkg] \
[teaish-pkginfo-get -version]] ""
$::teaish__PkgInfo(-name.pkg) \
$::teaish__PkgInfo(-version)] ""
}
-loadPrefix :f2d: -e {
string totitle [teaish-get -name.pkg]
-loadPrefix - -e {
string totitle $::teaish__PkgInfo(-name.pkg)
}
-vsatisfies :f2d: -v {{Tcl 8.5-}}
-pkgInit.tcl :f2d: -v ""
-pkgInit.tcl.in :f2d: -v ""
-url :f2d: -v ""
-vsatisfies - -v {{Tcl 8.5-}}
-pkgInit.tcl - -v ""
-pkgInit.tcl.in - -v ""
-url - -v ""
-tm.tcl - -v ""
-tm.tcl.in - -v ""
} {
set isPIFlag [expr {"-" ne $pflag}]
if {$isPIFlag} {
@@ -313,7 +338,7 @@ proc teaish-configure-core {} {
# Was already set - skip it.
continue;
}
proj-assert {{:f2d:} eq $key}
proj-assert {{-} eq $key}
set key $f2d($pflag)
}
proj-assert {"" ne $key}
@@ -470,7 +495,7 @@ proc teaish__configure_phase1 {} {
apply {{} {
# Set up "vsatisfies" code for pkgIndex.tcl.in,
# teaish.tester.tcl.in, and for a configure-time check. We would
# _teaish.tester.tcl.in, and for a configure-time check. We would
# like to put this before [teaish-checks-run -pre] but it's
# marginally conceivable that a client may need to dynamically
# calculate the vsatisfies and set it via [teaish-configure].
@@ -501,14 +526,17 @@ proc teaish__configure_phase1 {} {
proj-fatal -up $tclsh "check failed:" $vsat
}
}
lappend code [string trim [subst -nocommands -nobackslashes {
if { ![package vsatisfies [package provide $pkg] $vcheck] } {
if {$::teaish__Config(vsatisfies-error)} {
error {Package $::teaish__PkgInfo(-name) $::teaish__PkgInfo(-version) requires $pv}
} else {
return
}
}}]]
if {$::teaish__Config(vsatisfies-error)} {
set vunsat \
[list error [list Package \
$::teaish__PkgInfo(-name) $::teaish__PkgInfo(-version) \
requires $pv]]
} else {
set vunsat return
}
lappend code \
[string trim [subst -nocommands \
{if { ![package vsatisfies [package provide $pkg] $vcheck] } {\n $vunsat\n}}]]
}; # foreach pv
define TEAISH_VSATISFIES_CODE [join $code "\n"]
}}; # vsatisfies
@@ -531,19 +559,23 @@ if { ![package vsatisfies [package provide $pkg] $vcheck] } {
if {!$::teaish__Config(pkgindex-policy)} {
proj-error "Cannot determine which pkgIndex.tcl to use"
}
set tpi [proj-coalesce \
[get-define TEAISH_PKGINDEX_TCL_IN] \
[get-define TEAISH_PKGINDEX_TCL]]
proj-assert {$tpi ne ""} \
"TEAISH_PKGINDEX_TCL should have been set up by now"
teaish__verbose 1 msg-result "Using pkgIndex from $tpi"
if {0x0f & $::teaish__Config(pkgindex-policy)} {
# Don't leave stale pkgIndex.tcl laying around yet don't delete
# or overwrite a user-managed static pkgIndex.tcl.
file delete -force -- [get-define TEAISH_PKGINDEX_TCL]
proj-dot-ins-append [get-define TEAISH_PKGINDEX_TCL_IN]
if {0x300 & $::teaish__Config(pkgindex-policy)} {
teaish__verbose 1 msg-result "pkgIndex disabled by -tm.tcl(.in)"
} else {
teaish-dist-add [file tail $tpi]
set tpi [proj-coalesce \
[get-define TEAISH_PKGINDEX_TCL_IN] \
[get-define TEAISH_PKGINDEX_TCL]]
proj-assert {$tpi ne ""} \
"TEAISH_PKGINDEX_TCL should have been set up by now"
teaish__verbose 1 msg-result "Using pkgIndex from $tpi"
if {0x0f & $::teaish__Config(pkgindex-policy)} {
# Don't leave stale pkgIndex.tcl laying around yet don't delete
# or overwrite a user-managed static pkgIndex.tcl.
file delete -force -- [get-define TEAISH_PKGINDEX_TCL]
proj-dot-ins-append [get-define TEAISH_PKGINDEX_TCL_IN]
} else {
teaish-dist-add [file tail $tpi]
}
}
}}; # $::teaish__Config(pkgindex-policy)
@@ -555,6 +587,10 @@ if { ![package vsatisfies [package provide $pkg] $vcheck] } {
file delete -force -- [get-define TEAISH_PKGINIT_TCL]
proj-dot-ins-append [get-define TEAISH_PKGINIT_TCL_IN]
}
if {0x0f & $::teaish__Config(tm-policy)} {
file delete -force -- [get-define TEAISH_TM_TCL]
proj-dot-ins-append [get-define TEAISH_TM_TCL_IN]
}
apply {{} {
# Queue up any remaining dot-in files
@@ -582,6 +618,7 @@ if { ![package vsatisfies [package provide $pkg] $vcheck] } {
define TEAISH_AUTOSETUP_DIR $::teaish__Config(core-dir)
define TEAISH_ENABLE_DIST $::teaish__Config(dist-enabled)
define TEAISH_ENABLE_INSTALL $::teaish__Config(install-enabled)
define TEAISH_ENABLE_DLL $::teaish__Config(dll-enabled)
define TEAISH_TCL $::teaish__Config(teaish.tcl)
@@ -596,33 +633,18 @@ if { ![package vsatisfies [package provide $pkg] $vcheck] } {
# Ensure that any of these lists are flattened
define $f [join [get-define $f]]
}
define TEAISH__DEFINES_MAP \
[teaish__dump_defs_to_list]; # injected into teaish.tester.tcl
proj-remap-autoconf-dir-vars
proj-dot-ins-process -validate; # do not [define] after this point
set tdefs [teaish__defines_to_list]
define TEAISH__DEFINES_MAP $tdefs; # injected into _teaish.tester.tcl
#
# NO [define]s after this point!
#
proj-dot-ins-process -validate
proj-if-opt-truthy teaish-dump-defines {
make-config-header config.defines.txt \
-none {TEAISH__* TEAISH_*_CODE} \
-str {
BIN_* CC LD AR INSTALL LDFLAG* CFLAGS* *_LDFLAGS *_CFLAGS
} \
-bare {HAVE_*} \
-auto {*}
proj-file-write config.defines.txt $tdefs
}
#
# If these are set up before call [options], it triggers an
# "option already defined" error.
#
#proj-opt-set teaish.tcl [get-define ]
#proj-opt-set teaish.make.in [get-define ]
#
# $::autosetup(builddir)/.configured is a workaround to prevent
# concurrent executions of TEAISH_AUTORECONFIG. MUST come last in
# the configure process.
#
#proj-file-write $::autosetup(builddir)/.configured ""
}; # teaish__configure_phase1
#
@@ -789,7 +811,7 @@ proc teaish__check_tcl {} {
if {$use_tcl} {
# Set up the TCLLIBDIR
set tcllibdir [get-env TCLLIBDIR ""]
set extDirName [get-define TEAISH_LIBDIR_NAME]
set extDirName [teaish-pkginfo-get -libDir]
if {"" eq $tcllibdir} {
# Attempt to extract TCLLIBDIR from TCL's $auto_path
if {"" ne $withSh &&
@@ -807,27 +829,60 @@ proc teaish__check_tcl {} {
define TCLLIBDIR $tcllibdir
}; # find TCLLIBDIR
if {[file-isexec $withSh]} {
set gotSh [file-isexec $withSh]
set tmdir ""; # first tcl::tm::list entry
if {$gotSh} {
catch {
set tmli [exec echo {puts [tcl::tm::list]} | $withSh]
# Reminder: this list contains many names of dirs which do not
# exist but are legitimate. If we rely only on an is-dir check,
# we can end up not finding any of the many candidates.
set firstDir ""
foreach d $tmli {
if {"" eq $firstDir && ![string match //*:* $d]} {
# First non-VFS entry, e.g. not //zipfs:
set firstDir $d
}
if {[file isdirectory $d]} {
set tmdir $d
break
}
}
if {"" eq $tmdir} {
set tmdir $firstDir
}
}; # find tcl::tm path
}
define TEAISH_TCL_TM_DIR $tmdir
# Finally, let's wrap up...
if {$gotSh} {
teaish__verbose 1 msg-result "Using tclsh = $withSh"
if {$cfg ne ""} {
define HAVE_TCL 1
} else {
proj-warn "Found tclsh but no tclConfig.sh."
}
if {"" eq $tmdir} {
proj-warn "Did not find tcl::tm directory."
}
}
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 {![file-isexec $withSh]} {
if {!$gotSh} {
proj-error "Did not find tclsh"
} elseif {"" eq $cfg} {
proj-indented-notice -error {
Cannot find a usable tclConfig.sh file. Use
--with-tcl=DIR to specify a directory near which tclConfig.sh can be
found, or --with-tclsh=/path/to/tclsh to allow the tclsh binary
to locate its tclConfig.sh.
Cannot find a usable tclConfig.sh file. Use --with-tcl=DIR to
specify a directory near which tclConfig.sh can be found, or
--with-tclsh=/path/to/tclsh to allow the tclsh binary to locate
its tclConfig.sh, with the caveat that a symlink to tclsh, or
wrapper script around it, e.g. ~/bin/tclsh ->
$HOME/tcl/9.0/bin/tclsh9.1, may not work because tclsh emits
different library paths for the former than the latter.
}
}
msg-result "Using Tcl [get-define TCL_VERSION] from [get-define TCL_PREFIX]."
@@ -866,7 +921,7 @@ proc teaish__tcl_platform_quirks {} {
# automated tests on Haiku (but works when run
# manually). Similarly, the post-install [package require ...]
# test fails, presumably for a similar reason. We work around
# the former in teaish.tester.tcl.in. We work around the
# the former in _teaish.tester.tcl.in. We work around the
# latter by amending the post-install check's ::auto_path (in
# Makefile.in). This code MUST NOT contain any single-quotes.
define TEAISH_POSTINST_PREREQUIRE \
@@ -902,17 +957,12 @@ proc teaish__find_extension {} {
# Helper for the foreach loop below.
set checkTeaishTcl {{mustHave fid dir} {
if {[file isdirectory $dir]} {
set f [file join $dir $fid]
if {[file readable $f]} {
return [file-normalize $f]
} elseif {$mustHave} {
proj-error "Missing required $dir/$fid"
}
set f [file join $dir $fid]
if {[file readable $f]} {
file-normalize $f
} elseif {$mustHave} {
proj-error "--teaish-extension-dir=$dir does not reference a directory"
proj-error "Missing required $dir/$fid"
}
return ""
}}
#
@@ -938,7 +988,10 @@ proc teaish__find_extension {} {
if {![file isdirectory $extD]} {
proj-error "--teaish-extension-dir value is not a directory: $extD"
}
set extT [apply $checkTeaishTcl 1 teaish.tcl $extD]
set extT [apply $checkTeaishTcl 0 teaish.config $extD]
if {"" eq $extT} {
set extT [apply $checkTeaishTcl 1 teaish.tcl $extD]
}
set ::teaish__Config(extension-dir) $extD
}
--help {
@@ -962,7 +1015,7 @@ proc teaish__find_extension {} {
if {"" eq $extT} {
set flist [list]
proj-assert {$dirExt eq ""}
lappend flist $dirBld/teaish.tcl $dirSrc/teaish.tcl
lappend flist $dirBld/teaish.tcl $dirBld/teaish.config $dirSrc/teaish.tcl
if {![proj-first-file-found extT $flist]} {
if {$gotHelpArg} {
# Tell teaish-configure-core that the lack of extension is not
@@ -1096,8 +1149,8 @@ If you are attempting an out-of-tree build, use
define TEAISH_TEST_TCL_IN ""
}
# Look for teaish.tester.tcl[.in]
set flist [list $dirExt/teaish.tester.tcl.in $dirSrc/teaish.tester.tcl.in]
# Look for _teaish.tester.tcl[.in]
set flist [list $dirExt/_teaish.tester.tcl.in $dirSrc/_teaish.tester.tcl.in]
if {[proj-first-file-found ttt $flist]} {
# Generate teaish.test.tcl from $ttt
set xt [file rootname [file tail $ttt]]
@@ -1109,7 +1162,7 @@ If you are attempting an out-of-tree build, use
}
unset ttt xt
} else {
if {[file exists [set ttt [file join $dirSrc teaish.tester.tcl.in]]]} {
if {[file exists [set ttt [file join $dirSrc _teaish.tester.tcl.in]]]} {
set xt [file rootname [file tail $ttt]]
define TEAISH_TESTER_TCL $xt
define TEAISH_TESTER_TCL_IN $ttt
@@ -1459,77 +1512,133 @@ proc teaish-make-config-header {filename} {
}
#
# @teaish-feature-cache-set ?$key? value
# @teaish-feature-cache-set $key value
#
# Sets a feature-check cache entry with the given key.
# See proj-cache-set for the key's semantics.
# See proj-cache-set for the key's semantics. $key should
# normally be 0.
#
proc teaish-feature-cache-set {{key 0} val} {
proj-cache-set $key 1 $val
proc teaish-feature-cache-set {key val} {
proj-cache-set -key $key -level 1 $val
}
#
# @teaish-feature-cache-check ?$key? tgtVarName
# @teaish-feature-cache-check key tgtVarName
#
# Checks for a feature-check cache entry with the given key.
# See proj-cache-set for the key's semantics.
#
# $key should also almost always be 0 but, due to a tclsh
# incompatibility in 1 OS, it cannot have a default value unless it's
# the second argument (but it should be the first one).
#
# If the feature-check cache has a matching entry then this function
# assigns its value to tgtVar and returns 1, else it assigns tgtVar to
# "" and returns 0.
#
# See proj-cache-check for $key's semantics.
#
proc teaish-feature-cache-check {{key 0} tgtVar} {
proc teaish-feature-cache-check {key tgtVar} {
upvar $tgtVar tgt
proj-cache-check $key 1 tgt
proj-cache-check -key $key -level 1 tgt
}
#
# @teaish-check-cached@ ?-nostatus? msg script
# @teaish-check-cached@ ?flags? msg script...
#
# A proxy for feature-test impls which handles caching of a feature
# flag check on per-function basis, using the calling scope's name as
# the cache key.
#
# It emits [msg-checking $msg]. If $msg is empty then it defaults to
# the name of the caller's scope. At the end, it will [msg-result "ok"]
# [msg-result "no"] unless -nostatus is used, in which case the caller
# is responsible for emitting at least a newline when it's done.
# the name of the caller's scope. The -nomsg flag suppresses the
# message for non-cache-hit checks. At the end, it will [msg-result
# "ok"] [msg-result "no"] unless -nostatus is used, in which case the
# caller is responsible for emitting at least a newline when it's
# done. The -msg-0 and -msg-1 flags can be used to change the ok/no
# text.
#
# This function checks for a cache hit before running $script and
# caching the result. If no hit is found then $script is run in the
# calling scope and its result value is stored in the cache. This
# routine will intercept a 'return' from $script.
#
# $script may be a command and its arguments, as opposed to a single
# script block.
#
# Flags:
#
# -nostatus = do not emit "ok" or "no" at the end. This presumes
# that the caller will emit at least one newline before turning.
# that either $script will emit at least one newline before
# returning or the caller will account for it. Because of how this
# function is typically used, -nostatus is not honored when the
# response includes a cached result.
#
# -quiet = disable output from Autosetup's msg-checking and
# msg-result for the duration of the $script check. Note that when
# -quiet is in effect, Autosetup's user-notice can be used to queue
# up output to appear after the check is done. Also note that
# -quiet has no effect on _this_ function, only the $script part.
#
# -nomsg = do not emit $msg for initial check. Like -nostatus, this
# flag is not honored when the response includes a cached result
# because it would otherwise produce no output (which is confusing
# in this context). This is useful when a check runs several other
# verbose checks and they emit all the necessary info.
#
# -msg-0 and -msg-1 MSG = strings to show when the check has failed
# resp. passed. Defaults are "no" and "ok". The 0 and 1 refer to the
# result value from teaish-feature-cache-check.
#
# -key cachekey = set the cache context key. Only needs to be
# explicit when using this function multiple times from a single
# scope. See proj-cache-check and friends for details on the key
# name. Its default is the name of the scope which calls this
# function.
#
proc teaish-check-cached {args} {
proj-parse-simple-flags args flags {
-nostatus 0 {expr 1}
-quiet 0 {expr 1}
-key => 1
-nomsg 0 {expr 1}
-msg-0 => no
-msg-1 => ok
}
lassign $args msg script
set args [lassign $args msg]
set script [join $args]
if {"" eq $msg} {
set msg [proj-scope 1]
}
msg-checking "${msg} ... "
if {[teaish-feature-cache-check 1 check]} {
msg-checking "(cached) "
if {$check} {msg-result "ok"} else {msg-result "no"}
if {[teaish-feature-cache-check $flags(-key) check]} {
#if {0 == $flags(-nomsg)} {
msg-checking "${msg} ... (cached) "
#}
#if {!$flags(-nostatus)} {
msg-result $flags(-msg-[expr {0 != ${check}}])
#}
return $check
} else {
if {0 == $flags(-nomsg)} {
msg-checking "${msg} ... "
}
if {$flags(-quiet)} {
incr ::autosetup(msg-quiet)
}
set code [catch {uplevel 1 $script} rc xopt]
if {$flags(-quiet)} {
incr ::autosetup(msg-quiet) -1
}
#puts "***** cached-check got code=$code rc=$rc"
if {$code in {0 2}} {
teaish-feature-cache-set 1 $rc
if {!$flags(-nostatus)} {
if {$rc} {
msg-result "ok"
} else {
msg-result "no"
msg-result $flags(-msg-[expr {0 != ${rc}}])
} else {
#show-notices; # causes a phantom newline because we're in a
#msg-checking scope, so...
if {[info exists ::autosetup(notices)]} {
show-notices
}
}
} else {
@@ -1551,15 +1660,15 @@ proc teaish-check-cached {args} {
#
proc teaish__quote_str {asList value} {
if {$asList} {
return [join [list "\{" $value "\}"] ""]
return "{${value}}"
}
return \"[string map [list \\ \\\\ \" \\\"] $value]\"
}
#
# Internal helper for teaish__dump_defs_to_list. Expects to be passed
# Internal helper for teaish__defines_to_list. Expects to be passed
# a name and the variadic $args which are passed to
# teaish__dump_defs_to_list.. If it finds a pattern match for the
# teaish__defines_to_list.. If it finds a pattern match for the
# given $name in the various $args, it returns the type flag for that
# $name, e.g. "-str" or "-bare", else returns an empty string.
#
@@ -1576,9 +1685,9 @@ proc teaish__defs_type {name spec} {
#
# An internal impl detail. Requires a data type specifier, as used by
# make-config-header, and a value. Returns the formatted value or the
# value $::teaish__Config(defs-skip) if the caller should skip
# emitting that value.
# Autosetup's [make-config-header], and a value. Returns the formatted
# value or the value $::teaish__Config(defs-skip) if the caller should
# skip emitting that value.
#
# In addition to -str, -auto, etc., as defined by make-config-header,
# it supports:
@@ -1589,9 +1698,10 @@ proc teaish__defs_type {name spec} {
# -autolist {...} works like -auto {...} except that it falls back to
# -list {...} type instead of -str {...} style for non-integers.
#
# -array {...} emits the output in something which, for conservative
# inputs, will be a valid JSON array. It can only handle relatively
# simple values with no control characters in them.
# -jsarray {...} emits the output in something which, for
# conservative inputs, will be a valid JSON array. It can only
# handle relatively simple values with no control characters in
# them.
#
set teaish__Config(defs-skip) "-teaish__defs_format sentinel"
proc teaish__defs_format {type value} {
@@ -1619,22 +1729,25 @@ proc teaish__defs_format {type value} {
-list {
set value [teaish__quote_str 1 $value]
}
-array {
-jsarray {
set ar {}
foreach v $value {
set v [teaish__defs_format -auto $v]
if {![string is integer -strict $v]} {
set v [teaish__quote_str 0 $v]
}
if {$::teaish__Config(defs-skip) ne $v} {
lappend ar $v
}
}
set value "\[ [join $ar {, }] \]"
set value [concat \[ [join $ar {, }] \]]
}
"" {
# (Much later:) Why do we do this?
set value $::teaish__Config(defs-skip)
}
default {
proj-error \
"Unknown [project-current-scope] -type ($type) called from" \
"Unknown [proj-scope] -type ($type) called from" \
[proj-scope 1]
}
}
@@ -1644,31 +1757,35 @@ proc teaish__defs_format {type value} {
#
# Returns Tcl code in the form of code which evaluates to a list of
# configure-time DEFINEs in the form {key val key2 val...}. It may
# misbehave for values which are not numeric or simple strings.
# misbehave for values which are not numeric or simple strings. Some
# defines are specifically filtered out of the result, either because
# their irrelevant to teaish or because they may be arbitrarily large
# (e.g. makefile content).
#
proc teaish__dump_defs_to_list {args} {
# The $args are explained in the docs for internal-use-only
# [teaish__defs_format]. The default mode is -autolist.
#
proc teaish__defines_to_list {args} {
set lines {}
lappend lines "\{"
set skipper $::teaish__Config(defs-skip)
lappend args \
-none {
TEAISH__*
TEAISH_MAKEFILE_CODE
AM_* AS_*
} \
-auto {
SIZEOF_* HAVE_*
} \
-autolist *
foreach n [lsort [dict keys [all-defines]]] {
set type [teaish__defs_type $n $args]
set value [teaish__defs_format $type [get-define $n]]
set args [list \
-none {
TEAISH__*
TEAISH_*_CODE
AM_* AS_*
} \
{*}$args \
-autolist *]
foreach d [lsort [dict keys [all-defines]]] {
set type [teaish__defs_type $d $args]
set value [teaish__defs_format $type [get-define $d]]
if {$skipper ne $value} {
lappend lines "$n $value"
lappend lines "$d $value"
}
}
lappend lines "\}"
return [join $lines "\n"]
tailcall join $lines "\n"
}
#
@@ -1697,7 +1814,7 @@ proc teaish__dump_defs_to_list {args} {
# -vsatisfies value should simply "return" instead of "error".
#
# no-tester [L]: disables automatic generation of teaish.test.tcl
# even if a copy of teaish.tester.tcl.in is found.
# even if a copy of _teaish.tester.tcl.in is found.
#
# no-full-dist [L]: changes the "make dist" rules to never include
# a copy of teaish itself. By default it will include itself only
@@ -1713,13 +1830,16 @@ proc teaish__pragma {args} {
switch -exact -- $arg {
static-pkgIndex.tcl {
if {$::teaish__Config(tm-policy)} {
proj-fatal -up "Cannot use pragma $arg together with -tm.tcl or -tm.tcl.in."
}
set tpi [file join $::teaish__Config(extension-dir) pkgIndex.tcl]
if {[file exists $tpi]} {
define TEAISH_PKGINDEX_TCL_IN ""
define TEAISH_PKGINDEX_TCL $tpi
set ::teaish__Config(pkgindex-policy) 0x20
} else {
proj-error "$arg: found no package-local pkgIndex.tcl\[.in]"
proj-error "pragma $arg: found no package-local pkgIndex.tcl\[.in]"
}
}
@@ -1727,6 +1847,10 @@ proc teaish__pragma {args} {
set ::teaish__Config(dist-enabled) 0
}
no-install {
set ::teaish__Config(install-enabled) 0
}
full-dist {
set ::teaish__Config(dist-full-enabled) 1
}
@@ -1813,7 +1937,7 @@ proc teaish__pragma {args} {
# -vsatisfies {{...} ...}: Expects a list-of-lists of conditions
# for Tcl's `package vsatisfies` command: each list entry is a
# sub-list of `{PkgName Condition...}`. Teaish inserts those
# checks via its default pkgIndex.tcl.in and teaish.tester.tcl.in
# checks via its default pkgIndex.tcl.in and _teaish.tester.tcl.in
# templates to verify that the system's package dependencies meet
# these requirements. The default value is `{{Tcl 8.5-}}` (recall
# that it's a list-of-lists), as 8.5 is the minimum Tcl version
@@ -1907,15 +2031,16 @@ proc teaish-pkginfo-set {args} {
foreach {f d} $::teaish__Config(pkginfo-f2d) {
if {$sentinel eq [set v $flags($f)]} continue
switch -exact -- $f {
-options {
proj-assert {"" eq $d}
options-add $v
}
-pragmas {
foreach p $v {
teaish__pragma $p
}
teaish__pragma {*}$v
}
-vsatisfies {
if {1 == [llength $v] && 1 == [llength [lindex $v 0]]} {
# Transform X to {Tcl $X}
@@ -1923,30 +2048,74 @@ proc teaish-pkginfo-set {args} {
}
define $d $v
}
-pkgInit.tcl -
-pkgInit.tcl.in {
# Generate pkginit file X from X.in
set ::teaish__Config(pkginit-policy) 0x02
if {0x22 & $::teaish__Config(pkginit-policy)} {
proj-fatal "Cannot use -pkgInit.tcl(.in) more than once."
}
set x [file join $::teaish__Config(extension-dir) $v]
define TEAISH_PKGINIT_TCL_IN $x
set fout [file rootname [file tail $v]]
define TEAISH_PKGINIT_TCL $fout
define TEAISH_PKGINIT_TCL_TAIL $fout
set ::teaish__PkgInfo(-pkgInit.tcl) {}
set tTail [file tail $v]
if {"-pkgInit.tcl.in" eq $f} {
# Generate pkginit file X from X.in
set pI 0x02
set tIn $x
set tOut [file rootname $tTail]
set other -pkgInit.tcl
} else {
# Static pkginit file X
set pI 0x20
set tIn ""
set tOut $x
set other -pkgInit.tcl.in
}
set ::teaish__Config(pkginit-policy) $pI
set ::teaish__PkgInfo($other) {}
define TEAISH_PKGINIT_TCL_IN $tIn
define TEAISH_PKGINIT_TCL $tOut
define TEAISH_PKGINIT_TCL_TAIL $tTail
teaish-dist-add $v
set v $x
}
-pkgInit.tcl {
# Static pkginit file X
set ::teaish__Config(pkginit-policy) 0x20
-tm.tcl -
-tm.tcl.in {
if {0x30 & $::teaish__Config(pkgindex-policy)} {
proj-fatal "Cannot use $f together with a pkgIndex.tcl."
} elseif {$::teaish__Config(tm-policy)} {
proj-fatal "Cannot use -tm.tcl(.in) more than once."
}
set x [file join $::teaish__Config(extension-dir) $v]
define TEAISH_PKGINIT_TCL $x
define TEAISH_PKGINIT_TCL_IN ""
define TEAISH_PKGINIT_TCL_TAIL [file tail $v]
set ::teaish__PkgInfo(-pkgInit.tcl.in) {}
if {"-tm.tcl.in" eq $f} {
# Generate tm file X from X.in
set pT 0x02
set pI 0x100
set tIn $x
set tOut [file rootname [file tail $v]]
set other -tm.tcl
} else {
# Static tm file X
set pT 0x20
set pI 0x200
set tIn ""
set tOut $x
set other -tm.tcl.in
}
set ::teaish__Config(pkgindex-policy) $pI
set ::teaish__Config(tm-policy) $pT
set ::teaish__PkgInfo($other) {}
define TEAISH_TM_TCL_IN $tIn
define TEAISH_TM_TCL $tOut
define TEAISH_PKGINDEX_TCL ""
define TEAISH_PKGINDEX_TCL_IN ""
define TEAISH_PKGINDEX_TCL_TAIL ""
teaish-dist-add $v
teaish__pragma no-dll
set v $x
}
default {
proj-assert {"" ne $d}
define $d $v
}
}
@@ -2257,7 +2426,7 @@ extern int DLLEXPORT ${loadPrefix}_Init(Tcl_Interp *interp){
proj-file-write teaish.make.in $content
teaish__verbose 1 msg-result "Created teaish.make.in"
msg-result "Created new extension $name in \[$dir]."
msg-result "Created new extension \[$dir\]."
cd $cwd
set ::teaish__Config(install-ext-dir) $dir
@@ -2277,12 +2446,12 @@ proc teaish__install_file {f destDir force} {
&& ($st1(size) == $st2(size))} {
if {[file tail $f] in {
pkgIndex.tcl.in
teaish.tester.tcl.in
_teaish.tester.tcl.in
}} {
# Assume they're the same. In the scope of the "make dist"
# rules, this happens legitimately when an extension with a
# copy of teaish installed in the same dir assumes that the
# pkgIndex.tcl.in and teaish.tester.tcl.in belong to the
# pkgIndex.tcl.in and _teaish.tester.tcl.in belong to the
# extension, whereas teaish believes they belong to teaish.
# So we end up with dupes of those.
return
@@ -2358,7 +2527,7 @@ proc teaish__install {{dDest ""}} {
teaish__verbose 1 msg-result "Copying files to $dDest..."
foreach f {
auto.def configure Makefile.in pkgIndex.tcl.in
teaish.tester.tcl.in
_teaish.tester.tcl.in
} {
teaish__verbose 2 msg-result "\t$f"
teaish__install_file $dSrc/$f $dDest $force

View File

@@ -10,16 +10,17 @@
#
########################################################################
#
# Helper routines for running automated tests on teaish extensions
# Helper routines for running tests on teaish extensions
#
########################################################################
# ----- @module teaish-tester.tcl -----
# ----- @module teaish/tester.tcl -----
#
# @section TEA-ish Testing APIs.
#
# Though these are part of the autosup dir hierarchy, they are not
# intended to be run from autosetup code. Rather, they're for
# use with/via teaish.tester.tcl.
# intended to be run from autosetup code. Rather, they're for use
# with/via teaish.tester.tcl and target canonical Tcl only, not JimTcl
# (which the autosetup pieces do target).
#
# @test-current-scope ?lvl?
@@ -71,34 +72,68 @@ proc test-fail {args} {
error "FAIL: \[[test-current-scope 1]]: $args"
}
array set ::test__Counters {}
array set ::test__Config {
verbose-assert 0 verbose-affirm 0
}
# Internal impl for affirm and assert.
#
# Internal impl for assert-likes. Should not be called directly by
# client code.
#
proc test__assert {lvl script {msg ""}} {
set src "expr \{ $script \}"
# puts "XXXX evalling $src";
if {![uplevel $lvl $src]} {
# $args = ?-v? script {msg-on-fail ""}
proc test__affert {failMode args} {
if {$failMode} {
set what assert
} else {
set what affirm
}
set verbose $::test__Config(verbose-$what)
if {"-v" eq [lindex $args 0]} {
lassign $args - script msg
if {1 == [llength $args]} {
# If -v is the only arg, toggle default verbose mode
set ::test__Config(verbose-$what) [expr {!$::test__Config(verbose-$what)}]
return
}
incr verbose
} else {
lassign $args script msg
}
incr ::test__Counters($what)
if {![uplevel 1 [concat expr [list $script]]]} {
if {"" eq $msg} {
set msg $script
}
set caller1 [test-current-scope $lvl]
incr lvl
set caller2 [test-current-scope $lvl]
error "Assertion failed in: \[$caller2 -> $caller1]]: $msg"
set txt [join [list $what # $::test__Counters($what) "failed:" $msg]]
if {$failMode} {
puts stderr $txt
exit 1
} else {
error $txt
}
} elseif {$verbose} {
puts stderr [join [list $what # $::test__Counters($what) "passed:" $script]]
}
}
#
# @assert script ?message?
# @affirm ?-v? script ?msg?
#
# Kind of like a C assert: if uplevel (eval) of [expr {$script}] is
# false, a fatal error is triggered. The error message, by default,
# includes the body of the failed assertion, but if $msg is set then
# that is used instead.
# Works like a conventional assert method does, but reports failures
# using [error] instead of [exit]. If -v is used, it reports passing
# assertions to stderr. $script is evaluated in the caller's scope as
# an argument to [expr].
#
proc assert {script {msg ""}} {
test__assert 1 $script $msg
proc affirm {args} {
tailcall test__affert 0 {*}$args
}
#
# @assert ?-v? script ?msg?
#
# Works like [affirm] but exits on error.
#
proc assert {args} {
tailcall test__affert 1 {*}$args
}
#
@@ -108,7 +143,7 @@ proc assert {script {msg ""}} {
#
proc test-assert {testId script {msg ""}} {
puts "test $testId"
test__assert 2 $script $msg
tailcall test__affert 1 $script $msg
}
#
@@ -122,7 +157,7 @@ proc test-expect {testId script result} {
puts "test $testId"
set x [string trim [uplevel 1 $script]]
set result [string trim $result]
test__assert 1 {$x eq $result} \
tailcall test__affert 0 [list $x eq $result] \
"\nEXPECTED: <<$result>>\nGOT: <<$x>>"
}

View File

@@ -98,14 +98,9 @@ SQLITE_EXTENSION_INIT1
# include <direct.h>
# include "test_windirent.h"
# define dirent DIRENT
# ifndef chmod
# define chmod _chmod
# endif
# ifndef stat
# define stat _stat
# endif
# define mkdir(path,mode) _mkdir(path)
# define lstat(path,buf) stat(path,buf)
# define stat _stat
# define chmod(path,mode) fileio_chmod(path,mode)
# define mkdir(path,mode) fileio_mkdir(path)
#endif
#include <time.h>
#include <errno.h>
@@ -130,6 +125,40 @@ SQLITE_EXTENSION_INIT1
#define FSDIR_COLUMN_PATH 4 /* Path to top of search */
#define FSDIR_COLUMN_DIR 5 /* Path is relative to this directory */
/*
** UTF8 chmod() function for Windows
*/
#if defined(_WIN32) || defined(WIN32)
static int fileio_chmod(const char *zPath, int pmode){
sqlite3_int64 sz = strlen(zPath);
wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) );
int rc;
if( b1==0 ) return -1;
sz = MultiByteToWideChar(CP_UTF8, 0, zPath, sz, b1, sz);
b1[sz] = 0;
rc = _wchmod(b1, pmode);
sqlite3_free(b1);
return rc;
}
#endif
/*
** UTF8 mkdir() function for Windows
*/
#if defined(_WIN32) || defined(WIN32)
static int fileio_mkdir(const char *zPath){
sqlite3_int64 sz = strlen(zPath);
wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) );
int rc;
if( b1==0 ) return -1;
sz = MultiByteToWideChar(CP_UTF8, 0, zPath, sz, b1, sz);
b1[sz] = 0;
rc = _wmkdir(b1);
sqlite3_free(b1);
return rc;
}
#endif
/*
** Set the result stored by context ctx to a blob containing the
@@ -291,7 +320,13 @@ static int fileStat(
struct stat *pStatBuf
){
#if defined(_WIN32)
int rc = stat(zPath, pStatBuf);
sqlite3_int64 sz = strlen(zPath);
wchar_t *b1 = sqlite3_malloc64( (sz+1)*sizeof(b1[0]) );
int rc;
if( b1==0 ) return 1;
sz = MultiByteToWideChar(CP_UTF8, 0, zPath, sz, b1, sz);
b1[sz] = 0;
rc = _wstat(b1, pStatBuf);
if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
return rc;
#else
@@ -309,9 +344,7 @@ static int fileLinkStat(
struct stat *pStatBuf
){
#if defined(_WIN32)
int rc = lstat(zPath, pStatBuf);
if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
return rc;
return fileStat(zPath, pStatBuf);
#else
return lstat(zPath, pStatBuf);
#endif

View File

@@ -581,7 +581,7 @@ static int vfstraceFileControl(sqlite3_file *pFile, int op, void *pArg){
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 ){
if( zArg[0]>='0' && zArg[0]<='9' ){
pInfo->mTrace = (sqlite3_uint64)strtoll(a[2], 0, 0);
}else{
static const struct {

View File

@@ -2848,7 +2848,7 @@ static int deleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell, int iHeight){
return rc;
}
/*
** Insert cell pCell into node pNode. Node pNode is the head of a
** subtree iHeight high (leaf nodes have iHeight==0).

View File

@@ -28,11 +28,17 @@ static void usage(const char *argv0){
fprintf(stderr, "Usage: %s FILENAME COMMAND ...\n", argv0);
fprintf(stderr,
"COMMANDs:\n"
" apply DB Apply the changeset to database file DB\n"
" concat FILE2 OUT Concatenate FILENAME and FILE2 into OUT\n"
" dump Show the complete content of the changeset\n"
" invert OUT Write an inverted changeset into file OUT\n"
" sql Give a pseudo-SQL rendering of the changeset\n"
" apply DB [OPTIONS] Apply the changeset to database file DB. OPTIONS:\n"
" -n|--dryrun Test run. Don't apply changes\n"
" --enablefk Enable FOREIGN KEY support\n"
" --nosavepoint \\\n"
" --invert \\___ Flags passed into\n"
" --ignorenoop / changeset_apply_v2()\n"
" --fknoaction /\n"
" concat FILE2 OUT Concatenate FILENAME and FILE2 into OUT\n"
" dump Show the complete content of the changeset\n"
" invert OUT Write an inverted changeset into file OUT\n"
" sql Give a pseudo-SQL rendering of the changeset\n"
);
exit(1);
}
@@ -161,7 +167,7 @@ static int conflictCallback(
case SQLITE_DELETE: zOp = "DELETE from"; break;
}
printf("%s conflict on %s table %s with primary key", zType, zOp, zTab);
for(i=0; i<nCol; i++){
for(i=0; i<nCol && abPK; i++){
sqlite3_value *pVal;
if( abPK[i]==0 ) continue;
printf("%s", zSep);
@@ -188,21 +194,70 @@ int main(int argc, char **argv){
*/
if( strcmp(argv[2],"apply")==0 ){
sqlite3 *db;
if( argc!=4 ) usage(argv[0]);
rc = sqlite3_open(argv[3], &db);
int bDryRun = 0;
int bEnableFK = 0;
const char *zDb = 0;
int i;
int applyFlags = 0;
for(i=3; i<argc; i++){
const char *zArg = argv[i];
if( zArg[0]=='-' ){
if( zArg[1]=='-' && zArg[2]!=0 ) zArg++;
if( strcmp(zArg, "-n")==0 || strcmp(zArg,"-dryrun")==0 ){
bDryRun = 1;
continue;
}
if( strcmp(zArg, "-nosavepoint")==0 ){
applyFlags |= SQLITE_CHANGESETAPPLY_NOSAVEPOINT;
continue;
}
if( strcmp(zArg, "-invert")==0 ){
applyFlags |= SQLITE_CHANGESETAPPLY_INVERT;
continue;
}
if( strcmp(zArg, "-ignorenoop")==0 ){
applyFlags |= SQLITE_CHANGESETAPPLY_IGNORENOOP;
continue;
}
if( strcmp(zArg, "-fknoaction")==0 ){
applyFlags |= SQLITE_CHANGESETAPPLY_FKNOACTION;
continue;
}
if( strcmp(zArg, "-enablefk")==0 ){
bEnableFK = 1;
continue;
}
fprintf(stderr, "unknown option: \"%s\"\n", argv[i]);
exit(1);
}else if( zDb ){
fprintf(stderr, "unknown argument: \"%s\"\n", argv[i]);
exit(1);
}else{
zDb = zArg;
}
}
rc = sqlite3_open(zDb, &db);
if( rc!=SQLITE_OK ){
fprintf(stderr, "unable to open database file \"%s\": %s\n",
argv[3], sqlite3_errmsg(db));
zDb, sqlite3_errmsg(db));
sqlite3_close(db);
exit(1);
}
if( bEnableFK ){
sqlite3_exec(db, "PRAGMA foreign_keys=1;", 0, 0, 0);
}
sqlite3_exec(db, "BEGIN", 0, 0, 0);
nConflict = 0;
rc = sqlite3changeset_apply(db, sz, pBuf, 0, conflictCallback, 0);
if( applyFlags ){
rc = sqlite3changeset_apply_v2(db, sz, pBuf, 0, conflictCallback, 0,
0, 0, applyFlags);
}else{
rc = sqlite3changeset_apply(db, sz, pBuf, 0, conflictCallback, 0);
}
if( rc ){
fprintf(stderr, "sqlite3changeset_apply() returned %d\n", rc);
}
if( nConflict ){
if( nConflict || bDryRun ){
fprintf(stderr, "%d conflicts - no changes applied\n", nConflict);
sqlite3_exec(db, "ROLLBACK", 0, 0, 0);
}else if( rc ){

View File

@@ -570,7 +570,7 @@ int sqlite3changeset_start_v2(
** The following flags may passed via the 4th parameter to
** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]:
**
** <dt>SQLITE_CHANGESETAPPLY_INVERT <dd>
** <dt>SQLITE_CHANGESETSTART_INVERT <dd>
** Invert the changeset while iterating through it. This is equivalent to
** inverting a changeset using sqlite3changeset_invert() before applying it.
** It is an error to specify this flag with a patchset.

View File

@@ -1,5 +1,5 @@
C Merge\sthe\slatest\strunk\schanges\sinto\sthe\swal2\sbranch.
D 2025-05-06T21:38:45.322
C Merge\srecent\strunk\schanges\sinto\sthe\swal2\sbranch.
D 2025-05-19T16:52:04.044
F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -22,20 +22,16 @@ F autoconf/Makefile.msc f15ad424ca2820df8e39d9157965710af0a64d87773706706a12ea4f
F autoconf/README.first f1d3876e9a7852c22f275a6f06814e64934cecbc0b5b9617d64849094c1fd136
F autoconf/README.txt b749816b8452b3af994dc6d607394bef3df1736d7e09359f1087de8439a52807
F autoconf/auto.def 3d994f3a9cc9b712dbce92a5708570ddcf3b988141b6eb738f2ed16127a9f0ac
F autoconf/tea/Makefile.in 8c00e2ed350754d6b45681318ed7e4578aed8ad732abcac0593c1b10dc29e5a6
F autoconf/tea/Makefile.in 14c6a79ce87e10d8a35398f2d0e04e1d83a88eb52ee16ebf0eeaccf005ff84b3
F autoconf/tea/README.txt 656d4686c509d375f5988ff3deda94f65fe6cd8358cd55d1f1dcc7b6e2ff73aa
F autoconf/tea/_teaish.tester.tcl.in ed5445512e91c12afbbb99771efb68a23be4a046d52d61213fb5b6f010118129 w autoconf/tea/teaish.tester.tcl.in
F autoconf/tea/auto.def ce95b9450e2fa4ba5dc857e208fe10f4e6f2d737796ac3278aee6079db417529
F autoconf/tea/autosetup/README.txt b40071e6f8506500a2f7f71d5fc69e0bf87b9d7678dd9da1e5b4d0acbf40b1ca
F autoconf/tea/autosetup/core.tcl 7d942639871111e2fcef571c9d5a6e2dc75972eb214cf814a6b99f1e2b25182f
F autoconf/tea/autosetup/feature-tests.tcl 18194fb79a24d30e5bbdeab40999616f39278b53a27525349ded033af2fd73be
F autoconf/tea/autosetup/tester.tcl c293695a0ab5d9e8d0ceeb0ee422f90e8a6aa9f0c7c51acd0b6d9f09d8edfed3
F autoconf/tea/configure d0b12b984edca6030d1976375b80157ac78b5b90a5b4f0dcee39357f63f4a80b x
F autoconf/tea/doc/sqlite3.n 9a97f4f717ceab73004ea412af7960625c1cb24b5c25e4ae4c8b5d8fa4300f4e
F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523
F autoconf/tea/pkgIndex.tcl.in e07da6b94561f4aa382bab65b1ccceb04701b97bf59d007c1d1f20a222b22d07
F autoconf/tea/teaish.tcl 8e124f33cbaf9309f3e49be4e7018a03b8f3a52f8c8d9e1e5419f4f7b0eae59e
F autoconf/tea/teaish.tcl 81571a9f9ae5c70735595b05586cb2de9d2aea7e32aad10417c4982f2e2f01c8
F autoconf/tea/teaish.test.tcl cfe94e1fb79dd078f650295be59843d470125e0cc3a17a1414c1fb8d77f4aea6
F autoconf/tea/teaish.tester.tcl.in 31ac5b7b1e226b7e1bfc6b578a6c1a51550306ef7afae5949eec046df006ca7d
F autosetup/LICENSE 41a26aebdd2cd185d1e2b210f71b7ce234496979f6b35aef2cbf6b80cbed4ce4
F autosetup/README.autosetup a78ff8c4a3d2636a4268736672a74bf14a82f42687fcf0631a70c516075c031e
F autosetup/README.md f324bb9f9bf1cc787122034df53fbfdfed28ee2657e6652b763d992ab0d04829
@@ -51,9 +47,13 @@ F autosetup/cc.tcl c0fcc50ca91deff8741e449ddad05bcd08268bc31177e613a6343bbd1fd3e
F autosetup/find_tclconfig.tcl e64886ffe3b982d4df42cd28ed91fe0b5940c2c5785e126c1821baf61bc86a7e
F autosetup/jimsh0.c 563b966c137a4ce3c9333e5196723b7ac0919140a9d7989eb440463cd855c367
F autosetup/pkg-config.tcl 4e635bf39022ff65e0d5434339dd41503ea48fc53822c9c5bde88b02d3d952ba
F autosetup/proj.tcl 0287234d817e800ab0e10d46bf98545ba5762edd69e5dd0e2902029a7e6c3555
F autosetup/proj.tcl c4a77735b57f3c016a185bff048212a197b77723f9bea6cfafe396e4b542c666
F autosetup/sqlite-config.tcl 7ff986f6c3951f3aec5608522cbf772d8d04a0d26cc894289e2ca4836e018719
F autosetup/system.tcl 51d4be76cd9a9074704b584e5c9cbba616202c8468cf9ba8a4f8294a7ab1dba9
F autosetup/teaish/README.txt b40071e6f8506500a2f7f71d5fc69e0bf87b9d7678dd9da1e5b4d0acbf40b1ca w autoconf/tea/autosetup/README.txt
F autosetup/teaish/core.tcl 1ebbe849d8e716424a3ffe9384c7e8b352b3e1194d3d4a153b125cc5176b3715 w autoconf/tea/autosetup/core.tcl
F autosetup/teaish/feature.tcl 18194fb79a24d30e5bbdeab40999616f39278b53a27525349ded033af2fd73be w autoconf/tea/autosetup/feature-tests.tcl
F autosetup/teaish/tester.tcl 091745984473faea6985254b9986c6dfd0cce06f68bc515ba4afc1e6b3742fa8 w autoconf/tea/autosetup/tester.tcl
F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x
F contrib/sqlitecon.tcl eb4c6578e08dd353263958da0dc620f8400b869a50d06e271ab0be85a51a08d3
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
@@ -420,7 +420,7 @@ F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f82
F ext/misc/decimal.c 228d47e9ef4de60daf5851da19e3ac9ac1eda9e94432816914469501db6a1129
F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1
F ext/misc/explain.c 606100185fb90d6a1eade1ed0414d53503c86820d8956a06e3b0a56291894f2b
F ext/misc/fileio.c 07cf3109ec6452789e3a989a010234e2a17b599ce82ea29212c948572456abac
F ext/misc/fileio.c 34993b810514c58ff99d7b4254d4a388d844a4774ea77bec68a1dafe8de5ce41
F ext/misc/fossildelta.c 0aeb099e9627eea693cf21ae47826ecd1e0319b93143bed23090838b2ef0c162
F ext/misc/fuzzer.c 6b231352815304ba60d8e9ec2ee73d4918e74d9b76bda8940ba2b64e8777515e
F ext/misc/ieee754.c c9dd9d77c8e8e18e0a5706f8ffcccf4ccb6562073709f7453d4d73f5122f4362
@@ -458,7 +458,7 @@ F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917
F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf
F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20
F ext/misc/vfsstat.c 0b23c0a69a2b63dc0ef0af44f9c1fc977300c480a1f7a9814500369d8211f56e
F ext/misc/vfstrace.c 5264aedaa27967483f8bed0a2b42fce56d370f0af1559e5703329966ed742ddd
F ext/misc/vfstrace.c 0e4b8b17ac0675ea90f6d168d8214687e06ca3efbc0060aad4814994d82b41fb
F ext/misc/vtablog.c 1100250ce8782db37c833e3a9a5c9a3ecf1af5e15b8325572b82e6e0a138ffb5
F ext/misc/vtshim.c e5bce24ab8c532f4fdc600148718fe1802cb6ed57417f1c1032d8961f72b0e8f
F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668
@@ -541,7 +541,7 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c3350
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
F ext/rtree/README 734aa36238bcd2dee91db5dba107d5fcbdb02396612811377a8ad50f1272b1c1
F ext/rtree/geopoly.c f0573d5109fdc658a180db0db6eec86ab2a1cf5ce58ec66cbf3356167ea757eb
F ext/rtree/rtree.c 99dade93b5ca1c1fa4a5ba1381140d88b27a52573a92897827d9eb2a8059a460
F ext/rtree/rtree.c f12180fbc79f4de3dcb93afe55a64703481a23af7f80d1e988d2cb97afd07b6b
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
F ext/rtree/rtree1.test e0608db762b2aadca0ecb6f97396cf66244490adc3ba88f2a292b27be3e1da3e
F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d
@@ -577,7 +577,7 @@ F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de
F ext/rtree/util/randomshape.tcl 54ee03d0d4a1c621806f7f44d5b78d2db8fac26e0e8687c36c4bd0203b27dbff
F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
F ext/rtree/visual01.txt e9c2564083bcd30ec51b07f881bffbf0e12b50a3f6fced0c222c5c1d2f94ac66
F ext/session/changeset.c 7a1e6a14c7e92d36ca177e92e88b5281acd709f3b726298dc34ec0fb58869cb5
F ext/session/changeset.c 06b585d977391d498746f002b2d5f9315d0d37888ce9551bd0cb30bfe9a4cf47
F ext/session/changesetfuzz.c 227076ab0ae4447d742c01ee88a564da6478bbf26b65108bf8fac9cd8b0b24aa
F ext/session/changesetfuzz1.test 15b629004e58d5ffcc852e6842a603775bb64b1ce51254831f3d12b113b616cd
F ext/session/session1.test 5d2502922d38a1579076863827342379a1609ca6bae78c40691a2be1ed1be2aa x
@@ -620,7 +620,7 @@ F ext/session/sessionsize.test 8fcf4685993c3dbaa46a24183940ab9f5aa9ed0d23e5fb63b
F ext/session/sessionstat1.test 5e718d5888c0c49bbb33a7a4f816366db85f59f6a4f97544a806421b85dc2dec
F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc
F ext/session/sqlite3session.c 7a8816d56940c464c74706dfb02f18129b290655df1ccb8648228a7d436141f2
F ext/session/sqlite3session.h 9b58d8f8052145bc302a72391b898f41a47d5138c8a757818bd4dc467874f5f3
F ext/session/sqlite3session.h 9bb1a6687b467764b35178dc29bbd2c57ab8cd3acdc8a62f088c34ad17e4fe2b
F ext/session/test_session.c af162108e8dc40cb9fe0e876e0155cecabcb49e82e5939677d21451e36160283
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
F ext/wasm/GNUmakefile 24d7e6f446528fa67f5ade6c3c7d7e46e1ac52649d6264cbe24539c1dab608e1
@@ -721,8 +721,8 @@ F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc
F sqlite3.pc.in 0977c03a4da7c4204bd60e784a0efb8d51a190448aba78a4e973fe7192bdaf03
F src/alter.c 6a21a487290ed0990a0fac9db6b0b09c63de4b1cdaa6ba3fa3872e6f26b87768
F src/analyze.c 13895d4da6ac857d95d3291dc607d492eba3ea1cbc3bc04baaa0383fbc1bb3d4
F src/alter.c fc7bbbeb9e89c7124bf5772ce474b333b7bdc18d6e080763211a40fde69fb1da
F src/analyze.c 03bcfc083fc0cccaa9ded93604e1d4244ea245c17285d463ef6a60425fcb247d
F src/attach.c 9af61b63b10ee702b1594ecd24fb8cea0839cfdb6addee52fba26fa879f5db9d
F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
@@ -748,9 +748,9 @@ F src/hash.h 46b92795a95bfefb210f52f0c316e9d7cdbcdd7e7fcfb0d8be796d3a5767cddf
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
F src/insert.c d05934dfab2c5c0c480fc6fd2038f11215661de08ea6ff38d2563216bd555c1b
F src/json.c c84b0f2bae967341d5a035808d21d0619b23b6e054ceac08e7592cd87f04ed4f
F src/json.c 2406a6b0dd849ee0fd107d5cfef9fec2cdc2fbe631ece3183c31d6f85e0ec988
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36
F src/loadext.c d7edd8e671237539d795d30daaf888908a2c82e99bade4c78f3be021e8b7d655
F src/main.c 07f78d917ffcdf327982840cfd8e855fd000527a2ea5ace372ce4febcbd0bf97
F src/malloc.c 410e570b30c26cc36e3372577df50f7a96ee3eed5b2b161c6b6b48773c650c5e
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
@@ -773,7 +773,7 @@ F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e
F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a
F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107
F src/os_unix.c 410185df4900817c218c0efdb8064b3481af88cb3f7cea7392f820b6eebc7889
F src/os_win.c caab8bc13f1d64a2ba6b8af35d660ffe25083df3493d9082d7a461a5e9950a50
F src/os_win.c b39f31fb0b137d67091d21880f0fded6b1c3c8c59b9e24e42844a1c0070437d4
F src/os_win.h 4c247cdb6d407c75186c94a1e84d5a22cbae4adcec93fcae8d2bc1f956fd1f19
F src/pager.c bcc787d47b44b827639d260b716479b1313ed79033f1985cbc7243f4d575d650
F src/pager.h fc0c95d27f2aefffcb39b4373b3557e89e1b4b9a36b183cc04d6f22002bf0ad2
@@ -785,14 +785,14 @@ F src/pragma.c c6dbc66743689d2a7a8073a49ee0440df939fca8e1c5ab38c8ea5a0d8c0a2a85
F src/prepare.c 1832be043fce7d489959aae6f994c452d023914714c4d5457beaed51c0f3d126
F src/printf.c 3b91c334f528359145f4dde0dedd945bbb21044d0825ea064934d7222d61662c
F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
F src/resolve.c 20e1fbe8f840ffc0cd835e33f68a802a22e34faa918d7a269f3de242fda02f99
F src/resolve.c d40fe18d7c2fd0339f5846ffcf7d6809866e380acdf14c76fb2af87e9fe13f64
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 1a5956231f7c57571288eaad61e5c37aaf0f3acb5c8a5ea0b896938166b62fa2
F src/shell.c.in 2c904da4431fed365e7d5029b8cb2da46cb3e8cf8a09305d1478836a2301ea96
F src/select.c ee072fe20566119a195a5a3df454479bb6e944de7aef7006ff0b4d4612f9cb86
F src/shell.c.in ba53a52dafb167ac6320703da741386c34fbcabe8c078a188bb9f89808e3ef8f
F src/sqlite.h.in 22882ddd3a70751aa8864c81993ee4562ed54c2c508b6270f75e223ffee38e1b
F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
F src/sqliteInt.h 8b18ed676757ce49df633b603a465655aa105d9862821ffa9296afb189ba564f
F src/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e
F src/sqliteInt.h ded2e1527c84603d9d91adccb63dda460d96a2e2f98111d0438a479aa0dbe4e3
F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b
F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -843,8 +843,8 @@ F src/test_tclvar.c ae873248a0188459b1c16ca7cc431265dacce524399e8b46725c2b3b7e04
F src/test_thread.c 3edb4a5b5aeb1a6e9a275dccc848ac95acab7f496b3e9230f6d2d04953a2b862
F src/test_vdbecov.c 5c426d9cd2b351f5f9ceb30cabf8c64a63bfcad644c507e0bd9ce2f6ae1a3bf3
F src/test_vfs.c b4135c1308516adf0dfd494e6d6c33114e03732be899eace0502919b674586b5
F src/test_windirent.c a895e2c068a06644eef91a7f0a32182445a893b9a0f33d0cdb4283dca2486ac1
F src/test_windirent.h da2e5b73c32d09905fbdd00f27cd802212a32a58ead882736fe4f5eb775ebc50
F src/test_windirent.c cbee2b9a118b56b5a26b99c895adcbc861587bc66d24b88d1ad6e4c1d09dad7b
F src/test_windirent.h f8245d8002aa0d4322192d35b0f8bbfc757479e90d60fd0beb386d3913f72cdd
F src/test_window.c 6d80e11fba89a1796525e6f0048ff0c7789aa2c6b0b11c80827dc1437bd8ea72
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
@@ -853,7 +853,7 @@ F src/treeview.c d85ce76e6d1498d781957c07cb234da6d77ce0ed2d196480d516f54dabc6227
F src/trigger.c 3ffb8ed6b64dbcc0ccae6e82435d01be3bf547e13b814e2d46f7df9bef84748e
F src/update.c 3e5e7ff66fa19ebe4d1b113d480639a24cc1175adbefabbd1a948a07f28e37cf
F src/upsert.c 215328c3f91623c520ec8672c44323553f12caeb4f01b1090ebdca99fdf7b4f1
F src/utf.c 3a20cbae9688af4c1e3754cc2520189d00762e37f60c2deb0b303360d166bba6
F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165
F src/util.c 36fb1150062957280777655976f3f9a75db236cb8207a0770ceae8d5ec17fcd3
F src/vacuum.c d580ceb395c1ae3d59da41cbfea60683ff7dd2b94ddf4d0f5657620159e2eeb7
F src/vdbe.c ca31e2e5b3f4cdb2dd3ac5c1be3194d71d01e42df1de217c558acf0acbb7ecd2
@@ -871,9 +871,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 40492478a4bb0cc5de0f365b18a50fef6751aff36aa005959b7abcf6176e2101
F src/wal.h 97b8a9903387401377b59507e86b93a148ef1ad4e5ce0f23659a12dcdce56af2
F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014
F src/where.c 16aab5421a7119063fdb138dce6b53c57c50ad01b0b64992dacb14f946fe8d4a
F src/where.c 1d06561f7310af61bef8a046fa95d463ad88f855be9036fec9091f984520afc5
F src/whereInt.h ecdbfb5551cf394f04ec7f0bc7ad963146d80eee3071405ac29aa84950128b8e
F src/wherecode.c d67fadf5430c2647773b5f702a47b82eb4af50a317f8978c0c82363cc1a5107f
F src/wherecode.c 8825756ea7b1a49ac830719d28557c638520bb2434fe9c2dd6c7f584034bfe32
F src/whereexpr.c 2415c8eee5ff89a8b709d7d83d71c1ff986cd720d0520057e1d8a5371339012a
F src/window.c d01227141f622f24fbe36ca105fbe6ef023f9fd98f1ccd65da95f88886565db5
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
@@ -1079,7 +1079,7 @@ F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68
F test/date.test 180301372ed42520ff2d1c9bfa1d2aa726a0530d32452bd3f88f0a1c40f3c21e
F test/date2.test 7e12ec14aaf4d5e6294b4ba140445b0eca06ea50062a9c3a69c4ee13d0b6f8b1
F test/date3.test a1b77abf05c6772fe5ca2337cac1398892f2a41e62bce7e6be0f4a08a0e64ae5
F test/date4.test 75dc8401e8c0639a228cd26a6eaa4ff5ea8ccda912b9853d1c9462c476670e17
F test/date4.test b5ad22baf7394e008ac59383840159daedd45be31dcf74a3b2450ec0e28955ce
F test/date5.test 14ba189bc4d03efc371dd5302e035764f6633355a3e13acb4a45e7b33530231e
F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603
F test/dbfuzz.c fc566102f72c8af84ae8077b4faf7f056c571e6fa7a32e98b66e42b7505f47b6
@@ -2165,9 +2165,9 @@ F tool/logest.c c34e5944318415de513d29a6098df247a9618c96d83c38d4abd88641fe46e669
F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439
F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176
F tool/mkamalzip.tcl 8aa5ebe7973c8b8774062d34e15fea9815c4cc2ceea3a9b184695f005910876a
F tool/mkautoconfamal.sh 07b43da6ef5dfe4c8a119f813b997429e7237ccf537daa14e19af6e6d5a0947f
F tool/mkautoconfamal.sh 564378ae48cc8f4c8c68ef6d00228a0b2a70e2e3e4c67f26be1dd05d9730fefd
F tool/mkccode.tcl c42a8f8cf78f92e83795d5447460dbce7aaf78a3bbf9082f1507dc71a3665f3c x
F tool/mkctimec.tcl a384e7613db2a46e346cb4593731239a9239e942ff00aabd0c2b5d9e7afae840 x
F tool/mkctimec.tcl 313359eb98ff56bdd75e45817b0400ed2a748eaa800f5fd8d30386e44f84ea3e x
F tool/mkkeywordhash.c 6b0be901c47f9ad42215fc995eb2f4384ac49213b1fba395102ec3e999acf559
F tool/mkmsvcmin.tcl d76c45efda1cce2d4005bcea7b8a22bb752e3256009f331120fb4fecb14ebb7a
F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef
@@ -2203,10 +2203,10 @@ F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d
F tool/split-sqlite3c.tcl 07e18a1d8cc3f6b3a4a1f3528e63c9b29a5c8a7bca0b8d394b231da464ce1247
F tool/sqldiff.c 134be7866be19f8beb32043d5aea5657f01aaeae2df8d33d758ff722c78666b9
F tool/sqlite3_analyzer.c.in 14f02cb5ec3c264cd6107d1f1dad77092b1cf440fc196c30b69ae87b56a1a43b
F tool/sqlite3_rsync.c dcf03373565eab543bd43926ed7e97ade744ab0599115fde1ff8aadf04fa4974
F tool/sqlite3_rsync.c e8659970e839d71d2ef04b96d48ad65f1d4298a41636affaf93c32ed71f3f879
F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898
F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848
F tool/src-verify.c d00f93263aa2fa6ba0cba0106d95458e6effb94fdb5fc634f56834f90c05bbb4
F tool/src-verify.c 6c655d9a8d6b30f3648fc78a79bf3838ed68f8543869d380c43ea9f17b3b8501
F tool/srcck1.c 559e703c6cca1d70398bdba1d7f91036c1a71adf718a1aaa6401a562ccaed154
F tool/srctree-check.tcl fa4d82dd3e8a38d5cbce7d6ade8abef2f42b9eca0394484d521dc8d086739460
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
@@ -2219,10 +2219,10 @@ F tool/vdbe-compress.tcl fa2f37ab39b2a0087fafb6a7f3ce19503e25e624ffa8ed9951717ab
F tool/vdbe_profile.tcl 3ac5a4a9449f4baf77059358ea050db3e34395ccf59c5464d29b91746d5b961e
F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd72273503ae7d5
F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139
F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P c68d0d353082a5810a48f01637d642bcdfd9f03dd244e0618fc0d7cf5f7b9b12 6eb2939a6093c0796910645172d80c53055559dd57c012f1dc815d89fbf84447
R 71f6d3dc7cf4b3e239f1610c654bf049
P b17f5beab892028fa3e246858f7b34e9104ffb4edd970804e31e5c71bcd5bbc5 ba8184d132a935aa1980fbfb61ff308b93d433d559db4968f9014f7653ac9c6e
R 553b84faa01beb61e8558d962f0d971a
U drh
Z ae0c7f7b4f8ebc4d74a219746691a228
Z 1736e707bd1f686ff74d05d5968fe7d8
# Remove this line to create a well-formed Fossil manifest.

View File

@@ -1 +1 @@
b17f5beab892028fa3e246858f7b34e9104ffb4edd970804e31e5c71bcd5bbc5
720d175478e05921d97c561ca6883d0531188804009f388954fdb54642dec1e5

View File

@@ -1223,10 +1223,10 @@ static int renameEditSql(
}
assert( nQuot>=nNew && nSql>=0 && nNew>=0 );
zOut = sqlite3DbMallocZero(db, (u64)(nSql + pRename->nList*nQuot + 1));
zOut = sqlite3DbMallocZero(db, (u64)nSql + pRename->nList*(u64)nQuot + 1);
}else{
assert( nSql>0 );
zOut = (char*)sqlite3DbMallocZero(db, (u64)(nSql*2+1) * 3);
zOut = (char*)sqlite3DbMallocZero(db, (2*(u64)nSql + 1) * 3);
if( zOut ){
zBuf1 = &zOut[nSql*2+1];
zBuf2 = &zOut[nSql*4+2];

View File

@@ -1576,16 +1576,6 @@ static void decodeIntArray(
while( z[0]!=0 && z[0]!=' ' ) z++;
while( z[0]==' ' ) z++;
}
/* Set the bLowQual flag if the peak number of rows obtained
** from a full equality match is so large that a full table scan
** seems likely to be faster than using the index.
*/
if( aLog[0] > 66 /* Index has more than 100 rows */
&& aLog[0] <= aLog[nOut-1] /* And only a single value seen */
){
pIndex->bLowQual = 1;
}
}
}

View File

@@ -1756,7 +1756,12 @@ json_parse_restart:
|| c=='n' || c=='r' || c=='t'
|| (c=='u' && jsonIs4Hex(&z[j+1])) ){
if( opcode==JSONB_TEXT ) opcode = JSONB_TEXTJ;
}else if( c=='\'' || c=='0' || c=='v' || c=='\n'
}else if( c=='\'' || c=='v' || c=='\n'
#ifdef SQLITE_BUG_COMPATIBLE_20250510
|| (c=='0') /* Legacy bug compatible */
#else
|| (c=='0' && !sqlite3Isdigit(z[j+1])) /* Correct implementation */
#endif
|| (0xe2==(u8)c && 0x80==(u8)z[j+1]
&& (0xa8==(u8)z[j+2] || 0xa9==(u8)z[j+2]))
|| (c=='x' && jsonIs2Hex(&z[j+1])) ){
@@ -2143,7 +2148,7 @@ static u32 jsonbPayloadSize(const JsonParse *pParse, u32 i, u32 *pSz){
*pSz = 0;
return 0;
}
sz = (pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) +
sz = ((u32)pParse->aBlob[i+5]<<24) + (pParse->aBlob[i+6]<<16) +
(pParse->aBlob[i+7]<<8) + pParse->aBlob[i+8];
n = 9;
}
@@ -2724,7 +2729,21 @@ static u32 jsonUnescapeOneChar(const char *z, u32 n, u32 *piOut){
case 'r': { *piOut = '\r'; return 2; }
case 't': { *piOut = '\t'; return 2; }
case 'v': { *piOut = '\v'; return 2; }
case '0': { *piOut = 0; return 2; }
case '0': {
/* JSON5 requires that the \0 escape not be followed by a digit.
** But SQLite did not enforce this restriction in versions 3.42.0
** through 3.49.2. That was a bug. But some applications might have
** come to depend on that bug. Use the SQLITE_BUG_COMPATIBLE_20250510
** option to restore the old buggy behavior. */
#ifdef SQLITE_BUG_COMPATIBLE_20250510
/* Legacy bug-compatible behavior */
*piOut = 0;
#else
/* Correct behavior */
*piOut = (n>2 && sqlite3Isdigit(z[2])) ? JSON_INVALID_CHAR : 0;
#endif
return 2;
}
case '\'':
case '"':
case '/':

View File

@@ -517,7 +517,9 @@ static const sqlite3_api_routines sqlite3Apis = {
sqlite3_stmt_explain,
/* Version 3.44.0 and later */
sqlite3_get_clientdata,
sqlite3_set_clientdata
sqlite3_set_clientdata,
/* Version 3.50.0 and later */
sqlite3_setlk_timeout
};
/* True if x is the directory separator character

View File

@@ -4208,13 +4208,13 @@ static void *winConvertFromUtf8Filename(const char *zFilename){
if( osCygwin_conv_path && !(winIsDriveLetterAndColon(zFilename)
&& winIsDirSep(zFilename[2])) ){
int nByte;
i64 nByte;
int convertflag = CCP_POSIX_TO_WIN_W;
if( !strchr(zFilename, '/') ) convertflag |= CCP_RELATIVE;
nByte = (int)osCygwin_conv_path(convertflag,
nByte = (i64)osCygwin_conv_path(convertflag,
zFilename, 0, 0);
if( nByte>0 ){
zConverted = sqlite3MallocZero(nByte+12);
zConverted = sqlite3MallocZero(12+(u64)nByte);
if ( zConverted==0 ){
return zConverted;
}
@@ -5097,27 +5097,6 @@ static winVfsAppData winNolockAppData = {
** sqlite3_vfs object.
*/
#if 0 /* No longer necessary */
/*
** Convert a filename from whatever the underlying operating system
** supports for filenames into UTF-8. Space to hold the result is
** obtained from malloc and must be freed by the calling function.
*/
static char *winConvertToUtf8Filename(const void *zFilename){
char *zConverted = 0;
if( osIsNT() ){
zConverted = winUnicodeToUtf8(zFilename);
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
zConverted = winMbcsToUtf8(zFilename, osAreFileApisANSI());
}
#endif
/* caller will handle out of memory */
return zConverted;
}
#endif
/*
** This function returns non-zero if the specified UTF-8 string buffer
** ends with a directory separator character or one was successfully
@@ -5257,42 +5236,6 @@ static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
break;
}
sqlite3_free(zConverted);
#if 0 /* No longer necessary */
}else{
zConverted = sqlite3MallocZero( nMax+1 );
if( !zConverted ){
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
return SQLITE_IOERR_NOMEM_BKPT;
}
if( osCygwin_conv_path(
CCP_POSIX_TO_WIN_W, zDir,
zConverted, nMax+1)<0 ){
sqlite3_free(zConverted);
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n"));
return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno,
"winGetTempname2", zDir);
}
if( winIsDir(zConverted) ){
/* At this point, we know the candidate directory exists and should
** be used. However, we may need to convert the string containing
** its name into UTF-8 (i.e. if it is UTF-16 right now).
*/
char *zUtf8 = winConvertToUtf8Filename(zConverted);
if( !zUtf8 ){
sqlite3_free(zConverted);
sqlite3_free(zBuf);
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
return SQLITE_IOERR_NOMEM_BKPT;
}
sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
sqlite3_free(zUtf8);
sqlite3_free(zConverted);
break;
}
sqlite3_free(zConverted);
#endif /* No longer necessary */
}
}
}
@@ -6191,34 +6134,6 @@ static int winFullPathnameNoMutex(
}
}
#endif /* __CYGWIN__ */
#if 0 /* This doesn't work correctly at all! See:
<https://marc.info/?l=sqlite-users&m=139299149416314&w=2>
*/
SimulateIOError( return SQLITE_ERROR );
UNUSED_PARAMETER(nFull);
assert( nFull>=pVfs->mxPathname );
char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
if( !zOut ){
return SQLITE_IOERR_NOMEM_BKPT;
}
if( osCygwin_conv_path(
CCP_POSIX_TO_WIN_W,
zRelative, zOut, pVfs->mxPathname+1)<0 ){
sqlite3_free(zOut);
return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
"winFullPathname2", zRelative);
}else{
char *zUtf8 = winConvertToUtf8Filename(zOut);
if( !zUtf8 ){
sqlite3_free(zOut);
return SQLITE_IOERR_NOMEM_BKPT;
}
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
sqlite3_free(zUtf8);
sqlite3_free(zOut);
}
return SQLITE_OK;
#endif
#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && defined(_WIN32)
SimulateIOError( return SQLITE_ERROR );
@@ -6364,27 +6279,8 @@ static int winFullPathname(
*/
static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
HANDLE h;
#if 0 /* This doesn't work correctly at all! See:
<https://marc.info/?l=sqlite-users&m=139299149416314&w=2>
*/
int nFull = pVfs->mxPathname+1;
char *zFull = sqlite3MallocZero( nFull );
void *zConverted = 0;
if( zFull==0 ){
OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
return 0;
}
if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){
sqlite3_free(zFull);
OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
return 0;
}
zConverted = winConvertFromUtf8Filename(zFull);
sqlite3_free(zFull);
#else
void *zConverted = winConvertFromUtf8Filename(zFilename);
UNUSED_PARAMETER(pVfs);
#endif
if( zConverted==0 ){
OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
return 0;

View File

@@ -1202,13 +1202,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
** sqlite_version() that might change over time cannot be used
** in an index or generated column. Curiously, they can be used
** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all
** all this. */
** allow this. */
sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions",
NC_IdxExpr|NC_PartIdx|NC_GenCol, 0, pExpr);
}else{
assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */
pExpr->op2 = pNC->ncFlags & NC_SelfRef;
if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL);
}
if( (pDef->funcFlags & SQLITE_FUNC_INTERNAL)!=0
&& pParse->nested==0
@@ -1224,6 +1223,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0
&& !IN_RENAME_OBJECT
){
if( pNC->ncFlags & NC_FromDDL ) ExprSetProperty(pExpr, EP_FromDDL);
sqlite3ExprFunctionUsable(pParse, pExpr, pDef);
}
}

View File

@@ -8498,6 +8498,10 @@ int sqlite3Select(
if( iOrderByCol ){
Expr *pX = p->pEList->a[iOrderByCol-1].pExpr;
Expr *pBase = sqlite3ExprSkipCollateAndLikely(pX);
while( ALWAYS(pBase!=0) && pBase->op==TK_IF_NULL_ROW ){
pX = pBase->pLeft;
pBase = sqlite3ExprSkipCollateAndLikely(pX);
}
if( ALWAYS(pBase!=0)
&& pBase->op!=TK_AGG_COLUMN
&& pBase->op!=TK_REGISTER

View File

@@ -5340,103 +5340,104 @@ static const char *(azHelp[]) = {
};
/*
** Output help text.
** Output help text for commands that match zPattern.
**
** zPattern describes the set of commands for which help text is provided.
** If zPattern is NULL, then show all commands, but only give a one-line
** description of each.
** * If zPattern is NULL, then show all documented commands, but
** only give a one-line summary of each.
**
** Return the number of matches.
** * If zPattern is "-a" or "-all" or "--all" then show all help text
** for all commands except undocumented commands.
**
** * If zPattern is "0" then show all help for undocumented commands.
** Undocumented commands begin with "," instead of "." in the azHelp[]
** array.
**
** * If zPattern is a prefix for one or more documented commands, then
** show help for those commands. If only a single command matches the
** prefix, show the full text of the help. If multiple commands match,
** Only show just the first line of each.
**
** * Otherwise, show the complete text of any documented command for which
** zPattern is a LIKE match for any text within that command help
** text.
**
** Return the number commands that match zPattern.
*/
static int showHelp(FILE *out, const char *zPattern){
int i = 0;
int j = 0;
int n = 0;
char *zPat;
if( zPattern==0
|| zPattern[0]=='0'
|| cli_strcmp(zPattern,"-a")==0
|| cli_strcmp(zPattern,"-all")==0
|| cli_strcmp(zPattern,"--all")==0
if( zPattern==0 ){
/* Show just the first line for all help topics */
zPattern = "[a-z]";
}else if( cli_strcmp(zPattern,"-a")==0
|| cli_strcmp(zPattern,"-all")==0
|| cli_strcmp(zPattern,"--all")==0
){
enum HelpWanted { HW_NoCull = 0, HW_SummaryOnly = 1, HW_Undoc = 2 };
enum HelpHave { HH_Undoc = 2, HH_Summary = 1, HH_More = 0 };
/* Show all or most commands
** *zPattern==0 => summary of documented commands only
** *zPattern=='0' => whole help for undocumented commands
** Otherwise => whole help for documented commands
*/
enum HelpWanted hw = HW_SummaryOnly;
enum HelpHave hh = HH_More;
if( zPattern!=0 ){
hw = (*zPattern=='0')? HW_NoCull|HW_Undoc : HW_NoCull;
}
/* Show everything except undocumented commands */
zPattern = ".";
}else if( cli_strcmp(zPattern,"0")==0 ){
/* Show complete help text of undocumented commands */
int show = 0;
for(i=0; i<ArraySize(azHelp); i++){
switch( azHelp[i][0] ){
case ',':
hh = HH_Summary|HH_Undoc;
break;
case '.':
hh = HH_Summary;
break;
default:
hh &= ~HH_Summary;
break;
}
if( ((hw^hh)&HH_Undoc)==0 ){
if( (hh&HH_Summary)!=0 ){
sqlite3_fprintf(out, ".%s\n", azHelp[i]+1);
++n;
}else if( (hw&HW_SummaryOnly)==0 ){
sqlite3_fprintf(out, "%s\n", azHelp[i]);
}
}
}
}else{
/* Seek documented commands for which zPattern is an exact prefix */
zPat = sqlite3_mprintf(".%s*", zPattern);
shell_check_oom(zPat);
for(i=0; i<ArraySize(azHelp); i++){
if( sqlite3_strglob(zPat, azHelp[i])==0 ){
if( azHelp[i][0]=='.' ){
show = 0;
}else if( azHelp[i][0]==',' ){
show = 1;
sqlite3_fprintf(out, ".%s\n", &azHelp[i][1]);
n++;
}else if( show ){
sqlite3_fprintf(out, "%s\n", azHelp[i]);
j = i+1;
n++;
}
}
sqlite3_free(zPat);
if( n ){
if( n==1 ){
/* when zPattern is a prefix of exactly one command, then include
** the details of that command, which should begin at offset j */
while( j<ArraySize(azHelp)-1 && azHelp[j][0]==' ' ){
sqlite3_fprintf(out, "%s\n", azHelp[j]);
j++;
}
}
return n;
}
/* Look for documented commands that contain zPattern anywhere.
** Show complete text of all documented commands that match. */
zPat = sqlite3_mprintf("%%%s%%", zPattern);
shell_check_oom(zPat);
for(i=0; i<ArraySize(azHelp); i++){
if( azHelp[i][0]==',' ){
while( i<ArraySize(azHelp)-1 && azHelp[i+1][0]==' ' ) ++i;
continue;
}
if( azHelp[i][0]=='.' ) j = i;
if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
sqlite3_fprintf(out, "%s\n", azHelp[j]);
while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]==' ' ){
j++;
sqlite3_fprintf(out, "%s\n", azHelp[j]);
}
i = j;
n++;
}
}
sqlite3_free(zPat);
return n;
}
/* Seek documented commands for which zPattern is an exact prefix */
zPat = sqlite3_mprintf(".%s*", zPattern);
shell_check_oom(zPat);
for(i=0; i<ArraySize(azHelp); i++){
if( sqlite3_strglob(zPat, azHelp[i])==0 ){
sqlite3_fprintf(out, "%s\n", azHelp[i]);
j = i+1;
n++;
}
}
sqlite3_free(zPat);
if( n ){
if( n==1 ){
/* when zPattern is a prefix of exactly one command, then include
** the details of that command, which should begin at offset j */
while( j<ArraySize(azHelp)-1 && azHelp[j][0]==' ' ){
sqlite3_fprintf(out, "%s\n", azHelp[j]);
j++;
}
}
return n;
}
/* Look for documented commands that contain zPattern anywhere.
** Show complete text of all documented commands that match. */
zPat = sqlite3_mprintf("%%%s%%", zPattern);
shell_check_oom(zPat);
for(i=0; i<ArraySize(azHelp); i++){
if( azHelp[i][0]==',' ){
while( i<ArraySize(azHelp)-1 && azHelp[i+1][0]==' ' ) ++i;
continue;
}
if( azHelp[i][0]=='.' ) j = i;
if( sqlite3_strlike(zPat, azHelp[i], 0)==0 ){
sqlite3_fprintf(out, "%s\n", azHelp[j]);
while( j<ArraySize(azHelp)-1 && azHelp[j+1][0]==' ' ){
j++;
sqlite3_fprintf(out, "%s\n", azHelp[j]);
}
i = j;
n++;
}
}
sqlite3_free(zPat);
return n;
}

View File

@@ -366,6 +366,8 @@ struct sqlite3_api_routines {
/* Version 3.44.0 and later */
void *(*get_clientdata)(sqlite3*,const char*);
int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*));
/* Version 3.50.0 and later */
int (*setlk_timeout)(sqlite3*,int,int);
};
/*
@@ -699,6 +701,8 @@ typedef int (*sqlite3_loadext_entry)(
/* Version 3.44.0 and later */
#define sqlite3_get_clientdata sqlite3_api->get_clientdata
#define sqlite3_set_clientdata sqlite3_api->set_clientdata
/* Version 3.50.0 and later */
#define sqlite3_setlk_timeout sqlite3_api->setlk_timeout
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)

View File

@@ -2789,7 +2789,6 @@ struct Index {
unsigned isCovering:1; /* True if this is a covering index */
unsigned noSkipScan:1; /* Do not try to use skip-scan if true */
unsigned hasStat1:1; /* aiRowLogEst values come from sqlite_stat1 */
unsigned bLowQual:1; /* sqlite_stat1 says this is a low-quality index */
unsigned bNoQuery:1; /* Do not use this index to optimize queries */
unsigned bAscKeyBug:1; /* True if the bba7b69f9849b5bf bug applies */
unsigned bIdxRowid:1; /* One or more of the index keys is the ROWID */

View File

@@ -48,11 +48,13 @@ const char *windirent_getenv(
** Implementation of the POSIX opendir() function using the MSVCRT.
*/
LPDIR opendir(
const char *dirname
const char *dirname /* Directory name, UTF8 encoding */
){
struct _finddata_t data;
struct _wfinddata_t data;
LPDIR dirp = (LPDIR)sqlite3_malloc(sizeof(DIR));
SIZE_T namesize = sizeof(data.name) / sizeof(data.name[0]);
wchar_t *b1;
sqlite3_int64 sz;
if( dirp==NULL ) return NULL;
memset(dirp, 0, sizeof(DIR));
@@ -62,9 +64,25 @@ LPDIR opendir(
dirname = windirent_getenv("SystemDrive");
}
memset(&data, 0, sizeof(struct _finddata_t));
_snprintf(data.name, namesize, "%s\\*", dirname);
dirp->d_handle = _findfirst(data.name, &data);
memset(&data, 0, sizeof(data));
sz = strlen(dirname);
b1 = sqlite3_malloc64( (sz+3)*sizeof(b1[0]) );
if( b1==0 ){
closedir(dirp);
return NULL;
}
sz = MultiByteToWideChar(CP_UTF8, 0, dirname, sz, b1, sz);
b1[sz++] = '\\';
b1[sz++] = '*';
b1[sz] = 0;
if( sz+1>(sqlite3_int64)namesize ){
closedir(dirp);
sqlite3_free(b1);
return NULL;
}
memcpy(data.name, b1, (sz+1)*sizeof(b1[0]));
sqlite3_free(b1);
dirp->d_handle = _wfindfirst(data.name, &data);
if( dirp->d_handle==BAD_INTPTR_T ){
closedir(dirp);
@@ -75,8 +93,8 @@ LPDIR opendir(
if( is_filtered(data) ){
next:
memset(&data, 0, sizeof(struct _finddata_t));
if( _findnext(dirp->d_handle, &data)==-1 ){
memset(&data, 0, sizeof(data));
if( _wfindnext(dirp->d_handle, &data)==-1 ){
closedir(dirp);
return NULL;
}
@@ -86,9 +104,8 @@ next:
}
dirp->d_first.d_attributes = data.attrib;
strncpy(dirp->d_first.d_name, data.name, NAME_MAX);
dirp->d_first.d_name[NAME_MAX] = '\0';
WideCharToMultiByte(CP_UTF8, 0, data.name, -1,
dirp->d_first.d_name, DIRENT_NAME_MAX, 0, 0);
return dirp;
}
@@ -98,7 +115,7 @@ next:
LPDIRENT readdir(
LPDIR dirp
){
struct _finddata_t data;
struct _wfinddata_t data;
if( dirp==NULL ) return NULL;
@@ -111,65 +128,19 @@ LPDIRENT readdir(
next:
memset(&data, 0, sizeof(struct _finddata_t));
if( _findnext(dirp->d_handle, &data)==-1 ) return NULL;
memset(&data, 0, sizeof(data));
if( _wfindnext(dirp->d_handle, &data)==-1 ) return NULL;
/* TODO: Remove this block to allow hidden and/or system files. */
if( is_filtered(data) ) goto next;
dirp->d_next.d_ino++;
dirp->d_next.d_attributes = data.attrib;
strncpy(dirp->d_next.d_name, data.name, NAME_MAX);
dirp->d_next.d_name[NAME_MAX] = '\0';
WideCharToMultiByte(CP_UTF8, 0, data.name, -1,
dirp->d_next.d_name, DIRENT_NAME_MAX, 0, 0);
return &dirp->d_next;
}
/*
** Implementation of the POSIX readdir_r() function using the MSVCRT.
*/
INT readdir_r(
LPDIR dirp,
LPDIRENT entry,
LPDIRENT *result
){
struct _finddata_t data;
if( dirp==NULL ) return EBADF;
if( dirp->d_first.d_ino==0 ){
dirp->d_first.d_ino++;
dirp->d_next.d_ino++;
entry->d_ino = dirp->d_first.d_ino;
entry->d_attributes = dirp->d_first.d_attributes;
strncpy(entry->d_name, dirp->d_first.d_name, NAME_MAX);
entry->d_name[NAME_MAX] = '\0';
*result = entry;
return 0;
}
next:
memset(&data, 0, sizeof(struct _finddata_t));
if( _findnext(dirp->d_handle, &data)==-1 ){
*result = NULL;
return ENOENT;
}
/* TODO: Remove this block to allow hidden and/or system files. */
if( is_filtered(data) ) goto next;
entry->d_ino = (ino_t)-1; /* not available */
entry->d_attributes = data.attrib;
strncpy(entry->d_name, data.name, NAME_MAX);
entry->d_name[NAME_MAX] = '\0';
*result = entry;
return 0;
}
/*
** Implementation of the POSIX closedir() function using the MSVCRT.
*/

View File

@@ -88,6 +88,7 @@
# else
# define NAME_MAX (260)
# endif
# define DIRENT_NAME_MAX (NAME_MAX)
#endif
/*
@@ -131,8 +132,7 @@ struct DIR {
/*
** Provide a macro, for use by the implementation, to determine if a
** particular directory entry should be skipped over when searching for
** the next directory entry that should be returned by the readdir() or
** readdir_r() functions.
** the next directory entry that should be returned by the readdir().
*/
#ifndef is_filtered
@@ -148,12 +148,11 @@ extern const char *windirent_getenv(const char *name);
/*
** Finally, we can provide the function prototypes for the opendir(),
** readdir(), readdir_r(), and closedir() POSIX functions.
** readdir(), and closedir() POSIX functions.
*/
extern LPDIR opendir(const char *dirname);
extern LPDIRENT readdir(LPDIR dirp);
extern INT readdir_r(LPDIR dirp, LPDIRENT entry, LPDIRENT *result);
extern INT closedir(LPDIR dirp);
#endif /* defined(WIN32) && defined(_MSC_VER) */

View File

@@ -108,7 +108,7 @@ static const unsigned char sqlite3Utf8Trans1[] = {
/*
** Write a single UTF8 character whose value is v into the
** buffer starting at zOut. zOut must be sized to hold at
** least for bytes. Return the number of bytes needed
** least four bytes. Return the number of bytes needed
** to encode the new character.
*/
int sqlite3AppendOneUtf8Character(char *zOut, u32 v){

View File

@@ -3159,11 +3159,8 @@ static int whereLoopAddBtreeIndex(
assert( pNew->u.btree.nBtm==0 );
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
}
if( pProbe->bUnordered || pProbe->bLowQual ){
if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
if( pProbe->bLowQual && pSrc->fg.isIndexedBy==0 ){
opMask &= ~(WO_EQ|WO_IN|WO_IS);
}
if( pProbe->bUnordered ){
opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
}
assert( pNew->u.btree.nEq<pProbe->nColumn );
@@ -4100,7 +4097,7 @@ static int whereLoopAddBtree(
&& (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700))
){
WHERETRACE(0x200,
("-> %s a covering index according to bitmasks\n",
("-> %s is a covering index according to bitmasks\n",
pProbe->zName, m==0 ? "is" : "is not"));
pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED;
}

View File

@@ -600,7 +600,7 @@ static Expr *removeUnindexableInClauseTerms(
iField = pLoop->aLTerm[i]->u.x.iField - 1;
if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
pOrigRhs->a[iField].pExpr = 0;
pOrigRhs->a[iField].pExpr = 0;
if( pRhs ) pRhs->a[pRhs->nExpr-1].u.x.iOrderByCol = iField+1;
if( pOrigLhs ){
assert( pOrigLhs->a[iField].pExpr!=0 );

View File

@@ -24,7 +24,13 @@ ifcapable {!datetime} {
}
if {$tcl_platform(os)=="Linux"} {
set FMT {%d,%e,%F,%H,%k,%I,%l,%j,%m,%M,%u,%w,%W,%Y,%%,%P,%p,%U,%V,%G,%g}
if {"" eq [strftime {%P} 1]} {
# This is probably musl libc, which does not support
# %k, %l, %P
set FMT {%d,%e,%F,%H,%I,%j,%m,%M,%u,%w,%W,%Y,%%,%p,%U,%V,%G,%g}
} else {
set FMT {%d,%e,%F,%H,%k,%I,%l,%j,%m,%M,%u,%w,%W,%Y,%%,%P,%p,%U,%V,%G,%g}
}
} else {
set FMT {%d,%e,%F,%H,%I,%j,%p,%R,%u,%w,%W,%%}
}

View File

@@ -63,7 +63,7 @@ cp $TOP/main.mk $TMPSPACE
cd $TMPSPACE
# Clean up emacs-generated backup files from the target
rm -f ./autosetup/*~
rm -f ./autosetup/*~ ./autosetup/teaish/*~
rm -f ./*~
#if true; then
@@ -73,10 +73,6 @@ rm -f ./*~
# find . -name '*~' -exec rm \{} \;
#fi
mkdir -p autosetup/teaish
mv tea/autosetup/*.tcl autosetup/teaish/.
rm -fr tea/autosetup
mkdir -p tea/generic
cat <<EOF > tea/generic/tclsqlite3.c
#ifdef USE_SYSTEM_SQLITE

View File

@@ -108,6 +108,7 @@ set boolean_defnil_options {
SQLITE_ALLOW_ROWID_IN_VIEW
SQLITE_ALLOW_URI_AUTHORITY
SQLITE_BUG_COMPATIBLE_20160819
SQLITE_BUG_COMPATIBLE_20250510
SQLITE_CASE_SENSITIVE_LIKE
SQLITE_CHECK_PAGES
SQLITE_COVERAGE_TEST

View File

@@ -601,8 +601,6 @@ void add_path_argument(sqlite3_str *pStr){
# endif
#endif
typedef sqlite3_uint64 u64;
/*
** State structure for a Hash hash in progress
*/

View File

@@ -752,7 +752,7 @@ void sha1sum_file(const char *zFilename, char *zCksum){
SHA1Final(zResult, &ctx);
DigestToBase16(zResult, zCksum, 20);
}
/*
** Decode a fossilized string in-place.
*/

View File

@@ -10,7 +10,7 @@ if uname | grep -i openbsd ; then
WARNING_ANDROID_OPTS=-Wall
else
# Use these for testing on Linux and Mac OSX:
WARNING_OPTS="-Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long"
WARNING_OPTS="-Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -Wno-array-bounds"
gccvers=`gcc -v 2>&1 | grep '^gcc version'`
if test "$gccvers" '<' 'gcc version 6'
then
@@ -22,15 +22,15 @@ fi
rm -f sqlite3.c
make sqlite3.c
echo '********** No optimizations. Includes FTS4/5, GEOPOLY, JSON1 ***'
echo '********** ' Options: $WARNING_OPTS
echo '**** No optimizations. Includes FTS4/5, GEOPOLY, JSON1 ***'
echo '****' $WARNING_OPTS
gcc -c $WARNING_OPTS -std=c89 \
-ansi -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_GEOPOLY \
-DSQLITE_ENABLE_FTS5 \
sqlite3.c
if test x`uname` = 'xLinux'; then
echo '********** Android configuration ******************************'
echo '********** ' Options: $WARNING_ANDROID_OPTS
echo '**** Android configuration ******************************'
echo '****' $WARNING_ANDROID_OPTS
gcc -c \
-DSQLITE_HAVE_ISNAN \
-DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576 \
@@ -52,13 +52,13 @@ gcc -c \
$WARNING_ANDROID_OPTS \
-Os sqlite3.c shell.c
fi
echo '********** No optimizations. ENABLE_STAT4. THREADSAFE=0 *******'
echo '********** ' Options: $WARNING_OPTS
echo '**** No optimizations. ENABLE_STAT4. THREADSAFE=0 *******'
echo '****' $WARNING_OPTS
gcc -c $WARNING_OPTS -std=c89 \
-ansi -DSQLITE_ENABLE_STAT4 -DSQLITE_THREADSAFE=0 \
sqlite3.c
echo '********** Optimized -O3. Includes FTS4/5, GEOPOLY, JSON1 ******'
echo '********** ' Options: $WARNING_OPTS
echo '**** Optimized -O3. Includes FTS4/5, GEOPOLY, JSON1 ******'
echo '****' $WARNING_OPTS
gcc -O3 -c $WARNING_OPTS -std=c89 \
-ansi -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_GEOPOLY \
-DSQLITE_ENABLE_FTS5 \