]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Remove the ill-designed "-end" option from the command-line shell. Instead,
authordrh <drh@noemail.net>
Fri, 28 Nov 2014 13:35:03 +0000 (13:35 +0000)
committerdrh <drh@noemail.net>
Fri, 28 Nov 2014 13:35:03 +0000 (13:35 +0000)
allow multiple SQL or dot-commands as command-line arguments.  Any -cmd
commands are processed first, followed by other command-line arguments, for
backwards compatibility.

FossilOrigin-Name: 24fa2e9832daaa5d68ee28a00c56c55f97a4da9e

manifest
manifest.uuid
src/shell.c
test/shell1.test
test/shell2.test

index b2e178bb047f87884ce58c947ffbb79810cb34c1..527a5caae66d30a041b225c487ea8fe87826bcf8 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\sthe\s-end\soption\sto\sthe\scommand-line\sshell,\swhich\sforces\sit\sto\sexit\safter\nreading\sprior\scommand-line\soptions\s(presumably\sincluding\sone\sor\smore\s-cmd\noptions)\sand\swithout\sreading\sstandard\sinput.
-D 2014-11-28T11:54:44.417
+C Remove\sthe\sill-designed\s"-end"\soption\sfrom\sthe\scommand-line\sshell.\s\sInstead,\nallow\smultiple\sSQL\sor\sdot-commands\sas\scommand-line\sarguments.\s\sAny\s-cmd\ncommands\sare\sprocessed\sfirst,\sfollowed\sby\sother\scommand-line\sarguments,\sfor\nbackwards\scompatibility.
+D 2014-11-28T13:35:03.566
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in a226317fdf3f4c895fb3cfedc355b4d0868ce1fb
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -229,7 +229,7 @@ F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
 F src/resolve.c 4965007d6497b6a4d7a6d98751cc39712885f952
 F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
 F src/select.c 428165951748151e87a15295b7357221433e311b
-F src/shell.c f49ecad5afcae4c7fa2754a1446848582b105509
+F src/shell.c 45d9c9bd7cde07845af957f2d849933b990773cf
 F src/sqlite.h.in c63db0117aeb749ca02b6016dbbbccbbbd9a141d
 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
 F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
@@ -848,8 +848,8 @@ F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21
 F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
 F test/shared_err.test 2f2aee20db294b9924e81f6ccbe60f19e21e8506
 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
-F test/shell1.test d60946b5fde4d85fe06db7331dfe89011f564350
-F test/shell2.test c57da3a381c099b02c813ba156298d5c2f5c93a3
+F test/shell1.test ab6025d941f9c84c5b83412c6b4d8b57f78dfa3a
+F test/shell2.test 12b8bf901b0e3a8ac58cf5c0c63a0a388d4d1862
 F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29
 F test/shell4.test 8a9c08976291e6c6c808b4d718f4a8b299f339f5
 F test/shell5.test 15a419cc1df21c892ed64f5596ae7a501f2816f2
@@ -1223,7 +1223,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P f095cde579e7417306e11b5c1d2dd90b6bb547d5
-R 705c89a250127228fc15e4e2150ad4c0
+P b59397b1f1e32c478b5fa96659cd4300177d39f7
+R 1ff83ec33f372c19416fe00ba6e9161c
 U drh
-Z ed3d85af1529a8fcb757b6e7459b553e
+Z 816c9b1778ea4dbed9ea56de4b3769ca
index fa0366051778225e8f6d804ffd1e9fc53d3ddcaf..c82d09b6ab91d82a1cb35658b2f1a1afa1a74ca2 100644 (file)
@@ -1 +1 @@
-b59397b1f1e32c478b5fa96659cd4300177d39f7
\ No newline at end of file
+24fa2e9832daaa5d68ee28a00c56c55f97a4da9e
\ No newline at end of file
index 46b4c0f10fb18e6888c0443420724d9b59cf7b20..94d20d354929f2ba0776dcd030dcfed0687acaf2 100644 (file)
@@ -3944,7 +3944,6 @@ static const char zOptions[] =
   "   -cmd COMMAND         run \"COMMAND\" before reading stdin\n"
   "   -csv                 set output mode to 'csv'\n"
   "   -echo                print commands before execution\n"
-  "   -end                 Halt.  Useful after one or more -cmd\n"
   "   -init FILENAME       read/process named file\n"
   "   -[no]header          turn headers on or off\n"
 #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
@@ -4039,10 +4038,12 @@ int main(int argc, char **argv){
   char *zErrMsg = 0;
   ShellState data;
   const char *zInitFile = 0;
-  char *zFirstCmd = 0;
   int i;
   int rc = 0;
   int warnInmemoryDb = 0;
+  int readStdin = 1;
+  int nCmd = 0;
+  char **azCmd = 0;
 
 #if USE_SYSTEM_SQLITE+0!=1
   if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){
@@ -4062,6 +4063,18 @@ int main(int argc, char **argv){
   signal(SIGINT, interrupt_handler);
 #endif
 
+#ifdef SQLITE_SHELL_DBNAME_PROC
+  {
+    /* If the SQLITE_SHELL_DBNAME_PROC macro is defined, then it is the name
+    ** of a C-function that will provide the name of the database file.  Use
+    ** this compile-time option to embed this shell program in larger
+    ** applications. */
+    extern void SQLITE_SHELL_DBNAME_PROC(const char**);
+    SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
+    warnInmemoryDb = 0;
+  }
+#endif
+
   /* Do an initial pass through the command-line argument to locate
   ** the name of the database file, the name of the initialization file,
   ** the size of the alternative malloc heap,
@@ -4073,15 +4086,18 @@ int main(int argc, char **argv){
     if( z[0]!='-' ){
       if( data.zDbFilename==0 ){
         data.zDbFilename = z;
-        continue;
-      }
-      if( zFirstCmd==0 ){
-        zFirstCmd = z;
-        continue;
+      }else{
+        /* Excesss arguments are interpreted as SQL (or dot-commands) and
+        ** mean that nothing is read from stdin */
+        readStdin = 0;
+        nCmd++;
+        azCmd = realloc(azCmd, sizeof(azCmd[0])*nCmd);
+        if( azCmd==0 ){
+          fprintf(stderr, "out of memory\n");
+          exit(1);
+        }
+        azCmd[nCmd-1] = z;
       }
-      fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
-      fprintf(stderr,"Use -help for a list of options.\n");
-      return 1;
     }
     if( z[1]=='-' ) z++;
     if( strcmp(z,"-separator")==0
@@ -4171,11 +4187,6 @@ int main(int argc, char **argv){
 #else
     fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
     return 1;
-#endif
-#ifdef SQLITE_SHELL_DBNAME_PROC
-    { extern void SQLITE_SHELL_DBNAME_PROC(const char**);
-      SQLITE_SHELL_DBNAME_PROC(&data.zDbFilename);
-      warnInmemoryDb = 0; }
 #endif
   }
   data.out = stdout;
@@ -4273,6 +4284,10 @@ int main(int argc, char **argv){
     }else if( strcmp(z,"-help")==0 ){
       usage(1);
     }else if( strcmp(z,"-cmd")==0 ){
+      /* Run commands that follow -cmd first and separately from commands
+      ** that simply appear on the command-line.  This seems goofy.  It would
+      ** be better if all commands ran in the order that they appear.  But
+      ** we retain the goofy behavior for historical compatibility. */
       if( i==argc-1 ) break;
       z = cmdline_option_value(argc,argv,++i);
       if( z[0]=='.' ){
@@ -4289,8 +4304,6 @@ int main(int argc, char **argv){
           if( bail_on_error ) return rc;
         }
       }
-    }else if( strcmp(z, "-end")==0 ){
-      return 0;
     }else{
       fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
       fprintf(stderr,"Use -help for a list of options.\n");
@@ -4298,23 +4311,28 @@ int main(int argc, char **argv){
     }
   }
 
-  if( zFirstCmd ){
-    /* Run just the command that follows the database name
+  if( !readStdin ){
+    /* Run all arguments that do not begin with '-' as if they were separate
+    ** command-line inputs, except for the argToSkip argument which contains
+    ** the database filename.
     */
-    if( zFirstCmd[0]=='.' ){
-      rc = do_meta_command(zFirstCmd, &data);
-      if( rc==2 ) rc = 0;
-    }else{
-      open_db(&data, 0);
-      rc = shell_exec(data.db, zFirstCmd, shell_callback, &data, &zErrMsg);
-      if( zErrMsg!=0 ){
-        fprintf(stderr,"Error: %s\n", zErrMsg);
-        return rc!=0 ? rc : 1;
-      }else if( rc!=0 ){
-        fprintf(stderr,"Error: unable to process SQL \"%s\"\n", zFirstCmd);
-        return rc;
+    for(i=0; i<nCmd; i++){
+      if( azCmd[i][0]=='.' ){
+        rc = do_meta_command(azCmd[i], &data);
+        if( rc ) return rc==2 ? 0 : rc;
+      }else{
+        open_db(&data, 0);
+        rc = shell_exec(data.db, azCmd[i], shell_callback, &data, &zErrMsg);
+        if( zErrMsg!=0 ){
+          fprintf(stderr,"Error: %s\n", zErrMsg);
+          return rc!=0 ? rc : 1;
+        }else if( rc!=0 ){
+          fprintf(stderr,"Error: unable to process SQL: %s\n", azCmd[i]);
+          return rc;
+        }
       }
     }
+    free(azCmd);
   }else{
     /* Run commands received from standard input
     */
index ab382e74cbe052807a24606e67291781e2a36f97..27bbe872596574686fafdf1b1686465b53028d54 100644 (file)
@@ -45,20 +45,21 @@ do_test shell1-1.1.1 {
   list $rc \
        [regexp {Error: unknown option: -bad} $res]
 } {1 1}
-# error on extra options
-do_test shell1-1.1.2 {
-  set res [catchcmd "-bad test.db \"select 3\" \"select 4\"" ""]
+do_test shell1-1.1.1b {
+  set res [catchcmd "test.db -bad" ""]
   set rc [lindex $res 0]
   list $rc \
-       [regexp {Error: too many options: "select 4"} $res]
+       [regexp {Error: unknown option: -bad} $res]
 } {1 1}
 # error on extra options
+do_test shell1-1.1.2 {
+  catchcmd "test.db \"select 3\" \"select 4\"" ""
+} {0 {3
+4}}
+# error on extra options
 do_test shell1-1.1.3 {
-  set res [catchcmd "-bad FOO test.db BAD" ".quit"]
-  set rc [lindex $res 0]
-  list $rc \
-       [regexp {Error: too many options: "BAD"} $res]
-} {1 1}
+  catchcmd "test.db FOO test.db BAD" ".quit"
+} {1 {Error: near "FOO": syntax error}}
 
 # -help
 do_test shell1-1.2.1 {
@@ -75,11 +76,11 @@ do_test shell1-1.3.1 {
   catchcmd "-init FOO test.db" ""
 } {0 {}}
 do_test shell1-1.3.2 {
-  set res [catchcmd "-init FOO test.db .quit BAD" ""]
-  set rc [lindex $res 0]
-  list $rc \
-       [regexp {Error: too many options: "BAD"} $res]
-} {1 1}
+  catchcmd "-init FOO test.db .quit BAD" ""
+} {0 {}}
+do_test shell1-1.3.3 {
+  catchcmd "-init FOO test.db BAD .quit" ""
+} {1 {Error: near "BAD": syntax error}}
 
 # -echo                print commands before execution
 do_test shell1-1.4.1 {
index def574c76c16d82c405aaead3e9a3adbe2505f42..616610bd4ba2f88c8ecdefc2a34f9e25d023312b 100644 (file)
@@ -52,9 +52,9 @@ do_test shell2-1.1.1 {
 # Ticket [f5cb008a65].
 do_test shell2-1.2.1 {
   set rc [catch { eval exec $CLI \":memory:\" \"select 3\" \"select 4\" } msg]
-  list $rc \
-       [regexp {Error: too many options: "select 4"} $msg]
-} {1 1}
+  list $rc $msg
+} {0 {3
+4}}
 
 # Test a problem reported on the mailing list. The shell was at one point
 # returning the generic SQLITE_ERROR message ("SQL error or missing database")