]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improve and add docs for extensible shell.
authorlarrybr <larrybr@noemail.net>
Tue, 13 Jun 2023 23:04:34 +0000 (23:04 +0000)
committerlarrybr <larrybr@noemail.net>
Tue, 13 Jun 2023 23:04:34 +0000 (23:04 +0000)
FossilOrigin-Name: 1a57af86da17a3da6bb343001c779d4d9d2ff2c1937ded4d6370d6a951c3cda4

doc/extensible_shell.md [new file with mode: 0644]
doc/shell_extend.html
doc/tcl_extension_intro.md
manifest
manifest.uuid
src/test_shellext_c.c
src/test_shellext_cpp.cpp

diff --git a/doc/extensible_shell.md b/doc/extensible_shell.md
new file mode 100644 (file)
index 0000000..2547d12
--- /dev/null
@@ -0,0 +1,61 @@
+# Introduction to the SQLite Extensible Shell #
+
+This article introduces a set of enhancements to the SQLite "CLI" shell
+which make it extensible as a shell and provide other useful features.
+
+What "extensible" means as of June 2023 is that additional dot-commands
+can be implemented by a dynamically loaded extension and integrated
+into the shell's command repertoire and help for same. It also means
+that scripting support can be provided by an extension and integrated
+into the shell's input collection and dispatching facility.
+
+In the future, "extensible" will also mean that additional forms of query
+result output formatting (or other disposition), and additional methods
+of data collection into tables (or other disposition), can be provided
+by an extension and utilized via the shell's .mode and .import commands.
+(This integration with .mode and .import commands is in-work.)
+
+Scripting support for the shell is presently implemented by a
+[Tcl Shell Extension](https://sqlite.org/src/file?name=doc/tcl_extension_intro.md&ci=cli_extension).
+
+Some new features are available via these new or altered dot-commands:
+
+**.eval** will interpret its arguments as shell input. This is mainly useful
+from within a script to run fixed or formulated shell commands.
+
+**.parameter** has several enhancements: The new "edit" subcommand can be
+used to create or modify SQL binding parameters, either by name or from
+being referenced in the most recently run SQL. The new "save" and "load"
+subcommands will store or retrieve all or named parameters into/from a file.
+
+**.shxload** is used to load shell extensions at runtime.
+
+**.shxopts** either shows or alters extended shell features. Presently,
+this allows shell input parsing to be enhanced as described below or to be
+reverted to the traditional rule where dot-commands always occupy one line.
+
+**.tables** has new options to show only tables, views, or system tables.
+
+**.vars** is used to create or modify "shell" variables. These are
+key/value pairs which are associated with the shell session rather than
+a specific database such as .databases would list. These variables may
+be the subject of "edit", "set", "save" and "load" subcommands.
+
+**.x** is a general purpose, "run these" command. By default, its arguments
+are treated as shell variable names, values of which are interpreted as
+shell input. Optionally, its arguments are interpreted similarly to the
+.eval and .read subcommand. They differ in that interpretation of the
+arguments stops upon any error.
+
+Other new shell features are:
+
+By default, when invoked as "sqlite3x", or after ".shxopts +parsing" is run,
+the shell effects enhanced command parsing whereby quoted dot-command arguments
+may span multiple lines or dot-command input lines may be spliced together
+with trailing backslash.
+
+When not invoked as "sqlite3x", or after ".shxopts -parsing" is run, any
+dot-command arguments and the dot-command itself end at the first newline.
+This might be needed to run legacy shell scripts having some dot-command(s)
+with a final argument that has an initial quote but no closing quote or
+which happen to end with backslash.
index 0bf41aacc1c11cd5907147b557457bbb964a7ef0..27325af2991510cc6e2e2d42824600aba38090ac 100644 (file)
       <h2>Extensible Features</h2>
     <p>Only certain categories of features may be
       added or modified via extension, namely:
-      
+
       <h3>New or Revised Meta-Commands</h3>
     <p>The "dot" commands implemented by the shell,
       along with help text for them, may be augmented or overridden.
       A meta-command effected with an extension may be used
       in the same ways as one available in the core, non-extended shell.
-      
-      <h3>New or Revised Import Modes</h3>
+
+      <h3>New or Revised Import Modes (work-in-progress)</h3>
     <p>The ways in which data may be imported to a DB table
       may be augmented or overriden. Once that is done, the .import
       meta-command will either have a new option to specify a new import
       handler or an existing .import option can be overridden for this.
 
-      <h3>New or Revised Query Result Handling</h3>
+      <h3>New or Revised Query Result Handling (work-in-progress)</h3>
     <p>The display formatting or other disposition of query results
       may be augmented or overriden. Once that is done, the .mode
       meta-command will either have a new option to specify a new result
       the data is up to the handler, as may be affected
       by arguments to the .import or most recent .mode command.
 
+      <h3>Scriptability</h3>
+    <p>An shell extension may provide for integration of a scripting
+      subsystem with the shell. Such a subsystem may participate in
+      classification of input, extending the recognized classes from
+      { meta-command SQL-statement(s) comment } to add { script }, and
+      then handle input in the "script" input class. The shell exposes
+      some its internal data and code to script implementations so that
+      they may act in a manner providing adaptation or enhancement of
+      shell features rather than entirely independent new features.
+
       <h2>Extension Methods, Dynamic or Static</h2>
     <p>Shell extension may be effected at different times
       in different ways according to convenience and need.
 
       <h3>Runtime Extension</h3>
     <p>Extension at runtime (when the shell is running)
-      is effected via the .load command with a --shell flag.
+      is effected via the .shxload command.
       In this way, a dynamically loaded library (DLL) is loaded with
       provision made for its sqlite3_X_init() function to obtain
       the shell extension API entry points and thereby
       register with the shell core any
       new meta-commands, or import or query result handlers
-      that it implements.
+      or scripting support that it implements.
 
       <h3>Build-Time Extension</h3>
     <p>Extension when the shell is built is effected by specifying
       the same source code can be used either
       to produce most of a runtime shell extension DLL or to
       be incorporated into shell.c as a built-in shell extension.
-      (See the extension code samples for details.)
+      (See the extension code samples for details. (Not fully implemented.))
 
       <h3>Build-Time Diminuation</h3>
     <p>Just as new meta-commands can be readily incorporated into
       and shell extensions written in C/C++.
       Comments in that header tersely summarize these explanations:
 
-      <h3>struct ShellStateX and ShellExState</h3>
-    <p>The ShellStateX object, (maintained by the shell and known as
-      shellState), consists of a public portion, which is available and
-      stable for use in shell/extension interactions, and a private
-      portion which may not be stable. Shell extension code used only for
-      build-time extension might use the private part, (to which it has
-      access because such code is compiled within the same translation unit
-      as the core shell code), but such usage generally precludes (or makes
-      hazardous) use of runtime loadable extensions built from such code.
+      <h3>struct ShellInState and ShellExState</h3>
+    <p>The Shell{In,Ex}State objects, are maintained by the shell and known
+      as shell state. The shell state consists of a public portion, which
+      is available and stable for use in shell/extension interactions,
+      and a private portion which may not be stable. Shell extension code
+      used only for build-time extension might use the private part,
+      (to which it has access because such code is compiled within the same
+      translation unit as the core shell code),
+      but such usage generally precludes (or makes hazardous)
+      use of runtime loadable extensions built from such code.
 
       <h3>ExtensionId typedef and eid Member</h3>
     <p>An object of this type serves to uniquely identify an extension
 
       <h3>extensionDestruct member</h3>
     <p>The function addressed by this member will be called prior to
-      the extension being unloaded (if the pointer is non-zero.)
+      exit or the extension being unloaded (if the pointer is non-zero.)
       This is an out parameter from the sqlite3_X_init() function.
       It may perform any cleanup or deallocations necessitated by
       successful initialization generally (and will never be called
       <h3>Notes Regarding Object Interfaces for C vs C++ Writers</h3>
     <p>The objects registered with the shell core to provided extension
       functionality may be implemented in C or C++ (or anything else
-      producing the same ABI.) In the below descriptions of their
+      presenting the same ABI.) In the below descriptions of their
       interfaces, it should be understood that: C++ implementations
       need not explicitly deal with anything like a Whatsit_Vtable
       struct and will refer to the object pointer, passed implicitly,
       so destruct()'s responsibility should be limited to reversing
       the per-registered-object effects of sqlite3_X_init().
     <p>A registered object is deactivated when either: the extension
-      is immanently going to be unloaded; or the registered object is
+      is immanently going to be unloaded; the registered object is
       being overridden by some like-named object (such that it can no
-      longer be reached by the core shell.)
+      longer be reached by the core shell); or the shell is about to
+      return or exit.
 
-      <h3>MetaCommand typedef</h3>
+      <h3>DotCommand typedef</h3>
     <p>These objects represent an extension meta-command, including a
       dispatch table for the public interface and any accompanying
       data (which is opaque to the core shell.) Such objects are created
       by extensions and passed to the core shell only by reference.
-      They are made known to the shell core via registerMetaCommand() calls.
+      They are made known to the shell core via registerDotCommand() calls.
 
-      <h3>MetaCommand_Vtable typedef</h3>
-    <p>These objects represent the dispatch table of a MetaCommand object.
+      <h3>DotCommand_Vtable typedef</h3>
+    <p>These objects represent the dispatch table of a DotCommand object.
     <p>All methods are given the same leading (or lone) argument:<br>
-      (1) the address of the registered MetaCommand object.
+      (1) the address of the registered DotCommand object.
 
       <h4>destruct method</h4>
     <p>This method is called prior to unloading a runtime extension
-      for any registered MetaCommand object, provided its dispatch
+      for any registered DotCommand object, provided its dispatch
       table entry is non-zero.
       It should free resources allocated during the sqlite3_X_init() call
       associated with creation or preparation of the object.
       <h4>name method</h4>
     <p>This method returns the name of the meta-command (sans leading '.'.)
       The returned pointer must remain valid throughout the lifetime of
-      the registered MetaCommand object.
+      the registered DotCommand object.
 
       <h4>help method</h4>
     <p>This method returns help text for the meta-command. This text
       should be formatted and aligned with the built-in meta-command
       help text so that it can be displayed seamlessly.
     <p>There is one additional argument:<br>
-      (2) an integer directing what help text to return, with
+      (2) a const char * directing what help text to return, with
       0 indicating primary, single-line help, or
-      1 indicating any more detailed help beyond the primary level.
-    <p>The return is either a C string or null pointer. The C string
-      will not be freed by the core shell, and must remain valid
-      during the lifetime of the MetaCommand object.
-
-      <h4>argsRange method</h4>
-    <p>This method returns a pair of unsigned integers indicating the range
-      of valid argument counts for the meta-command.
-    <p>The returned .minArgs value indicates the minimum number of
-      arguments required for a successful execute call.
-      The returned .maxArgs value indicates the maximum number of
-      arguments allowed for a successful execute call, with ~0
-      indicating no (practical) upper limit. The execute method will
-      never be called with an argument count not within this range.
-      (This significantly simplifies argument checking.)
+      &"" indicating more detailed help beyond the primary level, or
+      &"(other)" reserved for expansion.
+    <p>The return for the first 2 forms is either a C string or
+      null pointer. The C string will not be freed by the core shell, and
+      must remain valid during the lifetime of the DotCommand object.
+
+      <h4>argsCheck method</h4>
+    <p>This method returns a DotCmdRC value indicating the validity
+      (or invalidity) of arguments for the meta-command, using the
+      coding scheme defined for the DotCmdRC type.
+    <p>There are three additional arguments:<br>
+      (2) a char** to possibly receive an error message, which the
+      caller must eventually pass to sqlite3_free().<br>
+      (3) a count of all provided arguments; and<br>
+      (4) a char* array of given arguments, led by meta-command's name.
 
       <h4>execute method</h4>
     <p>This method performs whatever work the meta-command is supposed
       to do when invoked. It has 4 additional arguments:<br>
-      (2) present ShellStateX, passed by reference (an in/out parameter);<br>
+      (2) present ShellExState, passed by reference (an in/out parameter);<br>
       (3) an error message pointer, passed by reference, set upon error but
       otherwise not modified, to be freed by the shell core;<br>
-      (4) the number of invocation arguments;<br>
+      (4) the number of invocation arguments; and<br>
       (5) an array of C strings constituting the invocation arguments;<br>
-    <p>The return is 0 for success, or anything else to indicate error.
-      The special value SHELL_INVALID_ARGS (aka SQLITE_MISUSE) should be
-      returned when argument checking shows an invalid call. This will
-      cause the command dispatcher to issue usage help (in interactive
-      shell sessions) without further fuss by the execute() method itself.
-      (And if an extension causes this error to be returned from the SQLite
-      library, which is a serious error by itself, it must either translate
-      it for return or trouble its users with a misleading error message
-      from the dispatcher.) If the output error message is set, it will
-      be issued in lieu of the standard error message for invalid calls.
-
-      <h3>OutModeHandler typedef</h3>
+    <p>The return is a DotCmdRC value, indicating success, error, or
+      other disposition as documented for the DotCmdRC type.
+
+      <h3>ExportHandler typedef</h3>
     <p>These objects represent an extension query result handler, including
       a dispatch table for the public interface and any accompanying
       data which is opaque to the core shell. Such objects are created
       by extensions and passed to the core shell only by reference.
-      They are made known to the shell core via registerOutMode() calls.
+      They are made known to the shell core via registerExporter() calls.
 
-      <h3>OutModeHandler_Vtable typedef</h3>
-    <p>These objects represent the dispatch table of an OutModeHandler object.
+      <h3>ExportHandler_Vtable typedef</h3>
+    <p>These objects represent the dispatch table of an ExportHandler object.
       All methods in the dispatch table are given at
       least this leading argument:<br>
-      (1) The OutModeHandler address registered via registerOutMode();<br>
+      (1) The ExportHandler address registered via registerExporter();<br>
 
       <h4>destruct method</h4>
-    <p>This method is called prior to unloading a runtime extension
-      for any registered OutModeHandler object, provided its dispatch
-      table entry is non-zero.
+    <p>This method is called prior to the shell's return or exit or
+      unloading the runtime extension for a registered ExportHandler object,
+      provided its dispatch table entry is non-zero.
       It should free resources allocated during the sqlite3_X_init() call
       associated with creation or preparation of the object.
 
       <h4>name method</h4>
-    <p>This method returns the name of the OutModeHandler, which users
+    <p>This method returns the name of the ExportHandler, which users
       specify to the .mode command (as the mode's name) to designate use
-      of the registered OutModeHandler for subsequent query results.
+      of the registered ExportHandler for subsequent query results.
       The returned pointer must remain valid throughout the lifetime of
-      the registered MetaCommand object.
+      the registered ExportHandler object.
 
       <h4>help method</h4>
-    <p>This method returns help text for the OutModeHandler.
+    <p>This method returns help text for the ExportHandler.
     <p>There is one additional argument:<br>
-      (2) an integer directing what help text to return, with
+      (2) a const char * directing what help text to return, with
       0 indicating primary, single-line help, or
-      1 indicating any more detailed help beyond the primary level.
-      The primary help is included in the .mode command's own
+      &"" indicating more detailed help beyond the primary level, or
+      &"(other)" reserved for expansion.
+    <p>The primary help is included in the .mode command's own
       detailed help text, so it should be aligned accordingly.
       The detailed help is shown by the .mode command's --help option.
     <p>The return is either a C string or null pointer. The C string
       will not be freed by the core shell, and must remain valid
-      during the lifetime of the MetaCommand object.
+      during the lifetime of the ExportHandler object.
 
       <h4>Common arguments</h4>
     <p>The following methods are given these 2 additional arguments:<br>
     <p>When the extension handler is activated via a .mode command,
       parsing that command and behaving accordingly is the responsibility
       of this method alone. (The command is parsed and acted upon by the
-      default .mode implementation only when no OutModeHandler is used.)
+      default .mode implementation only when no ExportHandler is used.)
     <p>Once this method is called and succeeds, it is guaranteed that the
       closeResultsOutStream method will be called.
     <p>This method should return SQLITE_OK only upon success.
     <p>This method should return SQLITE_OK only upon success
       without having completed stepping. If this method completes stepping,
       (by making its own calls to sqlite3_step() until it returns SQLITE_DONE),
-      it must return SQLITE_DONE. Any other return will abort the next call
+      it must return SQLITE_DONE. Any other return will avoid the next call
       in the handling sequence.
 
       <h4>appendResultsOut method</h4>
 
       <h4>closeResultsOutStream method</h4>
     <p>This method is called when a new .mode command is invoked specifying
-      some output mode not using this OutModeHandler or when the extension
-      is about to be unloaded with this OutModeHandler selected for output.
+      some output mode not using this ExportHandler or when the extension
+      is about to be unloaded with this ExportHandler selected for output.
       It should free resources allocated or held as a result of the
       previous openResultsOutStream call.
 
       (1) The ImportHandler address registered via registerImporter().
 
       <h4>destruct method</h4>
-    <p>This method is called prior to unloading a runtime extension
-      for any registered OutModeHandler object, provided its dispatch
-      table entry is non-zero.
+    <p>This method is called prior to the shell's return or exit or
+      unloading the runtime extension for a registered ImportHandler object,
+      provided its dispatch table entry is non-zero.
       It should free resources allocated during the sqlite3_X_init() call
       associated with creation or preparation of the object.
 
       be passed with leading '--' (or '-') to the .import command
       to specify use of the registered importer for that invocation.
       The returned pointer must remain valid throughout the lifetime of
-      the registered MetaCommand object.
+      the registered ImportHandler object.
 
       <h4>help method</h4>
-    <p>This method returns help text for the importer.
+    <p>This method returns help text for the ImportHandler.
     <p>There is one additional argument:<br>
-      (2) an integer directing what help text to return, with
+      (2) a const char * directing what help text to return, with
       0 indicating primary, single-line help, or
-      1 indicating any more detailed help beyond the primary level.
-      The primary help is included in the .import command's own
+      &"" indicating more detailed help beyond the primary level, or
+      &"(other)" reserved for expansion.
+    <p>The primary help is included in the .import command's own
       detailed help text, so it should be aligned accordingly.
       The detailed help is shown by the .import command's --help option.
     <p>The return is either a C string or null pointer. The C string
       will not be freed by the core shell, and must remain valid
-      during the lifetime of the MetaCommand object.
+      during the lifetime of the ImportHandler object.
 
       <h4>Common arguments</h4>
     <p>The following methods are given these 2 additional arguments:<br>
       It should free resources allocated or held as a result of the
       previous openDataInStream call.
 
+      <h3>ScriptSupport typedef</h3>
+    <p>An object of this type is passed by an extension to registerScripting()
+      to enable the shell core to gain scripting functionality provided by
+      the extension.
+    <p>All methods in the dispatch table have this 1 leading argument:<br>
+      (1) The object address registered via registerScripting().
+    <p>The object's v-table contains these methods:
+
+      <h4>destruct method</h4>
+    <p>This method is called prior to the shell's return or exit or unloading
+      the runtime extension, provided its dispatch table entry is non-zero.
+      It should free resources allocated during the sqlite3_X_init() call
+      associated with creation or preparation of the object.
+
+      <h4>name</h4>
+    <p>This method returns the name of the ScriptSupport object.
+      There is no presently planned scheme for using this to switch among
+      scripting providers or even to identify one that is loaded.
+
+      <h4>help</h4>
+    <p>This method returns help text for the ExportHandler.
+      There is no presently implemented use for this method's return.
+    <p>There is one additional argument:<br>
+      (2) a const char * directing what help text to return.
+
+      <h4>configure</h4>
+    <p>This method allows load-time configuration of the extension.
+      It returns a DotCmdRC code indicating status of the extension
+      load and subsequent configuration.
+      It has these 4 additional arguments:<br>
+      (2) ShellExState reference, for general use by the extension;<br>
+      (3) A char ** for an error message associated with configuration;<br>
+      (4) Count of arguments passed in next parameter; and<br>
+      (5) A char * array of arguments passed in the .shxload command tail.
+
+      <h4>isScriptLeader</h4>
+    <p>This method returns TRUE if the provided line text should be
+      considered part of an input line group to be handled by the extension
+      (rather than being treated as a dot-command or SQL), otherwise FALSE.
+      There is one additional argument:<br>
+      (2) char * zLineLead, the initial line of a shell input group.
+
+      <h4>scriptIsComplete</h4>
+    <p>This method returns TRUE if the provided line group text should be
+      considered ready to execute, otherwise FALSE.
+      There are two additional arguments:<br>
+      (2) char * zScript, the possibly ready-to-exectue text; and<br>
+      (3) char ** pzWhyNot, for possibly saying why it is not ready.
+
+      <h4>resetCompletionScan</h4>
+    <p>This method is called by the shell, with no additional arguments,
+      to (possibly) restore the extension's input line scanning state.
+      It has no return.
+
+      <h4>runScript</h4>
+    <p>This method executes the provided script text, returning a
+      DotCmdRC value to indicate success, error, or other dispositions.
+      It has three additional arguments:<br>
+      (2) char * zScript, the to-be-executed text;<br>
+      (3) ShellExState *, (same struct as is passed to configure); and<br>
+      (4) A char ** for an error message associated with the execution.
+
       <h3>ShellExtensionLink typedef</h3>
     <p>An object of this type is passed (somewhat indirectly) to the
       sqlite3_X_init(...) function which is called when a runtime
       It is used to establish linkage between the loaded extension
       and a shell core API exposed specifically for extensibility.
     <p>At present, the extension API is limited to registration of
-      meta-commands, query result handlers, and import handlers
-      implemented by extensions. This API may be extended in future
-      versions of the core shell, in a backwards-compatible manner.
+      meta-commands, query result handlers, import handlers, and
+      scripting support implemented by extensions. This API may be
+      extended in future versions of the core shell, in a backwards-
+      compatible manner.
       (See the pExtra sentinel, whose offset may increase.)
 
       <h4>Establishing Shell/Extension Linkage</h4>
-    <p>The 1st or 2nd parameter passed to the sqlite3_X_init() function
-      as an extension is dynamically loaded is used to obtain a pointer
-      to the ShellExtensionLink object (provided that .load was
-      invoked with the --shell flag.) To verify that the correct
-      object type was passed and reference it if so, the extension's
-      sqlite3_X_init() function can use one of these two means:
-    <p>The least code-intensive means is implemented by a macro,
-      EXTENSION_LINKAGE_PTR(pzem), parameter of which is the char**
-      passed as the 2nd sqlite3_X_init() argument. This is reliable
-      except in the case of a maliciously written shell core (which
-      portends worse problems than the undefined behavior which
-      could arise from invoking .load from such a shell.)
-    <p>A more code-intensive means, (which is no safer in the
-      case of a maliciously written shell core), is to use
-      a C macro, DEFINE_SHDB_TO_SHEXT_API(function_name),
-      in the extension source to define a function named per
-      the macro argument. Then that function may be called with its
-      lone argument being the sqlite3 * (db) pointer which was passed
-      as the 1st argument to sqlite3_X_init().
-    <p>Either means will return (or yield) either a null pointer
-      or a verified ShellExtensionLink pointer. In the former
-      case, sqlite3_X_init() may return SHELL_INVALID_ARGS to induce
-      the emission of help on using the .load command. (Said help
-      will mention the need to use the --shell flag for extensions.)
-      In the latter case, the obtained pointer may be called to
-      register the extension's feature implementor(s) as described.
+    <p>An extension's sqlite3_X_init() function is called soon after
+      the extension is dynamically loaded. It may obtain a pointer
+      to the ShellExtensionLink object by the following means. (Or,
+      without reference to that object, it can do nothing useful.) 
+    <p>During extension build, a macro provided by shext_linkage.h,
+      SHDB_TO_SHEXTLINK(link_function_name), is used to define a
+      function named per its argument. This function accepts a
+      sqlite3 *, as passed into sqlite3_X_init(db, ...), and reads
+      that DB to retrieve the address of a ShellExtensionLink object,
+      which it returns. (Or, it returns NULL if somebody has loaded
+      the extension erroneously using the .load meta-command.)
+    <p>The sqlite3_X_init() function may call this macro-written
+      function to obtain a reference to a ShellExtensionLink object
+      which will remain valid while the extension is loaded.
 
       <h2>Development Aspects of Extensibility and Its Evolution</h2>
 
index 1b01472d57f7dc68b4b0a84e2937cbee8a53a9b8..8d6e0a95aa6c6ca7c5c5a54b636573390b0534eb 100644 (file)
@@ -53,20 +53,25 @@ among others familiar to sqlite3 shell users.
 A variant of the SQLite shell can be built, called "sqlite3x" here,
 whose long name is "The SQLite Extensible Shell".
 It may be built on Unix-like systems by running "make sqlite3x".
-(Build setup for Windows systems will be provided soon.)
+On Windows systems, using MSVC, with suitable environment setup,
+it may be built by running "nmake -f Makefile.msc sqlite3x.exe".
 
 The Tcl extension for sqlite3x, called "tclshext" here,
 may be built for Unix-like systems,
 after configure is run with a "--enable-tcl" option
 (and a "--with-tcl=..." option if necessary),
 by invoking make with "tcl_shell_extension" as a target.
+On Windows systems, using MSVC, with nmake variables TCLDIR and TCLSUFFIX set
+appropriately, it may be built by running
+"nmake -f Makefile.msc tcl_shell_extension".
+
 It may be necessary to first install the Tcl development package or library
 in order for configure to find the Tcl interpreter
-and specify how get it linked into the extension.
+and specify how get it as a library to be linked into the extension.
 
 To manually get a Tcl-extended-shell started,
-(assuming the above-mentioned images were built
-and have been placed where the shell and OS loader can find them),
+(assuming the above-mentioned images were built and have
+been placed where the shell and OS loader can find them [^ loader ]),
 either of these inputs is needed:<br>
 ```
   From a running shell:
@@ -76,10 +81,11 @@ either of these inputs is needed:<br>
   At shell invocation:
     sqlite3x -cmd '.shxload tclshext'
 ```
-(footnote: A directory path may need to be prepended to the extension's
-name for the OS loader to find it unless it is in one of the locations
-designated to the loader as a candidate for dynamic libraries. How such
-designation is made is beyond the scope of this introduction.)
+[^loader]: A directory path may need to be prepended to the extension's
+  name for the OS loader to find it unless it is in one of the locations
+  designated to the loader as a candidate for dynamic libraries. How such
+  designation is made is beyond the scope of this introduction.)
+
 Provided this results in another prompt without any error message(s),
 the Tcl-extended shell is ready to go.
 For brevity, the shell in this state will be called "sqlite3xt".
@@ -166,7 +172,7 @@ in directories named in the PATH environment variable,
 will be executed in a sub-process
 (unless blocked by auto_noexec having been set.)
 
-* The command word and arguments are collected, 
+* The command word and arguments are collected,
 parsed and expanded according to the usual
 [rules for the Tcl language](https://www.tcl.tk/about/language.html).
 In particular, input line groups are collected until deemed "complete"
@@ -183,7 +189,7 @@ There are a few differences however. These are:<br>
 
 * A single '.' on an input line which is not inside of an incomplete
 Tcl line group is treated as a (momentary) end-of-input by the REPL.
-(footnote: "REPL" is short for "Read, Evaluate, Print Loop.)
+(^ "REPL" is short for "Read, Evaluate, Print Loop.)
 
 * The shell's dot commands, while not visible via \[info commands\],
 are discoverable by the "unknown" command and will be executed
@@ -207,7 +213,7 @@ like ones created in Tcl via "sqlite3&nbsp;someDbName&nbsp;itsFilename".
 
  + Commands sqlite_shell_REPL, get_tcl_group and now_interactive
 permit input to be collected in the same manner (and from the same
-sources) as the shell's REPL does. Here, "collected in the same manner" 
+sources) as the shell's REPL does. Here, "collected in the same manner"
 does not include the execution environment switching or SQL execution
 that the shell execution environment implements.
 
index 129388cf27a0dbbba352fe0c68e3387714c5af7e..162b29a4327aab1410402d671972870bb62d2055 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Finish\s.parameter\simprovements.\s(no\sset\s<cast_op>\sanymore,\snot\suseful\senough\sfor\sits\sapparent\scomplexity)
-D 2023-06-12T18:11:11.214
+C Improve\sand\sadd\sdocs\sfor\sextensible\sshell.
+D 2023-06-13T23:04:34.322
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -37,11 +37,12 @@ F configure 697e926af786eb6ddb94ade8aace9f42814902d939ddc6a7bc5f11c3eca7dd51 x
 F configure.ac 510be9293c7efca69c0cc7f427f223b0597f82dda214af7491887db25fa4e237
 F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
 F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
+F doc/extensible_shell.md 478e40a4b06032eb4bd626bf576a0ff4b3058ffb8da4d3fc9f49a94d3eb0654b
 F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f
 F doc/lemon.html d2862dbef72496e87f7996f37e814b146848190a742c12161d13fd15346051b0
 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
-F doc/shell_extend.html c2ce1584bd976613c984a0b7ea4680ef2d2c0ab0642540d730e0a899648e2294
-F doc/tcl_extension_intro.md 216e29662703881e25c857875d6b2b3cba0dfd93c1f718ec27a3bb79b0049066
+F doc/shell_extend.html 61e649726612004ae6efb07507301c120969426c052024dd21550606657ecb9b
+F doc/tcl_extension_intro.md 552277491082f7c286c04b75b5a2d8e1fa675201b28c6c571f7a0a7ed557c2b3
 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a
 F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56
 F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
@@ -691,8 +692,8 @@ F src/test_quota.c ea44c05f29b995bdb71c55eb0c602604884e55681d59b7736e604bbcc68b0
 F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d
 F src/test_rtree.c 671f3fae50ff116ef2e32a3bf1fe21b5615b4b7b
 F src/test_schema.c f5d6067dfc2f2845c4dd56df63e66ee826fb23877855c785f75cc2ca83fd0c1b
-F src/test_shellext_c.c aee192ee9ed63c1a6bde180a74ace1243a235f6fbd583aad67094c1ed6e1ec26
-F src/test_shellext_cpp.cpp 2525913692646e06e9f68206abce155fbcfd92a0c069ebf3937f58f752b871ad
+F src/test_shellext_c.c 9caae730dbbea057cbded37bcab0df4e5fdf87007bbe590d53c33c6044bf1d6e
+F src/test_shellext_cpp.cpp 244f35ee4ead819ac9d3a4e91e961adfa0d74b92476697b9f3b23320a8dca68a
 F src/test_sqllog.c 540feaea7280cd5f926168aee9deb1065ae136d0bbbe7361e2ef3541783e187a
 F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e
 F src/test_syscall.c 9fdb13b1df05e639808d44fcb8f6064aaded32b6565c00b215cfd05a060d1aca
@@ -2051,8 +2052,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 2b51dcdad8fdace33daefdf8ad00fc2f3ab069d5832a1ecf2ac95f580556685d
-R 7f6c971903ba5136fa3683c4ad7b5994
+P bbbdb864f087e806f8fb73618dd769cba5450252e33e938dac0630dd0abb8d43
+R 63bf2e0465b9d20f01f16674055aac03
 U larrybr
-Z 3736662b08f2dafb93e1b2029bd03d30
+Z 69f9a194b6b656a29ffe037db91af732
 # Remove this line to create a well-formed Fossil manifest.
index 87862f460301e80e7c7ad8cfa35919c94fd26163..2edd6e851a5c2048c3dae68f231920bf79919efb 100644 (file)
@@ -1 +1 @@
-bbbdb864f087e806f8fb73618dd769cba5450252e33e938dac0630dd0abb8d43
\ No newline at end of file
+1a57af86da17a3da6bb343001c779d4d9d2ff2c1937ded4d6370d6a951c3cda4
\ No newline at end of file
index b9ac59a8f6194cec3c732b1344da2294a28c2d6e..009d0c9db32c65a49330b30520fbbd87ffa7055e 100644 (file)
@@ -9,9 +9,12 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** Test extension for testing the shell's .load -shellext ... function.
+** Test extension for testing the shell's .shxload ... function.
 ** To build from the SQLite project root:
-** gcc -shared -fPIC -Wall -I. -g src/test_shellext_c.c -o test_shellext_c.so
+** on *Nix:
+** gcc -shared -fPIC -Wall -I. src/test_shellext_c.c -o test_shellext_c.so
+** on Windows with MSVC:
+** cl -I. src/test_shellext_c.c -LD -Fetest_shellext_c.dll
 */
 #include <stdio.h>
 #include "shx_link.h"
@@ -62,7 +65,7 @@ DERIVED_METHOD(DotCmdRC, execute, DotCommand,BatBeing, 4,
 /* Define a DotCommand v-table initialized to reference above methods. */
 DotCommand_IMPLEMENT_VTABLE(BatBeing, batty_methods);
 
-/* Define/initialize BatBeing as a DotCommand subclass using above v-table. 
+/* Define/initialize BatBeing as a DotCommand subclass using above v-table.
  * This compiles in a type-safe manner because the batty_methods v-table
  * and methods it incorporates strictly match the DotCommand interface.
  */
index ae18b1fd8ccc13f009d1ea551283286d00ef0bca..2b926829c4a9eb8f69e8ed80a1d59e5f2b3f9954 100644 (file)
@@ -9,10 +9,12 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** Test extension for testing the shell's .load <extName> -shext function.
+** Test extension for testing the shell's .shxload <extName> function.
 ** To build from the SQLite project root:
-     g++ -shared -fPIC -Wall -I. -g src/test_shellext_cpp.cpp \
-      -o test_shellext_cpp.so
+** on *Nix:
+** g++ -shared -fPIC -Wall -I. src/test_shellext_cpp.cpp -o test_shellext_cpp.so
+** on Windows with MSVC:
+** cl -I. src/test_shellext_cpp.cpp -LD -Fetest_shellext_cpp.dll
 */
 #include <stdio.h>
 #include "shx_link.h"