-C .tables\sfixup\sfor\slegacy\sbehavior.
-D 2021-07-10T14:48:46.041
+C Much\sself-doc\simprovement\sfor\sshell.c\sgeneration.\sMisleading\serror\smessage\sfixed.
+D 2021-07-11T12:58:51.966
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F src/resolve.c b379c5ffe3b692e9c64fa37817cc0efa204b7c9468a818309dde85fd132d9d81
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c 4fa607bab6bcc580f12dbaf9c800b2250a1e408f10321a1d3bcb1dd30c447e62
-F src/shell.c.in cc7c2c8a88af743a2af7e199b2e008c210347949567f74b49d9cfbc31daf3c6e
+F src/shell.c.in 95d72eae73d2c9bb76934c0bb9f083c0a770822640ef167cb15276102d1b7e52
F src/sqlite.h.in ecf5aa981da30c33da3e9f353bf3ebf055d3c380c80d6a4f954e58d18ccd6df1
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510
F tool/mkopcodeh.tcl 130b88697da6ec5b89b41844d955d08fb62c2552e889dec8c7bcecb28d8f50bd
F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa
F tool/mkpragmatab.tcl ae5585ae76ca26e4d6ccd5ea9cdebaf5efefb318bf989497a0e846cd711d9ab1
-F tool/mkshellc.tcl 8d154d752af008add2ae41d6bff4753d275e8d457620adde7d09380010bf0e67
+F tool/mkshellc.tcl ba339f8c33d7588cfe40243148de015f5a235c34a402d9a526df922b3f48ad1d
F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9
F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P ac4267da196020b41f736b72e8ddc97e8e83be5e97e23caabd107a5a6d832921
-R 05b05996f39d22bb5178c3e0aab92706
+P 827ea61d7d509fb6356aeab9e4fdd7619c1eeb4e8860d71ccb79a91737f9dde9
+R 8d6fc3f0c488c96ecd42108ef059ec74
U larrybr
-Z 00b8639d40cc18fa56382ef7ba39d140
+Z 3572dfa7570a81d67634e9e7f808d789
return rc;
}
-/*
- * Define meta-commands and provide for their dispatch and .help text.
- * These should be kept in command name order for coding convenience
- * except where meta-commands share implementation. (The ordering
- * required for dispatch and help text is effected regardless.)
- */
-
+/* Meta-command implementation functions are defined in this section.
+COMMENT Define meta-commands and provide for their dispatch and .help text.
+COMMENT These should be kept in command name order for coding convenience
+COMMENT except where meta-commands share implementation. (The ordering
+COMMENT required for dispatch and help text is effected regardless.) The
+COMMENT effect of this configuration can be seen in generated output or by
+COMMENT executing tool/mkshellc.tcl --parameters (or --details or --help).
+COMMENT Generally, this section defines dispatchable functions inline and
+COMMENT causes collection of dispatch and help table entries, to be later
+COMMENT emitted by the EMIT_DISPATCH and EMIT_HELP_TEXT macros further on.
+*/
DISPATCH_CONFIG[
RETURN_TYPE=int
STORAGE_CLASS=static
}
if( nSep>1 ){
raw_printf(stderr,
- "Error: multi-character column separators not allowed"
- " for import\n");
+ "Error: multi-character or multi-byte column separators"
+ " not allowed for import\n");
return 1;
}
nSep = strlen30(p->rowSeparator);
/*****************
* The .tables, .views, .indices and .indexes command
- * These are kept together because they share implementation or are aliases.
+ * These are together because they share implementation or are aliases.
*/
COLLECT_HELP_TEXT[
".indexes ?TABLE? Show names of indexes",
" If TABLE is specified, only show indexes for",
" tables matching TABLE using the LIKE operator.",
-#ifndef LEGACY_TABLES_LISTING
- ".tables ?FLAG? ?TABLE? List names of tables/views matching LIKE pattern TABLE",
- " FLAG can be -t to list tables only or -v to list views only",
-#else
- ".tables ?TABLE? List names of tables/views matching LIKE pattern TABLE",
-#endif
];
static int showTableLike(char *azArg[], int nArg, ShellState *p, char ot){
int rc;
for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){
const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
const char *zFilter = "";
+ const char *zSystem = " AND name NOT LIKE 'sqlite_%'";
if( zDbName==0 ) continue;
if( s.z && s.z[0] ) appendText(&s, " UNION ALL ", 0);
if( sqlite3_stricmp(zDbName, "main")==0 ){
zFilter = "'view'";
break;
#endif
+ case 's':
+ zSystem = " AND name LIKE 'sqlite_%'";
+ /* fall thru */
case 'T':
zFilter = "'table','view'";
break;
}
appendText(&s, " WHERE type IN(", 0);
appendText(&s, zFilter, 0);
- appendText(&s, ") AND name LIKE ?1 AND name NOT LIKE 'sqlite_%'", 0);
+ appendText(&s, ") AND name LIKE ?1", 0);
+ appendText(&s, zSystem, 0);
}
rc = sqlite3_finalize(pStmt);
appendText(&s, " ORDER BY 1", 0);
sqlite3_free(azResult);
return 0;
}
+
+COLLECT_HELP_TEXT[
+#ifndef LEGACY_TABLES_LISTING
+ ".tables ?FLAG? ?TABLE? List names of tables/views matching LIKE pattern TABLE",
+ " FLAG can be -t, -v or -s to list tables or views only, or system tables only",
+#else
+ ".tables ?TABLE? List names of tables/views matching LIKE pattern TABLE",
+#endif
+];
DISPATCHABLE_COMMAND( tables 2 1 3 ){
char objType = 'T';
#ifndef LEGACY_TABLES_LISTING
if( nArg>1 && azArg[1][0]=='-' && azArg[1][1]!=0 && azArg[1][2]==0 ){
char c = azArg[1][1];
switch (c){
+ case 's':
case 't':
case 'v':
objType = c;
return 0;
}
+/* End of published, standard meta-command implementation functions
+COMMENT Build-time overrides of above meta-commands or new meta-commands may be
+COMMENT incorporated into shell.c via: -it COMMAND_CUSTOMIZE=<customize source>
+COMMENT where <customize source> names a file using the methodology of the above
+COMMENT section to define new or altered meta-commands and their help text.
+*/
+INCLUDE( COMMAND_CUSTOMIZE );
+
/* Define and populate command dispatch table. */
static struct DispatchEntry {
const char * cmdName;
int (*cmdDoer)(char *azArg[], int nArg, ShellState *);
unsigned char minLen, minArgs, maxArgs;
} command_table[] = {
+ COMMENT Emit the dispatch table entries generated and collected above.
EMIT_DISPATCH(2);
{ 0, 0, 0, -1, -1 }
};
static unsigned numCommands = sizeof(command_table)/sizeof(struct DispatchEntry) - 1;
+COMMENT This help text is set seperately from meta-command definition section
+COMMENT for the always-built-in, non-customizable commands with visible help.
+COLLECT_HELP_TEXT[
+ ".exit ?CODE? Exit this program with return-code CODE or 0",
+ ".quit Exit this program",
+];
+
+/*
+** Text of help messages.
+**
+** The help text for each individual command begins with a line that starts
+** with ".". Subsequent lines are supplimental information.
+**
+** There must be two or more spaces between the end of the command and the
+** start of the description of what that command does.
+*/
+static const char *(azHelp[]) = {
+/* Template for help text indents and length:
+ ".whatever ?arg? ... Summary of effects (limited to this line's length)",
+ " ^ ^ ^ ^ ",
+*/
+ COMMENT Emit the help text fragments collected above via COLLECT_HELP_TEXT.
+ EMIT_HELP_TEXT(2);
+ 0 /* Sentinel */
+};
+
/*****************
* Command dispatcher
*/
sqlite3_free(zBuf);
}
-COLLECT_HELP_TEXT[
- ".exit ?CODE? Exit this program with return-code CODE",
- ".quit Exit this program",
-];
-
-/*
-** Text of help messages.
-**
-** The help text for each individual command begins with a line that starts
-** with ".". Subsequent lines are supplimental information.
-**
-** There must be two or more spaces between the end of the command and the
-** start of the description of what that command does.
-*/
-static const char *(azHelp[]) = {
-/* Template for help text indents and length:
- ".whatever ?arg? ... Summary of effects (limited to this line's length)",
- " ^ ^ ^ ^ ",
-*/
- EMIT_HELP_TEXT(2);
- 0 /* Sentinel */
-};
-
/*
** Show available command line options
*/
** Most of the code found below comes from the "src/shell.c.in" file in
** the canonical SQLite source tree. That main file contains "INCLUDE"
** lines that specify other files in the canonical source tree that are
-** inserted and transformed to generate this complete program source file.
+** inserted and transformed, (via macro invocations explained by running
+** "tool/mkshellc.tcl --help"), to generate this complete program source.
**
-** The code from multiple files is combined into this single "shell.c"
-** source file to help make the command-line program easier to compile.
+** By means of this generation process, creating this single "shell.c"
+** file, building the command-line program is made simpler and easier.
**
** To modify this program, get a copy of the canonical SQLite source tree,
-** edit the src/shell.c.in" and/or some of the other files included by
-** "src/shell.c.in", then rerun the tool/mkshellc.tcl script.
+** edit file src/shell.c.in and/or some of the other files included by it,
+** then rerun the tool/mkshellc.tcl script.
*/}
set customRun 0
+set lineDirectives 1
set infiles {}
-array set incTypes [list "*" {}]
+array set ::incTypes [list "*" {}]
while {[llength $argv] > 0} {
set argv [lassign $argv opt]
- if {[regexp {^-{1,2}((help)|(details))$} $opt ma ho]} {
- if {$ho eq "help"} { set customRun 2 } else { set customRun 3 }
+ if {[regexp {^-{1,2}((help)|(details)|(parameters))$} $opt ma ho]} {
+ switch $ho {
+ help {set customRun 2}
+ details {set customRun 3}
+ parameters {set customRun 4}
+ }
} elseif {[regexp {^-it$} $opt]} {
set argv [lassign $argv nextOpt]
if {![regexp {^(\w+)=(.+)$} $nextOpt ma k v]} {
puts stderr "Get help with --help."
exit 1
}
- set incTypes($k) $v
- puts stderr "Include types not yet implemented or needed." ; exit 1
+ set ::incTypes($k) $v
} elseif {$opt eq "-tcl"} {
puts stderr "Tcl extension not yet implemented." ; exit 1
+ } elseif {[regexp {^--?no-line-directives$} $opt]} {
+ set lineDirectives 0
} elseif {[regexp {^[^-]} $opt]} {
lappend infiles $opt
set customRun 1
set ::cmd_help [dict create]
set ::cmd_dispatch [dict create]
set ::cmd_condition [dict create]
+set ::inc_type_files [dict create]
set ::iShuffleErrors 0
regexp {(\{)(\})} "{}" ma ::lb ::rb ; # Ease use of { and }.
# Setup dispatching function signature and table entry struct .
+# The effect of these key/value pairs is as this --parameters output says:
+set ::parametersHelp {
+ The following parameters given to DISPATCH_CONFIG have these effects:
+ RETURN_TYPE sets the generated dispatchable function signature return type.
+ STORAGE_CLASS sets the dispatchable function linkage, (typically "static".)
+ ARGS_SIGNATURE sets the formal argument list for the dispatchable functions.
+ DISPATCH_ENTRY sets the text of each entry line in emitted dispatch table.
+ DISPATCHEE_NAME sets the name to be generated for dispatchable functions.
+ CMD_CAPTURE_RE sets a regular expression to be used for capturing the name
+ to be used for meta-commands within a line passed into COLLECT_DISPATCH,
+ (which is needed to permit them to be emitted in lexical order by name.)
+ DC_ARG_COUNT sets the effective argument count for DISPATCHABLE_COMMAND().
+ DC_ARG#_DEFAULT sets a default value, DISPATCHABLE_COMMAND() #'th argument.
+ Within values set for ARGS_SIGNATURE, DISPATCHEE_NAME, and DISPATCH_ENTRY
+ parameters, the variables $cmd and $arg# (where # is an integer) may appear,
+ to be replaced by the meta-command name or the #'th effective argument to
+ DISPATCHABLE_COMMAND(). The "effective" argument is either what is provided,
+ or a default value when the actual argument is missing (at the right end of
+ the provided argument list) or the argument has the value ? . The expansion
+ of $cmd and $arg# variables is done by Tcl evaluation (via subst), allowing
+ a wide range of logic to be employed in the derivation of effective values.
+}
set ::dispCfg [dict create \
RETURN_TYPE int \
STORAGE_CLASS static \
array set ::macroTailREs [list \
COLLECT_DISPATCH {^\(\s*([\w\*]+)\s*\)\[} \
COLLECT_HELP_TEXT {^\[} \
+ COMMENT {\s+(.*)$} \
CONDITION_COMMAND {^\(\s*(\w+)\s+([^;]+)\);} \
DISPATCH_CONFIG {^\[} \
DISPATCHABLE_COMMAND {^\(([\w\? ]+)\)(\S)\s*$} \
EMIT_DISPATCH {^\((\d*)\)} \
EMIT_HELP_TEXT {^\((\d*)\)} \
+ INCLUDE {^\(\s*(\w+)\s*\)} \
]
array set ::macroUsages [list \
COLLECT_DISPATCH "\[\n <dispatch table entry lines>\n \];" \
COLLECT_HELP_TEXT "\[\n <help text lines>\n \];" \
+ COMMENT " <arbitrary characters to end of line>" \
CONDITION_COMMAND "( name pp_expr );" \
DISPATCH_CONFIG "\[\n <NAME=value lines>\n \];" \
- DISPATCHABLE_COMMAND "( name args... ){\n <code lines>\n }" \
+ DISPATCHABLE_COMMAND "( name args... ){\n <implementation code lines>\n }" \
EMIT_DISPATCH "( indent );" \
EMIT_HELP_TEXT "( indent );" \
+ INCLUDE {( <inc_type> )} \
]
# RE for early discard of non-macro lines, matching all above keywords
-set ::macroKeywordTailRE {^\s{0,8}((?:(?:CO)|(?:DI)|(?:EM))[A-Z_]+)\M(.+)$}
+set ::macroKeywordTailRE {^\s{0,8}((?:(?:CO)|(?:DI)|(?:EM)|(?:IN))[A-Z_]+)\M(.+)$}
# All macro processor procs return the count of extra input lines consumed.
incr iAte
return $iAte
}
-
+
+proc COMMENT {hFile tailCaptureIgnore ostrm} {
+ # Allow comments in an input file which have no effect on output.
+ return 1
+}
+
+proc INCLUDE {hFile tailCaptureIncType ostrm} {
+ # If invoked with a bare filename, include the named file. If invoked
+ # with the parenthesized word form, include a file named by means of
+ # the '-it <inc_type>=filename' command line option, provided that the
+ # word matches a specified <inc_type>. Otherwise, do nothing.
+ set it [lindex $tailCaptureIncType 0]
+ if {[regexp {\s*([a-zA-Z\._\\/]+)\s*} $it ma it]} {
+ if {[info exists ::incTypes($it)]} {
+ set fname $::incTypes($it)
+ puts $ostrm "/* INCLUDE($it), of \"$fname\" skipped. */"
+ # ToDo: Get including done with a proc so it can be done from here.
+ # This will support emitting #line directives to aid debugging.
+ }
+ }
+ return 1
+}
+
proc COLLECT_HELP_TEXT {hFile tailCaptureEmpty ostrm} {
# Collect help text table values, along with ordering info.
set iAte 0
proc DISPATCHABLE_COMMAND {hFile tailCapture ostrm} {
# Generate and emit a function definition, maybe wrapped as set by
- # CONDITION_COMMAND(), and generate/collect its dispatch table entry.
+ # CONDITION_COMMAND(), and generate/collect its dispatch table entry,
+ # as determined by its actual arguments and DISPATCH_CONFIG parameters.
lassign $tailCapture args tc
if {$tc ne $::lb} {
yap_usage "DISPATCHABLE_COMMAND($args)$tc" DISPATCHABLE_COMMAND
# Show options and usage
say_usage [lsort [array names ::macroUsages]] {
mkshellc.tcl <options>
- <options> may be either --help, --details, or any sequence of:
+ <options> may be either --help, --details, --parameters or any sequence of:
<input_filename>
-it <inc_type>=<include_filename>
-tcl
- If no input files are specified, <PROJECT_ROOT>/src/shell.c.in will be
- read. Input files are read and processed, producing output to sdout.
- They may include macro lines or line sequences matching any of:
- INCUDE <file_name>
- INCUDE(<inc_type>) }
- puts stderr { Use --details option for effects of these macros.}
+ -no-line-directives
+ If no input files are specified, <PROJECT_ROOT>/src/shell.c.in is read.
+ Input files are read and processed in order, producing output to sdout.
+ The -it option associates a filename with an <inc_type> word which may
+ be encountered during execution of INCLUDE(...) directives in the input.
+ Input files may include macro lines or line sequences matching any of:
+ INCUDE <file_name> }
+ puts stderr {
+ Use --details option for detailed effects of these macros.
+ Use --parameters option for DISPATCH_CONFIG parameter names and effects.
+ }
exit 0
} elseif {$customRun == 3} {
set sfd [open $argv0 r]
+ set macdos [dict create]
while {![eof $sfd]} {
if {[regexp {^proc ([A-Z_]+\M)} [gets $sfd] ma macro]} {
if {[info exists ::macroTailREs($macro)]} {
while {[regexp {^\s+#\s*(.+)$} [gets $sfd] ma effect]} {
lappend effects " $effect"
}
- puts stderr "\nThe $macro macro will:"
- puts stderr [join $effects "\n"]
+ dict set macdos $macro [join $effects "\n"]
}
}
}
close $sfd
+ foreach m [lsort [dict keys $macdos]] {
+ puts stderr "\nThe $m macro will:\n [dict get $macdos $m]"
+ }
+ exit 0
+} elseif {$customRun == 4} {
+ puts stderr $::parametersHelp
exit 0
}