]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Streamline most common command definition
authorlarrybr <larrybr@noemail.net>
Sun, 4 Jul 2021 22:38:20 +0000 (22:38 +0000)
committerlarrybr <larrybr@noemail.net>
Sun, 4 Jul 2021 22:38:20 +0000 (22:38 +0000)
FossilOrigin-Name: dd76b41a72aca94450fb6f45ff56af95d2adb9275eebe9ca67ebd04a52a63c33

manifest
manifest.uuid
src/shell.c.in
tool/mkshellc.tcl

index 5821ef2b6a24169870660c9740b6b25ac0502e4e..37b39890780747bcc0d16b3d93ec301faa83b21b 100644 (file)
--- 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
index f649a6ef7e2eeb4d43e24246f09806389e9a6023..7ee1d1065db39c7f18c334505cf3c42e55806f40 100644 (file)
@@ -1 +1 @@
-5e7e0d4ef8665e924f499238b1469a5fc06d24f6cf96864b502e62734d92e7ee
\ No newline at end of file
+dd76b41a72aca94450fb6f45ff56af95d2adb9275eebe9ca67ebd04a52a63c33
\ No newline at end of file
index 5fa089b49009c65857e4ba7943d12924c68e5686..fe5db11388e0922a83d777718035f9ffd19f34a8 100644 (file)
@@ -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; rc<nArg; ++rc)
+    raw_printf(p->out, "%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 */
 };
 
 /*
index 71ab09e3025a87b7c4cb8632110d880f868eee66..8ca4259ded162ba558c6b4d0846d76946a66f5e7 100644 (file)
@@ -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