**.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.
+reverted to the traditional rule where dot-commands always occupy one line
+and neither dot-commands nor #-prefixed comments may have leading whitespace.
**.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.
+be the subject of "edit", "set", "save" and "load" subcommands with
+effect similar to what they do with the .parameter dot-command.
**.x** is a general purpose, "run these" command. By default, its arguments
are treated as shell variable names, values of which are interpreted as
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.
+with trailing backslash, and all shell input may have leading whitespace.
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.
+Also, input lines with leading whitespace will not be accepted as dot-commands
+or #-prefixed comments.
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.
+
+The shell's handling of certain fatal conditions has been changed to make
+it more suitable being embedded into other applications. It no longer calls
+exit() for OOM conditions or -safe mode violations. This feature has not
+yet been fully tested; work remains to be sure that the shell can be called,
+then return to its caller, repeatedly without leaking resources or leaving
+the console in an odd state. But the infrastructure is in place to make
+that all work with only minor (or possibly no) revisions.
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,
+may be built from the top directory of a SQLite project checkout.
+(See [Obtaining Code ...](https://sqlite.org/getthecode.html#obtaining_code_directly_from_the_version_control_system).)
+
+Build the extension 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.
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 as a library to be linked into the extension.
+and specify how to locate it as a library to be linked with the extension.
To manually get a Tcl-extended-shell started,
(assuming the above-mentioned images were built and have
.shxload tclshext
or
At shell invocation:
- sqlite3x -cmd '.shxload tclshext'
+ sqlite3x -cmd ".shxload tclshext"
```
[^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.)
+ 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.
## Yet Another Prompt -- Now What? ##
-When sqlite3xt is ready, it acts very much like the sqlite3 shell.
+When sqlite3xt is ready for input, it acts very much like the sqlite3 shell.
+(^ The sqlite3x shell passes a test suite which is substantially
+identical to that used for the traditional shell, differing only
+in the content and format of error messages.)
When given sensible inputs (as discussed below in "Parsing"),
-that are recognized by sqlite3,
+that are recognized by and valid for the sqlite3 shell,
the same outputs and effects will occur as would with sqlite3.
This condition,
where SQL and dot commands recognized by sqlite3 may be input
The effect of loading tclshext can be briefly summarized as
the introduction of an alternative "execution environment",
+together with a way of entering and leaving it,
explication of which follows this on the primary "execution environment":
-### shell execution environment ###
+### Shell execution environment ###
The "shell execution environment", in effect upon sqlite3xt startup,
has these characteristics pertinent here:
* Whitespace-delimited arguments after the leading token
are parsed according to the section on "Dot-command arguments"
-[here](https://sqlite.org/cli.html), with one exception as noted next.
+[here](https://sqlite.org/cli.html#rules_for_dot_commands_sql_and_more),
+with exceptions as noted next.
-The exception to legacy argument parsing is that open quote
+The main exception to legacy argument parsing is that open quote
constructs are not auto-closed by the end of an input line.
(This legacy behavior may be reinstated if desired by: entering
".shxopts -parsing" at the prompt; renaming the sqlite3x image
until an input line ends outside of any open quote construct.
(Input which does not depend on the legacy, auto-close-on-newline
behavior is what the term "sensible inputs" means as used above.)
-As examples, this would not be sensible input to sqlite3:<br>
+For example, this would not be sensible input to sqlite3:<br>
```
.print 'Hello.
This was entered as multi-line input.'
```
-as it would result in an error, while this input:<br>
+as it would result in an error, (malformed SQL), while this input:<br>
```
- .print "I'm not fond of closing my quotations.
+ .print "I'm not fond of closing my quotations.
```
-is acceptable to sqlite3, but deemed not "sensible" here.
+is acceptable to sqlite3, but deemed "not sensible" here.
When either is input to sqlite3x, a continuation prompt will be issued
-(in interactive mode.)
+(in interactive mode) and the rest of the multi-line input
+will be taken as part of the .print dot-command.
Of course, this is (mostly) review to those familiar with the sqlite3 shell.
* An expanded set of command words is available and readily expanded further.
* The available command words generally do not begin with '.'.
+(^In the Tcl execution environment, enter
+"info commands" to see the available command words.)
* When in interactive mode, commands whose
initial token is not defined as a Tcl command,
-but can be found as an executable
-in directories named in the PATH environment variable,
+but which can be found as an executable
+in a directory named in the PATH environment variable,
will be executed in a sub-process
-(unless blocked by auto_noexec having been set.)
+(unless blocked by Tcl global variable auto_noexec having been set.)
* The command word and arguments are collected,
parsed and expanded according to the usual
either of which may affect argument expansion
per the usual Tcl rules.
-This environment will be quite familiar to those who use Tcl.
+This environment will be familiar to those who use Tcl.
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.
-(^ "REPL" is short for "Read, Evaluate, Print Loop.)
+(^ "REPL" is an acronym 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
if their names (with the '.' prefix) would be found and resolved
unambiguously in the shell execution environment.
-Commands whose names begin with '.' which are not found uniquely in the
+Commands whose names begin with '.' which are not found as unique in the
shell execution environment produce an "invalid command name" error.
Except for that treatment, the unknown command in effect
acts like the standard Tcl version.
-(footnote: That version remains available as _original_unkown,
-to which non-dot commands are delegated .)
+(That standard version remains available as _original_unkown,
+to which handling of non-dot-prefixed commands is delegated.)
* A few non-standard-Tcl commands are available. In particular:
it does nothing, quietly and successfully, with the empty result.
* The present implementation does not run the event loop processing
-that Tcl often uses for certain functionality (such as sockets.)
+that the standard Tcl REPL uses to support certain functionality
+(such as sockets, asynchronous I/O and the Tk GUI subsystem.)
+A future enhancement is to support use of event loop and Tk.
## Switching Execution Environments ##
When entered without any argument(s)
from the shell execution environment,
the .tcl command has the same effect as .. by itself.
-(footnote:
-When run from the Tcl execution environment with no arguments,
-it acts as a no-op rather than entering a recursive REPL.)
+(^When run from the Tcl execution environment with no arguments,
+.tcl acts as a no-op rather than entering a recursive REPL.)
With arguments, it will read file content into the Tcl interpreter
just as Tcl's source command would.
This may be useful for getting the Tcl execution environment
This temporary use of the Tcl interpreter serves two purposes.
One is to exploit the more powerful capabilities of Tcl for argument processing.
-Within the text of arguments as provided,
-variables can be accessed,
-computations can be done,
+Within the text of arguments as provided,
+variables can be accessed, computations can be done,
and Tcl commands can be invoked to yield results (or produce side effects),
all of which can affect what the expanded arguments finally contain.
The other (miniscule) effect is to avoid the need for extra
passed to the Tcl command named "unknown".
In the tclshext-augmented Tcl environment,
that procedure is implemented by C code which treats
-a purported command with a leading '.' specially,
+a purported command with a leading '.' specially,
by attempting to find it in the shell's repertoire of dot commands.
If found (unambiguously), it is then executed
and the result (such as it is) returned to the caller.
-(footnote: The sqlite3 dot commands return the empty result on success.)
+(The sqlite3 shell dot-commands return the empty result on success.)
So, assuming there is a dot command invokable as .dotcmd,
(which there could be if another extension provided it),
it can be found and executed from the Tcl execution environment
It should be noted, for those new to Tcl, that brace-quoting in Tcl
means "Whatever is between these matching braces is the (single) value."
-It can be used for nearly any content, except for mismatched braces.
+It can be used for nearly any content, excepting explicit mismatched braces.
## Summary, More to Come ##
-C Improve\sand\sadd\sdocs\sfor\sextensible\sshell.
-D 2023-06-13T23:04:34.322
+C More\sdoc\stweaks,\sone\steensy\senhancement,\sand\sa\snew\sfeature\sbug\sfix
+D 2023-06-16T02:18:59.017
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F configure.ac 510be9293c7efca69c0cc7f427f223b0597f82dda214af7491887db25fa4e237
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd
-F doc/extensible_shell.md 478e40a4b06032eb4bd626bf576a0ff4b3058ffb8da4d3fc9f49a94d3eb0654b
+F doc/extensible_shell.md 3a32ed1d6f9d59d9cd8c94d149a33c448cfdfcff20aaa9031681699f9e82710e
F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f
F doc/lemon.html d2862dbef72496e87f7996f37e814b146848190a742c12161d13fd15346051b0
F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710
F doc/shell_extend.html 61e649726612004ae6efb07507301c120969426c052024dd21550606657ecb9b
-F doc/tcl_extension_intro.md 552277491082f7c286c04b75b5a2d8e1fa675201b28c6c571f7a0a7ed557c2b3
+F doc/tcl_extension_intro.md 4c0505365c6a37dbfb93c66e72e228c517947e9daa9f3040ef4390461cb5740b
F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a
F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56
F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
F ext/misc/spellfix.c 94df9bbfa514a563c1484f684a2df3d128a2f7209a84ca3ca100c68a0163e29f
F ext/misc/sqlar.c 53e7d48f68d699a24f1a92e68e71eca8b3a9ff991fe9588c2a05bde103c6e7b7
F ext/misc/stmt.c bc30d60d55e70d0133f10ac6103fe9336543f673740b73946f98758a2bb16dd7
-F ext/misc/tclshext.c.in 1a49bd7d9e2e06f7ed5f409dab829724b9e91a5c766275313fc142e30d441012
+F ext/misc/tclshext.c.in 066f3b5cb386244167aeb03d7a46b5974b50ac72d17d6546649a66ceb7614613
F ext/misc/templatevtab.c 8a16a91a5ceaccfcbd6aaaa56d46828806e460dd194965b3f77bf38f14b942c4
F ext/misc/totype.c fa4aedeb07f66169005dffa8de3b0a2b621779fd44f85c103228a42afa71853b
F ext/misc/uint.c 053fed3bce2e89583afcd4bf804d75d659879bbcedac74d0fa9ed548839a030b
F src/resolve.c c1457b920aeb33ed106bf478fad31b7473a8950a755ea898980c428928f3a514
F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
F src/select.c 1ddfe4450101c3d4890ecb2d6b97ab80b78764d5a3e7022b171721df1620c419
-F src/shell.c.in a1cca1616759d744de488f9592a86557b85caf65ff5aa7fe5fb2aa75f14bad75
+F src/shell.c.in 188945e30d1688970ca853c07a4a5bd95657381d01a6b6150e0a9e11fce221c8
F src/shext_linkage.h 4a686427844d5d2b71f2095cb032280fb262490795f0710487ebbedb3732f1cb
F src/sqlite.h.in 3076d78836b6dac53b3ab0875fc8fd15bca8077aad4d33c85336e05af6aef8c7
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P bbbdb864f087e806f8fb73618dd769cba5450252e33e938dac0630dd0abb8d43
-R 63bf2e0465b9d20f01f16674055aac03
+P 1a57af86da17a3da6bb343001c779d4d9d2ff2c1937ded4d6370d6a951c3cda4
+R b6513344e2855361b63c6f2e2dc46ceb
U larrybr
-Z 69f9a194b6b656a29ffe037db91af732
+Z 29b4d969b0d35ef65e922c1adb2b29af
# Remove this line to create a well-formed Fossil manifest.
}
if( zFile==0 ) return DCR_Missing;
if( pzExtArgs==0 ) pzExtArgs = azArg + ai;
+ open_db(p, 0);
rc = load_shell_extension(p, zFile, zProc, pzErr, nArg-ai, pzExtArgs);
return DCR_Ok|(rc!=SQLITE_OK);
}
return DCR_CmdErred;
}
+static void showWidths(ShellExState *p){
+ int i = 0;
+ while( i < p->numWidths ){
+ raw_printf(ISS(p)->out," %d",p->pSpecWidths[i++]);
+ }
+ raw_printf(ISS(p)->out,"\n");
+}
+
DISPATCHABLE_COMMAND( show ? 1 1 ){
static const char *azBool[] = { "off", "on", "trigger", "full"};
const char *zOut;
case 3: zOut = "vmstep"; break;
}
utf8_printf(out, "%12.12s: %s\n","stats", zOut);
- utf8_printf(out, "%12.12s: ", "width");
- for (i=0;i<p->numWidths;i++) {
- raw_printf(out, "%d ", p->pSpecWidths[i]);
- }
- raw_printf(out, "\n");
+ utf8_printf(out, "%12.12s:", "width");
+ showWidths(p);
utf8_printf(out, "%12.12s: %s\n", "filename",
psi->pAuxDb->zDbFilename ? psi->pAuxDb->zDbFilename : "");
return DCR_Ok;
}
COLLECT_HELP_TEXT[
".width NUM1 NUM2 ... Set minimum column widths for columnar output",
- " Negative values right-justify",
+ " Negative values right-justify. A lone ? shows the current values.",
];
DISPATCHABLE_COMMAND( width ? 1 0 ){
- setColumnWidths(p, azArg+1, nArg-1);
+ if( nArg==2 && cli_strcmp(azArg[1],"?")==0 ) showWidths(p);
+ else setColumnWidths(p, azArg+1, nArg-1);
return DCR_Ok;
}