diff options
-rw-r--r-- | autoconf/tea/Makefile.in | 73 | ||||
-rw-r--r-- | autoconf/tea/_teaish.tester.tcl.in (renamed from autoconf/tea/teaish.tester.tcl.in) | 8 | ||||
-rw-r--r-- | autoconf/tea/teaish.tcl | 2 | ||||
-rw-r--r-- | autosetup/proj.tcl | 135 | ||||
-rw-r--r-- | autosetup/teaish/README.txt (renamed from autoconf/tea/autosetup/README.txt) | 0 | ||||
-rw-r--r-- | autosetup/teaish/core.tcl (renamed from autoconf/tea/autosetup/core.tcl) | 515 | ||||
-rw-r--r-- | autosetup/teaish/feature.tcl (renamed from autoconf/tea/autosetup/feature-tests.tcl) | 0 | ||||
-rw-r--r-- | autosetup/teaish/tester.tcl (renamed from autoconf/tea/autosetup/tester.tcl) | 83 | ||||
-rw-r--r-- | ext/rtree/rtree.c | 2 | ||||
-rw-r--r-- | manifest | 46 | ||||
-rw-r--r-- | manifest.uuid | 2 | ||||
-rw-r--r-- | src/alter.c | 4 | ||||
-rw-r--r-- | src/loadext.c | 4 | ||||
-rw-r--r-- | src/os_win.c | 110 | ||||
-rw-r--r-- | src/sqlite3ext.h | 4 | ||||
-rw-r--r-- | src/utf.c | 2 | ||||
-rw-r--r-- | src/wherecode.c | 2 | ||||
-rw-r--r-- | tool/mkautoconfamal.sh | 6 | ||||
-rw-r--r-- | tool/src-verify.c | 2 | ||||
-rw-r--r-- | tool/warnings.sh | 18 |
20 files changed, 595 insertions, 423 deletions
diff --git a/autoconf/tea/Makefile.in b/autoconf/tea/Makefile.in index ad71c8b3e..5b2ad4c69 100644 --- a/autoconf/tea/Makefile.in +++ b/autoconf/tea/Makefile.in @@ -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) diff --git a/autoconf/tea/teaish.tester.tcl.in b/autoconf/tea/_teaish.tester.tcl.in index 4e203cd78..59d11f0a8 100644 --- a/autoconf/tea/teaish.tester.tcl.in +++ b/autoconf/tea/_teaish.tester.tcl.in @@ -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*] diff --git a/autoconf/tea/teaish.tcl b/autoconf/tea/teaish.tcl index 87d059c32..9333495aa 100644 --- a/autoconf/tea/teaish.tcl +++ b/autoconf/tea/teaish.tcl @@ -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 diff --git a/autosetup/proj.tcl b/autosetup/proj.tcl index 4691cfe36..133556706 100644 --- a/autosetup/proj.tcl +++ b/autosetup/proj.tcl @@ -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 { @@ -1259,6 +1274,8 @@ proc proj-defs-format_ {type 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 # fully-functional JSON emitter, and will emit broken JSON for @@ -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]} diff --git a/autoconf/tea/autosetup/README.txt b/autosetup/teaish/README.txt index e11519b04..e11519b04 100644 --- a/autoconf/tea/autosetup/README.txt +++ b/autosetup/teaish/README.txt diff --git a/autoconf/tea/autosetup/core.tcl b/autosetup/teaish/core.tcl index 4b3eb9a82..381597ec5 100644 --- a/autoconf/tea/autosetup/core.tcl +++ b/autosetup/teaish/core.tcl @@ -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 "" - - -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 { + - 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 - -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 - 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 {*} - } + set tdefs [teaish__defines_to_list] + define TEAISH__DEFINES_MAP $tdefs; # injected into _teaish.tester.tcl # - # If these are set up before call [options], it triggers an - # "option already defined" error. + # NO [define]s after this point! # - #proj-opt-set teaish.tcl [get-define ] - #proj-opt-set teaish.make.in [get-define ] + proj-dot-ins-process -validate + proj-if-opt-truthy teaish-dump-defines { + proj-file-write config.defines.txt $tdefs + } - # - # $::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} - } - lassign $args msg script + -quiet 0 {expr 1} + -key => 1 + -nomsg 0 {expr 1} + -msg-0 => no + -msg-1 => ok + } + 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). +# +# The $args are explained in the docs for internal-use-only +# [teaish__defs_format]. The default mode is -autolist. # -proc teaish__dump_defs_to_list {args} { +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 diff --git a/autoconf/tea/autosetup/feature-tests.tcl b/autosetup/teaish/feature.tcl index 6c927d1a7..6c927d1a7 100644 --- a/autoconf/tea/autosetup/feature-tests.tcl +++ b/autosetup/teaish/feature.tcl diff --git a/autoconf/tea/autosetup/tester.tcl b/autosetup/teaish/tester.tcl index 5c546e841..d8b5f7a0e 100644 --- a/autoconf/tea/autosetup/tester.tcl +++ b/autosetup/teaish/tester.tcl @@ -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? +# +# 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 affirm {args} { + tailcall test__affert 0 {*}$args +} + +# +# @assert ?-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 [affirm] but exits on error. # -proc assert {script {msg ""}} { - test__assert 1 $script $msg +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>>" } diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index 5e9fa6996..f90fd5a0a 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -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). @@ -1,5 +1,5 @@ -C Improved\sversion\sof\sthe\sprevious\scheck-in. -D 2025-05-16T18:19:11.764 +C Clarify\ssome\smalloc\ssize\scomputations\sto\ssimplify\sthe\sproof\sthat\sthey\nare\ssafe.\s\sRemove\ssome\scode\sassociated\swith\scygwin\sthat\sis\smarked\s"#if\s0". +D 2025-05-19T14:50:36.906 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 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 +F autosetup/teaish/core.tcl 1ebbe849d8e716424a3ffe9384c7e8b352b3e1194d3d4a153b125cc5176b3715 +F autosetup/teaish/feature.tcl 18194fb79a24d30e5bbdeab40999616f39278b53a27525349ded033af2fd73be +F autosetup/teaish/tester.tcl 091745984473faea6985254b9986c6dfd0cce06f68bc515ba4afc1e6b3742fa8 F configure 9a00b21dfd13757bbfb8d89b30660a89ec1f8f3a79402b8f9f9b6fc475c3303a x F contrib/sqlitecon.tcl eb4c6578e08dd353263958da0dc620f8400b869a50d06e271ab0be85a51a08d3 F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd @@ -539,7 +539,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 @@ -719,7 +719,7 @@ 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/alter.c fc7bbbeb9e89c7124bf5772ce474b333b7bdc18d6e080763211a40fde69fb1da F src/analyze.c 03bcfc083fc0cccaa9ded93604e1d4244ea245c17285d463ef6a60425fcb247d F src/attach.c 9af61b63b10ee702b1594ecd24fb8cea0839cfdb6addee52fba26fa879f5db9d F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc @@ -748,7 +748,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c d05934dfab2c5c0c480fc6fd2038f11215661de08ea6ff38d2563216bd555c1b 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 @@ -771,7 +771,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 9fbb541b46125dfa8914827575e6bb4d15048caa008073b1709112d495d7983b F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8 @@ -789,7 +789,7 @@ 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/sqlite3ext.h 0bfd049bb2088cc44c2ad54f2079d1c6e43091a4e1ce8868779b75f6c1484f1e F src/sqliteInt.h ded2e1527c84603d9d91adccb63dda460d96a2e2f98111d0438a479aa0dbe4e3 F src/sqliteLimit.h 6d817c28a8f19af95e6f4921933b7fbbca48a962bce0eb0ec81e8bb3ef38e68b F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd @@ -851,7 +851,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 0feab5781141acca67bd5de84172fff902304274ec5cfe58609f005b8d160050 @@ -871,7 +871,7 @@ F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 F src/walker.c d5006d6b005e4ea7302ad390957a8d41ed83faa177e412f89bc5600a7462a014 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 @@ -2151,7 +2151,7 @@ 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 11c9eda4a8d18c74b79280b30506d832849fd1855e6d9e95e1fd506f1d211c37 x F tool/mkkeywordhash.c 6b0be901c47f9ad42215fc995eb2f4384ac49213b1fba395102ec3e999acf559 @@ -2192,7 +2192,7 @@ F tool/sqlite3_analyzer.c.in 14f02cb5ec3c264cd6107d1f1dad77092b1cf440fc196c30b69 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 @@ -2205,10 +2205,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 955a026996b93e530ca5b566689cc646b31d3b9b5a5837897a58452d70f6d942 -R 804d8a6678db1d3197b731d5b4dee948 +P 8819b7285b71932327f47d29fa575cfb338e2fccd3f7c2023faf0575bfdb0079 +R 946ad68930588fd8088439cf4ef3fb55 U drh -Z 439b5225de67a70c541dcd306ac1747e +Z 28d57a56afcfa879aa70c91fd7351c46 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0bb3bb984..c9309a9f8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -036c97e36cb36a2ac765a8e8539433dcb63f69155d4c24857f84faa44eed6eb5 +ba8184d132a935aa1980fbfb61ff308b93d433d559db4968f9014f7653ac9c6e diff --git a/src/alter.c b/src/alter.c index f3108cbf9..a7255e75e 100644 --- a/src/alter.c +++ b/src/alter.c @@ -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]; diff --git a/src/loadext.c b/src/loadext.c index 7e0ae2543..40d4f3128 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -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 diff --git a/src/os_win.c b/src/os_win.c index 0dd56af58..cd7e49190 100644 --- a/src/os_win.c +++ b/src/os_win.c @@ -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; diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index ae0949baf..cf775dfbd 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -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) @@ -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){ diff --git a/src/wherecode.c b/src/wherecode.c index 014f697d9..95b12b77a 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -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 ); diff --git a/tool/mkautoconfamal.sh b/tool/mkautoconfamal.sh index 35f8dbc8c..b750593c9 100644 --- a/tool/mkautoconfamal.sh +++ b/tool/mkautoconfamal.sh @@ -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 diff --git a/tool/src-verify.c b/tool/src-verify.c index 0c7ed6f4c..6dc9f7259 100644 --- a/tool/src-verify.c +++ b/tool/src-verify.c @@ -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. */ diff --git a/tool/warnings.sh b/tool/warnings.sh index 2b962d15e..b589780ea 100644 --- a/tool/warnings.sh +++ b/tool/warnings.sh @@ -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 \ |