From: larrybr Date: Sun, 4 Jul 2021 22:38:20 +0000 (+0000) Subject: Streamline most common command definition X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=efb33029866274ba45d3dd36695b58f2db32e27d;p=thirdparty%2Fsqlite.git Streamline most common command definition FossilOrigin-Name: dd76b41a72aca94450fb6f45ff56af95d2adb9275eebe9ca67ebd04a52a63c33 --- diff --git a/manifest b/manifest index 5821ef2b6a..37b3989078 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Create\sinfrastructure\sfor\sdynamic\sshell\sextension. -D 2021-07-03T19:20:48.689 +C Streamline\smost\scommon\scommand\sdefinition +D 2021-07-04T22:38:20.110 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -545,7 +545,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/resolve.c b379c5ffe3b692e9c64fa37817cc0efa204b7c9468a818309dde85fd132d9d81 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 4fa607bab6bcc580f12dbaf9c800b2250a1e408f10321a1d3bcb1dd30c447e62 -F src/shell.c.in ab31fb9d92ab84e1abb02a2c40e910b24434e729fa7549acbb3fee9aed5973d8 +F src/shell.c.in 0a1460f9daacc06ce7618981d2d3d3b206a64ca30258a5968ffd421eccaabaeb F src/sqlite.h.in ecf5aa981da30c33da3e9f353bf3ebf055d3c380c80d6a4f954e58d18ccd6df1 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 @@ -1853,7 +1853,7 @@ F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 130b88697da6ec5b89b41844d955d08fb62c2552e889dec8c7bcecb28d8f50bd F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa F tool/mkpragmatab.tcl ae5585ae76ca26e4d6ccd5ea9cdebaf5efefb318bf989497a0e846cd711d9ab1 -F tool/mkshellc.tcl 627d5f39b306cc335e5f29d8b24945c54a64a42e635fc8eb8c2558ba257c9844 +F tool/mkshellc.tcl 270ddd503b3c6c2ea1fa6559a086cd2517ff84088b54909960fffeda4d0b816e F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f @@ -1919,10 +1919,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 68db1ff9c44fa9c37690ce55ad304d4263ba6fac490063d9e08470de6c17cfe6 -R 347b1c92e54f1f6ec16ffdb8c5434cca -T *branch * cli_extension -T *sym-cli_extension * -T -sym-trunk * +P 5e7e0d4ef8665e924f499238b1469a5fc06d24f6cf96864b502e62734d92e7ee +R 1911848c8c9c967a495f2da60a0478ec U larrybr -Z d788ab2ca1c9950dfd92c69b64866455 +Z 9f01a27b7f49ee2ea4a875a6945797b7 diff --git a/manifest.uuid b/manifest.uuid index f649a6ef7e..7ee1d1065d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5e7e0d4ef8665e924f499238b1469a5fc06d24f6cf96864b502e62734d92e7ee \ No newline at end of file +dd76b41a72aca94450fb6f45ff56af95d2adb9275eebe9ca67ebd04a52a63c33 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 5fa089b490..fe5db11388 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -218,6 +218,7 @@ static void setTextMode(FILE *file, int isOutput){ #endif static const char *(azHelp[]); +static unsigned numCommands; /* True if the timer is enabled */ static int enableTimer = 0; @@ -3911,7 +3912,7 @@ static int showHelp(FILE *out, const char *zPattern){ } pzH = pzHxtra; n++; - } else { + }else{ ++pzH; } } @@ -7130,6 +7131,39 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ } #endif /* !(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) */ +CONDITION_COMMAND(seeargs defined(SQLITE_GIMME_SEEARGS)); +/***************** + * The .seeargs command + */ +COLLECT_HELP_TEXT[ + ".seeargs Echo arguments separated by |", + " A near-dummy command for use as a template (to vanish soon)", +]; +DISPATCHABLE_COMMAND( seeargs ? 0 0 azArg nArg p ){ + int rc = 0; + for (rc=1; rcout, "%s%s", azArg[rc], (rc==nArg-1)? "\n" : "|"); + return rc; +} + +/***************** + * The .auth command + */ +CONDITION_COMMAND(auth !defined(SQLITE_OMIT_AUTHORIZATION)); +COLLECT_HELP_TEXT[ + ".auth ON|OFF Show authorizer callbacks", +]; +DISPATCHABLE_COMMAND( auth 3 2 2 azArg nArg p ){ + int rc = 0; + open_db(p, 0); + if( booleanValue(azArg[1]) ){ + sqlite3_set_authorizer(p->db, shellAuth, p); + }else{ + sqlite3_set_authorizer(p->db, 0, 0); + } + return rc; +} + /***************** * The .help command */ @@ -7161,6 +7195,7 @@ static struct DispatchEntry { EMIT_DISPATCH(); { 0, 0, 0, -1, -1 } }; +static unsigned numCommands = sizeof(command_table)/sizeof(struct DispatchEntry) - 1; /***************** * Command dispatcher @@ -7171,17 +7206,27 @@ static struct DispatchEntry { int dispatchCommand(char *azArg[], int nArg, ShellState *pSS) { const char *cmdName = azArg[0]; - /* A temporary, simple-minded scan */ - struct DispatchEntry *pde = command_table; - while (pde->cmdName != 0){ - if (0==strncmp(cmdName, pde->cmdName, pde->minLen)){ - if((pde->minArgs > 0 && pde->minArgs > nArg)||(pde->maxArgs > 0 && pde->maxArgs < nArg)){ - return INVALID_ARGS; - } - return (pde->cmdDoer)(azArg, nArg, pSS); - } else { ++pde; } + struct DispatchEntry *pde = 0; + int ixb = 0, ixe = numCommands-1; + while( ixb <= ixe ){ + int ixm = (ixb+ixe)/2; + int md = strncmp(cmdName, command_table[ixm].cmdName, command_table[ixm].minLen); + if( md>0 ){ + ixb = ixm+1; + }else if( md<0 ){ + ixe = ixm-1; + }else{ + pde = &command_table[ixm]; + break; + } } - return NO_SUCH_COMMAND; + if( 0==pde ){ + return NO_SUCH_COMMAND; + } + if((pde->minArgs > 0 && pde->minArgs > nArg)||(pde->maxArgs > 0 && pde->maxArgs < nArg)){ + return INVALID_ARGS; + } + return (pde->cmdDoer)(azArg, nArg, pSS); } @@ -7236,21 +7281,6 @@ static int do_meta_command(char *zLine, ShellState *p){ c = azArg[0][0]; clearTempFile(p); -#ifndef SQLITE_OMIT_AUTHORIZATION - if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){ - if( nArg!=2 ){ - raw_printf(stderr, "Usage: .auth ON|OFF\n"); - rc = 1; - goto meta_command_exit; - } - open_db(p, 0); - if( booleanValue(azArg[1]) ){ - sqlite3_set_authorizer(p->db, shellAuth, p); - }else{ - sqlite3_set_authorizer(p->db, 0, 0); - } - }else -#endif #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){ @@ -10198,9 +10228,14 @@ static int do_meta_command(char *zLine, ShellState *p){ /* The meta-command is not among the specially handled ones. Dispatch it. */ { int dispatchResult = dispatchCommand(azArg, nArg, p); - if( NO_SUCH_COMMAND==dispatchResult || INVALID_ARGS==dispatchResult ){ - utf8_printf(stderr, "Error: unknown command or invalid arguments: " - " \"%s\". Enter \".help\" for help\n", azArg[0]); + if( NO_SUCH_COMMAND==dispatchResult ){ + utf8_printf(stderr, "Error: unknown command: \"%s\"\n" + " Enter \".help\" for a list of commands.\n", azArg[0]); + rc = 1; + } + if( INVALID_ARGS==dispatchResult ){ + utf8_printf(stderr, "Error: invalid arguments for \".%s\"\n" + " Enter \".help %s\" for help on it.\n", azArg[0],azArg[0]); rc = 1; } } @@ -10554,11 +10589,6 @@ COLLECT_HELP_TEXT[ " http://sqlite.org/cli.html#sqlite_archive_support", #endif ]; -COLLECT_HELP_TEXT[ -#ifndef SQLITE_OMIT_AUTHORIZATION - ".auth ON|OFF Show authorizer callbacks", -#endif -]; COLLECT_HELP_TEXT[ ".backup ?DB? FILE Backup DB (default \"main\") to FILE", " --append Use the appendvfs", @@ -10829,8 +10859,12 @@ COLLECT_HELP_TEXT[ ** 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(); - 0 + 0 /* Sentinel */ }; /* diff --git a/tool/mkshellc.tcl b/tool/mkshellc.tcl index 71ab09e302..8ca4259ded 100644 --- a/tool/mkshellc.tcl +++ b/tool/mkshellc.tcl @@ -14,9 +14,9 @@ set out stdout fconfigure stdout -translation {auto lf} puts $out {/* DO NOT EDIT! ** This file is automatically generated by the script in the canonical -** SQLite source tree at tool/mkshellc.tcl. That script combines source -** code from various constituent source files of SQLite into this single -** "shell.c" file used to implement the SQLite command-line shell. +** SQLite source tree at tool/mkshellc.tcl. That script combines and +** transforms code from various constituent source files of SQLite into +** this single "shell.c" file to implement the SQLite command-line shell. ** ** 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" @@ -33,12 +33,35 @@ puts $out {/* DO NOT EDIT! set in [open $topdir/src/shell.c.in rb] -proc omit_redundant_typedefs {line} { -} - set ::cmd_help [dict create] set ::cmd_dispatch [dict create] +set ::cmd_condition [dict create] set ::iShuffleErrors 0 +set ::commandFuncSuffix "Command" + +proc condition_command {cmd pp_expr} { + if {[regexp {^(!)?defined\(\s*(\w+)\s*\)} $pp_expr ma bang pp_var]} { + if {$bang eq "!"} { + set pp_expr "#ifndef $pp_var" + } else { + set pp_expr "#ifdef $pp_var" + } + } else { + set pp_expr "#if [string trim $pp_expr]" + } + dict set ::cmd_condition $cmd $pp_expr +} + +proc emit_conditionally {cmd lines ostrm} { + set wrapped [dict exists $::cmd_condition $cmd] + if {$wrapped} { + puts $ostrm [dict get $::cmd_condition $cmd] + } + puts $ostrm [join $lines "\n"] + if {$wrapped} { + puts $ostrm "#endif" + } +} # Convert list of help text lines into a dict. # Keys are the command names. Values are the help for the @@ -106,10 +129,35 @@ proc do_shuffle {hFile lx ostrm} { } incr iAte set ::cmd_help [dict merge $::cmd_help [chunkify_help $help_frag]] + } elseif {[regexp {^\s*DISPATCHABLE_COMMAND\(([\w\? ]+)\)(\S)\s*$} $lx ma args tc] + && $tc eq "\x7B"} { + set args [split [regsub {\s+} [string trim $args] " "]] + incr iAte + if {[llength $args] != 7} { + puts stderr "Bad args: $lx" + } else { + set body {} + while {![eof $hFile]} { + set lb [gets $hFile] + incr iAte + lappend body $lb + if {[regexp "^\x7D\\s*\$" $lb]} { break } + } + foreach {cmd cmdLen naMin naMax azA nA pSS} $args { + if {$cmdLen eq "?"} { + set cmdLen [string length $cmd] + } + set func "$cmd$::commandFuncSuffix" + set dispEntry " \x7B \"$cmd\", $func, $cmdLen, $naMin, $naMax \x7D," + set funcOpen "static int ${func}(char *$azA\[\], int $nA, ShellState *$pSS)\x7B" + emit_conditionally $cmd [linsert $body 0 $funcOpen] $ostrm + dict set ::cmd_dispatch $cmd [list $dispEntry] + } + } } elseif {[regexp {^\s*EMIT_HELP_TEXT\(\)} $lx]} { incr iAte foreach htc [lsort [dict keys $::cmd_help]] { - puts $ostrm [join [dict get $::cmd_help $htc] "\n"] + emit_conditionally $htc [dict get $::cmd_help $htc] $ostrm } } elseif {[regexp {^COLLECT_DISPATCH\(\s*(\w+)\s*\)\[} $lx ma cmd]} { incr iAte @@ -125,8 +173,11 @@ proc do_shuffle {hFile lx ostrm} { } elseif {[regexp {^\s*EMIT_DISPATCH\(\)} $lx]} { incr iAte foreach cmd [lsort [dict keys $::cmd_dispatch]] { - puts $ostrm [join [dict get $::cmd_dispatch $cmd] "\n"] + emit_conditionally $cmd [dict get $::cmd_dispatch $cmd] $ostrm } + } elseif {[regexp {^CONDITION_COMMAND\(\s*(\w+)\s+([^;]+)\);} $lx ma cmd pp_expr]} { + incr iAte + condition_command $cmd [string trim $pp_expr] } else { puts $ostrm $lx } @@ -181,4 +232,5 @@ while {1} { } close $in close $out + exit $::iShuffleErrors