diff options
author | stephan <stephan@noemail.net> | 2025-05-17 11:06:02 +0000 |
---|---|---|
committer | stephan <stephan@noemail.net> | 2025-05-17 11:06:02 +0000 |
commit | 953e450e8ec192e510332783270e16c045f24c43 (patch) | |
tree | 0166a9a4459fdf7b145d01f529d653154852c2b7 | |
parent | 972a0f5e8d3486b39f6fbb86de65883ffe9dfe06 (diff) | |
parent | c953cb6b3b779e6685de4da1b6a37e16bbbb2975 (diff) | |
download | sqlite-master.tar.gz sqlite-master.zip |
Latest teaish pieces, most significantly for tcl portability fixes. Move autoconf/teaish/autosetup/... to autosetup/teaish/. to simplify maintenance and deployment via the autoconf bundle.HEADmaster
FossilOrigin-Name: 381d3e82e831bedee56108fb585880d802c4d7d50b0804d909a33ff15a3be185
-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-- | manifest | 31 | ||||
-rw-r--r-- | manifest.uuid | 2 | ||||
-rw-r--r-- | tool/mkautoconfamal.sh | 6 |
11 files changed, 563 insertions, 292 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>>" } @@ -1,5 +1,5 @@ -C Improved\sversion\sof\sthe\sprevious\scheck-in. -D 2025-05-16T18:19:11.764 +C Latest\steaish\spieces,\smost\ssignificantly\sfor\stcl\sportability\sfixes.\sMove\sautoconf/teaish/autosetup/...\sto\sautosetup/teaish/.\sto\ssimplify\smaintenance\sand\sdeployment\svia\sthe\sautoconf\sbundle. +D 2025-05-17T11:06:02.899 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 @@ -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 @@ -2207,8 +2207,9 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 955a026996b93e530ca5b566689cc646b31d3b9b5a5837897a58452d70f6d942 -R 804d8a6678db1d3197b731d5b4dee948 -U drh -Z 439b5225de67a70c541dcd306ac1747e +P 036c97e36cb36a2ac765a8e8539433dcb63f69155d4c24857f84faa44eed6eb5 43259e8c3fab13b4597cdd1c670df00ec756a6fefdeb7d4ba2e0644e4ad47113 +R 39ca8780111060790d2845d7852fde6d +T +closed 43259e8c3fab13b4597cdd1c670df00ec756a6fefdeb7d4ba2e0644e4ad47113 Closed\sby\sintegrate-merge. +U stephan +Z b3892a2462d40bd10e662612ff769df0 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 0bb3bb984..6c9528e1c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -036c97e36cb36a2ac765a8e8539433dcb63f69155d4c24857f84faa44eed6eb5 +381d3e82e831bedee56108fb585880d802c4d7d50b0804d909a33ff15a3be185 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 |