]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Latest upstream teaish pieces for minor fixes. Restructure this copy of teaish to...
authorstephan <stephan@noemail.net>
Sat, 17 May 2025 07:02:06 +0000 (07:02 +0000)
committerstephan <stephan@noemail.net>
Sat, 17 May 2025 07:02:06 +0000 (07:02 +0000)
FossilOrigin-Name: 2b8d9b75ec5fe96cb5d06a3464fd4eb9a53018b7b548fedcd6cdbc46cdb55bdc

autoconf/tea/Makefile.in
autoconf/tea/_teaish.tester.tcl.in [moved from autoconf/tea/teaish.tester.tcl.in with 87% similarity]
autoconf/tea/teaish.tcl
autosetup/proj.tcl
autosetup/teaish/README.txt [moved from autoconf/tea/autosetup/README.txt with 100% similarity]
autosetup/teaish/core.tcl [moved from autoconf/tea/autosetup/core.tcl with 84% similarity]
autosetup/teaish/feature-tests.tcl [moved from autoconf/tea/autosetup/feature-tests.tcl with 100% similarity]
autosetup/teaish/tester.tcl [moved from autoconf/tea/autosetup/tester.tcl with 70% similarity]
manifest
manifest.uuid
tool/mkautoconfamal.sh

index ad71c8b3e22bec9c582716ad17c91825fafd5dda..5b2ad4c69992b8c50e807a19ebd76ceebea68817 100644 (file)
@@ -1,5 +1,9 @@
 all:
 #
+# Unless this file is named Makefile.in, you are probably looking
+# at an automatically generated/filtered copy and should probably not
+# edit it.
+#
 # This makefile is part of the teaish framework, a tool for building
 # Tcl extensions, conceptually related to TEA/tclconfig but using the
 # Autosetup configuration system instead of the GNU Autotools.
@@ -47,6 +51,12 @@ tx.dll8          = @TEAISH_DLL8@
 tx.dll9          = @TEAISH_DLL9@
 tx.dll           = $(tx.dll$(TCL_MAJOR_VERSION))
 tx.dir           = @TEAISH_EXT_DIR@
+@if TEAISH_TM_TCL
+# Input filename for tcl::tm-style module
+tx.tm             = @TEAISH_TM_TCL@
+# Target filename for tcl::tm-style installation
+tx.tm.tgt        = $(tx.name.pkg)-$(tx.version).tm
+@endif
 
 @if TEAISH_DIST_NAME
 tx.name.dist     = @TEAISH_DIST_NAME@
@@ -157,23 +167,12 @@ tx.LDFLAGS =
 #
 tx.dist.files = @TEAISH_DIST_FILES@
 
-#
-# May get amended with generated file names. They are cleaned up by
-# the 'clean' rules. Client code which wants to clean up extra stuff
-# should do so by adding their cleanup target (e.g. clean-extension)
-# as a dependency to the 'clean' target, like so:
-#
-# clean: distclean-extension
-# distclean: distclean-extension
-#
-teaish__cleanExtra =
-
 # List of deps which may trigger an auto-reconfigure.
 #
 teaish__autogen.deps = \
   $(tx.makefile.in) $(teaish.makefile.in) \
   $(tx.tcl) \
-  @TEAISH_PKGINDEX_TCL_IN@ \
+  @TEAISH_PKGINDEX_TCL_IN@ @TEAISH_TM_TCL_IN@ \
   @AUTODEPS@
 
 @if TEAISH_MAKEFILE_IN
@@ -271,10 +270,10 @@ test: test-post
 # Cleanup rules...
 #
 #.PHONY: clean-pre clean-core clean-post clean-extension
-clean-extension: # this name is reserved for use by teaish.make
+#
 clean-pre:
 clean-core: clean-pre
-       rm -f $(tx.dll8) $(tx.dll9) tclsh $(teaish__cleanExtra)
+       rm -f $(tx.dll8) $(tx.dll9) tclsh
 clean-post: clean-core
 clean: clean-post
 
@@ -300,26 +299,59 @@ distclean-core: distclean-pre
 @if TEAISH_TEST_TCL_IN
        rm -f @TEAISH_TEST_TCL@
 @endif
-distclean-extension: # this name is reserved for use by teaish.make
 distclean-post: distclean-core
 distclean: distclean-post
+#
+# The (dist)clean-extension targets are reserved for use by
+# client-side teaish.make.
+#
+# Client code which wants to clean up extra stuff should do so by
+# adding their cleanup target (e.g. clean-extension) as a dependency
+# to the 'clean' target, like so:
+#
+# clean: distclean-extension
+# distclean: distclean-extension
+#
+distclean-extension:
+clean-extension:
 
 #
 # Installation rules...
 #
+@if TEAISH_ENABLE_INSTALL
 .PHONY: install-pre install-core install-post install-test install-prepre install-extension
 install-extension: # this name is reserved for use by teaish.make
+
+@if TEAISH_ENABLE_DLL
 install-prepre: $(tx.dll)
+@else
+install-prepre:
+@endif
+
+@if TEAISH_TM_TCL
+install-core.tmdir = $(DESTDIR)@TEAISH_TCL_TM_DIR@
+@endif
+
 install-pre: install-prepre
 install-core: install-pre
        @if [ ! -d "$(DESTDIR)$(TCLLIBDIR)" ]; then \
                set -x; $(INSTALL) -d "$(DESTDIR)$(TCLLIBDIR)"; \
        fi
 # ^^^^ on some platforms, install -d fails if the target already exists.
+@if TEAISH_ENABLE_DLL
        $(INSTALL) $(tx.dll) "$(DESTDIR)$(TCLLIBDIR)"
-       $(INSTALL.noexec) pkgIndex.tcl "$(DESTDIR)$(TCLLIBDIR)"
+@endif
+@if TEAISH_PKGINDEX_TCL
+       $(INSTALL.noexec) "@TEAISH_PKGINDEX_TCL@" "$(DESTDIR)$(TCLLIBDIR)"
+@endif
 @if TEAISH_PKGINIT_TCL
-       $(INSTALL.noexec) @TEAISH_PKGINIT_TCL@ "$(DESTDIR)$(TCLLIBDIR)"
+       $(INSTALL.noexec) "@TEAISH_PKGINIT_TCL@" "$(DESTDIR)$(TCLLIBDIR)"
+@endif
+@if TEAISH_TM_TCL
+       @if [ ! -d "$(install-core.tmdir)" ]; then \
+               set -x; $(INSTALL) -d "$(install-core.tmdir)"; \
+       fi
+       $(INSTALL.noexec) "@TEAISH_TM_TCL@" "$(install-core.tmdir)/$(tx.tm.tgt)"
 @endif
 install-test: install-core
        @echo "Post-install test of [package require $(tx.name.pkg) $(tx.version)]..."; \
@@ -344,10 +376,17 @@ install: install-post
 uninstall-extension: # this name is reserved for use by teaish.make
 uninstall-pre:
 uninstall-core: uninstall-pre
+@if TEAISH_ENABLE_DLL
        rm -fr "$(DESTDIR)$(TCLLIBDIR)"
+@endif
+@if TEAISH_TM_TCL
+       rm -f "$(DESTDIR)$(install-core.tmdir)/$(tx.tm.tgt)"
+@endif
+
 uninstall-post: uninstall-core
        @echo "Uninstalled Tcl extension $(tx.name) $(tx.version)"
 uninstall: uninstall-post
+@endif # TEAISH_ENABLE_INSTALL
 
 @if TEAISH_MAKEFILE_IN
 Makefile:  $(tx.makefile.in)
similarity index 87%
rename from autoconf/tea/teaish.tester.tcl.in
rename to autoconf/tea/_teaish.tester.tcl.in
index 4e203cd78507e6011814fb392c65bff8de54f857..59d11f0a8f6ef751811a6043b790ec0973fa77d4 100644 (file)
@@ -1,6 +1,6 @@
 # -*- tcl -*-
 #
-# Unless this file is named teaish.tester.tcl.in, you are probably
+# Unless this file is named _teaish.tester.tcl.in, you are probably
 # looking at an automatically generated/filtered copy and should
 # probably not edit it.
 #
@@ -28,6 +28,12 @@ apply {{file} {
   source -encoding utf-8 $file
 }} [join {@TEAISH_PKGINIT_TCL@}]
 @endif
+@if TEAISH_TM_TCL
+apply {{file} {
+  set dir [file dirname $::argv0]
+  source -encoding utf-8 $file
+}} [join {@TEAISH_TM_TCL@}]
+@endif
 @if TEAISH_TEST_TCL
 apply {{file} {
   # Populate state for [tester.tcl::teaish-build-flag*]
index 87d059c32826d1419b3b446fee17a83c8f2b46fe..9333495aa3dacfee471be4073995c1cd589d1759 100644 (file)
@@ -117,7 +117,7 @@ proc teaish-options {} {
 # work needed for this extension.
 #
 proc teaish-configure {} {
-  use teaish/feature-tests
+  use teaish/feature
 
   teaish-src-add -dist -dir generic/tclsqlite3.c
 
index 4691cfe36f9ae79f76acafc7fce770289934fefa..a4957ed61d0f2cfa90cec82c15dffe58d7cfde55 100644 (file)
@@ -60,8 +60,8 @@
 # $proj__Config is an internal-use-only array for storing whatever generic
 # internal stuff we need stored.
 #
-array set proj__Config {
-  self-tests 0
+array set ::proj__Config {
+  self-tests 1
 }
 
 
@@ -74,8 +74,8 @@ array set proj__Config {
 #
 # See: proj-dot-ins-append and proj-dot-ins-process
 #
-set proj__Config(dot-in-files) [list]
-set proj__Config(isatty) [isatty? stdout]
+set ::proj__Config(dot-in-files) [list]
+set ::proj__Config(isatty) [isatty? stdout]
 
 #
 # @proj-warn msg
@@ -88,6 +88,25 @@ proc proj-warn {args} {
   puts stderr [join [list "WARNING: \[[proj-scope 1]\]: " {*}$args] " "]
 }
 
+
+# Internal impl of [proj-fatal] and [proj-error]. It must be called
+# using tailcall.
+proc proj__faterr {failMode argv} {
+  show-notices
+  set lvl 1
+  while {"-up" eq [lindex $argv 0]} {
+    set argv [lassign $argv -]
+    incr lvl
+  }
+  if {$failMode} {
+    puts stderr [join [list "FATAL: \[[proj-scope $lvl]]: " {*}$argv]]
+    exit 1
+  } else {
+    error [join [list "\[[proj-scope $lvl]]:" {*}$argv]]
+  }
+}
+
+
 #
 # @proj-fatal ?-up...? msg...
 #
@@ -99,31 +118,19 @@ proc proj-warn {args} {
 # additional level.
 #
 proc proj-fatal {args} {
-  show-notices
-  set lvl 1
-  while {"-up" eq [lindex $args 0]} {
-    set args [lassign $args -]
-    incr lvl
-  }
-  puts stderr [join [list "FATAL: \[[proj-scope $lvl]]: " {*}$args]]
-  exit 1
+  tailcall proj__faterr 1 $args
 }
 
 #
 # @proj-error ?-up...? msg...
 #
-# Works like prop-fatal but uses [error] intead of [exit].
+# Works like proj-fatal but uses [error] intead of [exit].
 #
 proc proj-error {args} {
-  show-notices
-  set lvl 1
-  while {"-up" eq [lindex $args 0]} {
-    set args [lassign $args -]
-    incr lvl
-  }
-  error [join [list "\[[proj-scope $lvl]]:" {*}$args]]
+  tailcall proj__faterr 0 $args
 }
 
+set ::proj__Config(verbose-assert) [get-env proj-assert-verbose 0]
 #
 # @proj-assert script ?message?
 #
@@ -133,7 +140,7 @@ proc proj-error {args} {
 # used instead.
 #
 proc proj-assert {script {msg ""}} {
-  if {1 == [get-env proj-assert 0]} {
+  if {1 eq $::proj__Config(verbose-assert)} {
     msg-result [proj-bold "asserting: $script"]
   }
   if {![uplevel 1 [list expr $script]]} {
@@ -162,7 +169,9 @@ proc proj-bold {args} {
 # @proj-indented-notice ?-error? ?-notice? msg
 #
 # Takes a multi-line message and emits it with consistent indentation.
-# It does not perform any line-wrapping of its own.
+# It does not perform any line-wrapping of its own. Which output
+# routine it uses depends on its flags, defaulting to msg-result.
+# For -error and -notice it uses user-notice.
 #
 # If the -notice flag it used then it emits using [user-notice], which
 # means its rendering will (A) go to stderr and (B) be delayed until
@@ -176,7 +185,7 @@ proc proj-bold {args} {
 #
 proc proj-indented-notice {args} {
   set fErr ""
-  set outFunc "puts"
+  set outFunc "msg-result"
   while {[llength $args] > 1} {
     switch -exact -- [lindex $args 0] {
       -error  {
@@ -632,7 +641,7 @@ proc proj-no-check-module-loader {} {
 }
 
 #
-# @proj-file-conent ?-trim? filename
+# @proj-file-content ?-trim? filename
 #
 # Opens the given file, reads all of its content, and returns it.  If
 # the first arg is -trim, the contents of the file named by the second
@@ -701,10 +710,10 @@ proc proj-file-write {args} {
 # argument it is assumed to be the name of an autosetup boolean config
 # which controls whether to run/skip this check.
 #
-# Returns 1 if supported, else 0. Defines MAKE_COMPILATION_DB to "yes"
-# if supported, "no" if not. The use of MAKE_COMPILATION_DB is
-# deprecated/discouraged. It also sets HAVE_COMPILE_COMMANDS to 0 or
-# 1, and that's the preferred usage.
+# Returns 1 if supported, else 0, and defines HAVE_COMPILE_COMMANDS to
+# that value. Defines MAKE_COMPILATION_DB to "yes" if supported, "no"
+# if not. The use of MAKE_COMPILATION_DB is deprecated/discouraged:
+# HAVE_COMPILE_COMMANDS is preferred.
 #
 # ACHTUNG: this test has a long history of false positive results
 # because of compilers reacting differently to the -MJ flag.
@@ -713,6 +722,7 @@ proc proj-check-compile-commands {{configFlag {}}} {
   msg-checking "compile_commands.json support... "
   if {"" ne $configFlag && ![proj-opt-truthy $configFlag]} {
     msg-result "explicitly disabled"
+    define HAVE_COMPILE_COMMANDS 0
     define MAKE_COMPILATION_DB no
     return 0
   } else {
@@ -787,7 +797,12 @@ proc proj-make-from-dot-in {args} {
     catch { exec chmod u+w $fOut }
   }
   #puts "making template: $fIn ==> $fOut"
-  make-template $fIn $fOut
+  #define-push {top_srcdir} {
+    #puts "--- $fIn $fOut top_srcdir=[get-define top_srcdir]"
+    make-template $fIn $fOut
+    #puts "--- $fIn $fOut top_srcdir=[get-define top_srcdir]"
+    # make-template modifies top_srcdir
+  #}
   if {$touch} {
     proj-touch $fOut
   }
@@ -1220,7 +1235,7 @@ proc proj-quote-str_ {value} {
 # the formatted value or the value $::proj__Config(defs-skip) if the caller
 # should skip emitting that value.
 #
-set proj__Config(defs-skip) "-proj-defs-format_ sentinel"
+set ::proj__Config(defs-skip) "-proj-defs-format_ sentinel"
 proc proj-defs-format_ {type value} {
   switch -exact -- $type {
     -bare {
@@ -1258,6 +1273,8 @@ proc proj-defs-format_ {type value} {
   return $value
 }
 
+#
+# @proj-dump-defs-json outfile ...flags
 #
 # This function works almost identically to autosetup's
 # make-config-header but emits its output in JSON form. It is not a
@@ -1965,12 +1982,10 @@ 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}
+  #if {"-" eq $arg} {set arg 0}
   if {[string is integer -strict $arg]} {
     return [proj-scope [expr {$arg + $addLevel + 1}]]
   }
@@ -2046,8 +2061,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 +2110,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,7 +2201,7 @@ proc proj-parse-simple-flags {argvName tgtArrayName prototype} {
 
 if {$::proj__Config(self-tests)} {
   apply {{} {
-    proj-warn "Test code for proj-cache"
+    #proj-warn "Test code for proj-cache"
     proj-assert {![proj-cache-check here check]}
     proj-assert {"here" eq [proj-cache-key here]}
     proj-assert {"" eq $check}
similarity index 84%
rename from autoconf/tea/autosetup/core.tcl
rename to autosetup/teaish/core.tcl
index 4b3eb9a824fb4095fb254fa37f2dc3bcb96e2502..5476206ed2e68bad2ebc9053e1bb24aabf872a80 100644 (file)
@@ -36,11 +36,13 @@ array set teaish__Config [proj-strip-hash-comments {
   debug-enabled 0
 
   #
-  # 0    = don't yet have extension's pkgindex
-  # 0x01 = found TEAISH_EXT_DIR/pkgIndex.tcl.in
-  # 0x02 = found srcdir/pkgIndex.tcl.in
-  # 0x10 = found TEAISH_EXT_DIR/pkgIndex.tcl (static file)
-  # 0x20 = static-pkgIndex.tcl pragma: behave as if 0x10
+  # 0     = don't yet have extension's pkgindex
+  # 0x01  = found TEAISH_EXT_DIR/pkgIndex.tcl.in
+  # 0x02  = found srcdir/pkgIndex.tcl.in
+  # 0x10  = found TEAISH_EXT_DIR/pkgIndex.tcl (static file)
+  # 0x20  = static-pkgIndex.tcl pragma: behave as if 0x10
+  # 0x100 = disabled by -tm.tcl.in
+  # 0x200 = disabled by -tm.tcl
   #
   # Reminder: it's significant that the bottom 4 bits be
   # cases where teaish manages ./pkgIndex.tcl.
@@ -60,6 +62,11 @@ array set teaish__Config [proj-strip-hash-comments {
   # the (generated) pkginit file.
   #
   pkginit-policy 0
+  #
+  # 0    = no tm.tcl
+  # 0x01 = tm.tcl.in
+  # 0x10 = static tm.tcl
+  tm-policy 0
 
   #
   # If 1+ then teaish__verbose will emit messages.
@@ -68,7 +75,7 @@ array set teaish__Config [proj-strip-hash-comments {
 
   #
   # Mapping of pkginfo -flags to their TEAISH_xxx define (if any).
-  # This must not be modified.
+  # This must not be modified after initialization.
   #
   pkginfo-f2d {
     -name            TEAISH_NAME
@@ -81,6 +88,8 @@ array set teaish__Config [proj-strip-hash-comments {
     -pkgInit.tcl     TEAISH_PKGINIT_TCL
     -pkgInit.tcl.in  TEAISH_PKGINIT_TCL_IN
     -url             TEAISH_URL
+    -tm.tcl          TEAISH_TM_TCL
+    -tm.tcl.in       TEAISH_TM_TCL_IN
     -options         {}
     -pragmas         {}
   }
@@ -95,6 +104,10 @@ array set teaish__Config [proj-strip-hash-comments {
   # when building from an extension's dir, disabled when building
   # elsewhere.
   dist-enabled 1
+  # Whether or not "make install" parts are enabled. By default
+  # they are, but we have a single use case where they're
+  # both unnecessary and unhelpful, so...
+  install-enabled 1
 
   # By default we enable compilation of a native extension but if the
   # extension has no native code or the user wants to take that over
@@ -272,40 +285,52 @@ proc teaish-configure-core {} {
   }]; # main options.
 
   if {$gotExt} {
+    # We found an extension. Source it...
+    set ttcl $::teaish__Config(teaish.tcl)
     proj-assert {"" ne [teaish-pkginfo-get -name]}
-    proj-assert {[file exists $::teaish__Config(teaish.tcl)]} \
-      "Expecting to have found teaish.tcl by now"
-    uplevel 1 {source $::teaish__Config(teaish.tcl)}
+    proj-assert {[file exists $ttcl]} \
+      "Expecting to have found teaish.(tcl|config) by now"
+    if {[string match *.tcl $ttcl]} {
+      uplevel 1 {source $::teaish__Config(teaish.tcl)}
+    } else {
+      teaish-pkginfo-set {*}[proj-file-content -trim $ttcl]
+    }
+    unset ttcl
     # Set up some default values if the extension did not set them.
     # This must happen _after_ it's sourced but before
     # teaish-configure is called.
     array set f2d $::teaish__Config(pkginfo-f2d)
     foreach {pflag key type val} {
-      - TEAISH_CFLAGS           -v ""
-      - TEAISH_LDFLAGS          -v ""
-      - TEAISH_MAKEFILE         -v ""
-      - TEAISH_MAKEFILE_CODE    -v ""
-      - TEAISH_MAKEFILE_IN      -v ""
-      - TEAISH_PKGINDEX_TCL     -v ""
-      - TEAISH_PKGINDEX_TCL_IN  -v ""
-      - TEAISH_TEST_TCL         -v ""
-      - TEAISH_TEST_TCL_IN      -v ""
-
-      -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
@@ -1486,50 +1539,101 @@ proc teaish-feature-cache-check {{key 0} tgtVar} {
 }
 
 #
-# @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 +1655,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 +1680,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 +1693,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 +1724,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 +1752,35 @@ proc teaish__defs_format {type value} {
 #
 # Returns Tcl code in the form of code which evaluates to a list of
 # configure-time DEFINEs in the form {key val key2 val...}. It may
-# misbehave for values which are not numeric or simple strings.
+# misbehave for values which are not numeric or simple strings.  Some
+# defines are specifically filtered out of the result, either because
+# their irrelevant to teaish or because they may be arbitrarily large
+# (e.g. makefile content).
 #
-proc teaish__dump_defs_to_list {args} {
+# The $args are explained in the docs for internal-use-only
+# [teaish__defs_format]. The default mode is -autolist.
+#
+proc teaish__defines_to_list {args} {
   set lines {}
   lappend lines "\{"
   set skipper $::teaish__Config(defs-skip)
-  lappend args \
-    -none {
-      TEAISH__*
-      TEAISH_MAKEFILE_CODE
-      AM_* AS_*
-    } \
-    -auto {
-      SIZEOF_* HAVE_*
-    } \
-    -autolist *
-  foreach n [lsort [dict keys [all-defines]]] {
-    set type [teaish__defs_type $n $args]
-    set value [teaish__defs_format $type [get-define $n]]
+  set args [list \
+              -none {
+                TEAISH__*
+                TEAISH_*_CODE
+                AM_* AS_*
+              } \
+              {*}$args \
+              -autolist *]
+  foreach d [lsort [dict keys [all-defines]]] {
+    set type [teaish__defs_type $d $args]
+    set value [teaish__defs_format $type [get-define $d]]
     if {$skipper ne $value} {
-      lappend lines "$n $value"
+      lappend lines "$d $value"
     }
   }
   lappend lines "\}"
-  return [join $lines "\n"]
+  tailcall join $lines "\n"
 }
 
 #
@@ -1697,7 +1809,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 +1825,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 +1842,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 +1932,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 +2026,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 +2043,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 +2421,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 +2441,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 +2522,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
similarity index 70%
rename from autoconf/tea/autosetup/tester.tcl
rename to autosetup/teaish/tester.tcl
index 5c546e841d7cd240bf417d31847e95f2eeee2ab1..d8b5f7a0e8c29ff50335dd858c53e34f86748223 100644 (file)
 #
 ########################################################################
 #
-# 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>>"
 }
 
index c61a38545bc61705fb44df86cd9a559c116bec52..299b1419440b7d9aa7410432f9e5c2df28b245de 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Improved\sversion\sof\sthe\sprevious\scheck-in.
-D 2025-05-16T18:19:11.764
+C Latest\supstream\steaish\spieces\sfor\sminor\sfixes.\sRestructure\sthis\scopy\sof\steaish\sto\ssimplify\smaintenance\sand\sthe\sautoconf\sbundle\sbuild.
+D 2025-05-17T07:02:06.426
 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 2d3431d7b379a741d2b6727e34b6885e546066c1956e43757adbaf49db82945b
 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 a96140a11141dc165e0e84f38e0bd0031611553303a40ab9df7f28646611292a w autoconf/tea/autosetup/core.tcl
+F autosetup/teaish/feature-tests.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,11 @@ 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
+R 84f69ea0a581f0671fbf90c83e33cd68
+T *branch * tea-cleanups
+T *sym-tea-cleanups *
+T -sym-trunk * Cancelled\sby\sbranch.
+U stephan
+Z ec5e72cf16174ce398433604a2e0a2ca
 # Remove this line to create a well-formed Fossil manifest.
index 0bb3bb9849bab1371ace10b4aa85badbf0962532..77c3c6156610a3a3890a402438f3155efe563a13 100644 (file)
@@ -1 +1 @@
-036c97e36cb36a2ac765a8e8539433dcb63f69155d4c24857f84faa44eed6eb5
+2b8d9b75ec5fe96cb5d06a3464fd4eb9a53018b7b548fedcd6cdbc46cdb55bdc
index 35f8dbc8c67771a8411ce67df987fd5f75c771a8..b750593c984c6b62b2763609dda7060d3536a36e 100644 (file)
@@ -63,7 +63,7 @@ cp $TOP/main.mk           $TMPSPACE
 cd $TMPSPACE
 
 # Clean up emacs-generated backup files from the target
-rm -f ./autosetup/*~
+rm -f ./autosetup/*~ ./autosetup/teaish/*~
 rm -f ./*~
 
 #if true; then
@@ -73,10 +73,6 @@ rm -f ./*~
 #  find . -name '*~' -exec rm \{} \;
 #fi
 
-mkdir -p autosetup/teaish
-mv tea/autosetup/*.tcl autosetup/teaish/.
-rm -fr tea/autosetup
-
 mkdir -p tea/generic
 cat <<EOF > tea/generic/tclsqlite3.c
 #ifdef USE_SYSTEM_SQLITE