]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improvements to error messages for errors in the dot-commands of the
authordrh <drh@noemail.net>
Thu, 29 May 2014 12:36:14 +0000 (12:36 +0000)
committerdrh <drh@noemail.net>
Thu, 29 May 2014 12:36:14 +0000 (12:36 +0000)
command-line shell.  Add the ".once" command.  The output of ".help"
now goes to the designated output channel.

FossilOrigin-Name: 48dce821a07ac29da6ce05e92cf3f6e52b6eb388

manifest
manifest.uuid
src/shell.c
test/shell1.test
test/shell4.test
test/shell5.test

index 0d3e2478c41aa235254b262e45044b80cd4968ca..fb3c92c2cf7300d7660219f6121841f57017cbd7 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Only\squote\sthe\sarguments\sto\sthe\s".shell"\sand\s".system"\scommands\sif\sthey\ncontain\sspaces.
-D 2014-05-29T03:17:29.412
+C Improvements\sto\serror\smessages\sfor\serrors\sin\sthe\sdot-commands\sof\sthe\ncommand-line\sshell.\s\sAdd\sthe\s".once"\scommand.\s\sThe\soutput\sof\s".help"\nnow\sgoes\sto\sthe\sdesignated\soutput\schannel.
+D 2014-05-29T12:36:14.908
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in dd2b1aba364ff9b05de41086f74407f285c57670
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -221,7 +221,7 @@ F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
 F src/resolve.c 273d5f47c4e2c05b2d3d2bffeda939551ab59e66
 F src/rowset.c a9c9aae3234b44a6d7c6f5a3cadf90dce1e627be
 F src/select.c 7df17ec5506c2427576d412bee0e6ea740e12563
-F src/shell.c f389c2bcae6192daad01b46169e63538456427fa
+F src/shell.c a94689054bc0a66608f3d75b3ced2b886c3d7f50
 F src/sqlite.h.in 564fc23db33870b5096b20d72df7491ce0b8b74f
 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
@@ -813,11 +813,11 @@ F test/shared9.test 5f2a8f79b4d6c7d107a01ffa1ed05ae7e6333e21
 F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
 F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa
 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
-F test/shell1.test f2a1d471e5cd2b42f7a65b166dc1ace2b8d11583
+F test/shell1.test fb080d67c81e8a80a79ea04b36f127209b5bd112
 F test/shell2.test c57da3a381c099b02c813ba156298d5c2f5c93a3
 F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29
-F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9
-F test/shell5.test fa5583230c0aea5c9ff33f0ac1e26b1e3f03d153
+F test/shell4.test 8a9c08976291e6c6c808b4d718f4a8b299f339f5
+F test/shell5.test 6b1a53c49a4ff5c3bd0bad17a85ecba505608278
 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
 F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
@@ -1173,7 +1173,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 d018a34a05cec6adda61ed225d084c587343f2a6
-R c32df26ea35dc6668db5bcd28814662e
+P e58f4bd39d51c4c1a28684dab6427de81173d564
+R 7215154feb44506111be05bd24ee86a7
 U drh
-Z a04310abc4a1ec4cc8144d03b2ee32a5
+Z cfc4096d1968e16f0aae201a0082ea68
index 944a28888f956ff59ea9822488eeeaee8c863b4a..9fb4a9df391ff114237be767d438c2e55e689b9f 100644 (file)
@@ -1 +1 @@
-e58f4bd39d51c4c1a28684dab6427de81173d564
\ No newline at end of file
+48dce821a07ac29da6ce05e92cf3f6e52b6eb388
\ No newline at end of file
index f51ce9a1647750ab8555c623d1f8d7c918ae9c3e..e2748911e66ab3cd43d7f869c1edb96a57a82d93 100644 (file)
@@ -446,8 +446,9 @@ struct previous_mode_data {
 struct callback_data {
   sqlite3 *db;           /* The database */
   int echoOn;            /* True to echo input commands */
-  int autoEQP;           /* Run EXPLAIN QUERY PLAN prior to seach SQL statement */
+  int autoEQP;           /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
   int statsOn;           /* True to display memory stats before each finalize */
+  int outCount;          /* Revert to stdout when reaching zero */
   int cnt;               /* Number of records displayed so far */
   FILE *out;             /* Write results here */
   FILE *traceOut;        /* Output for sqlite3_trace() */
@@ -878,7 +879,8 @@ static int shell_callback(void *pArg, int nArg, char **azArg, char **azCol, int
         }else if( aiType && aiType[i]==SQLITE_TEXT ){
           if( zSep[0] ) fprintf(p->out,"%s",zSep);
           output_quoted_string(p->out, azArg[i]);
-        }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
+        }else if( aiType && (aiType[i]==SQLITE_INTEGER
+                             || aiType[i]==SQLITE_FLOAT) ){
           fprintf(p->out,"%s%s",zSep, azArg[i]);
         }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
           const void *pBlob = sqlite3_column_blob(p->pStmt, i);
@@ -1570,17 +1572,17 @@ static int run_schema_dump_query(
 */
 static char zHelp[] =
   ".backup ?DB? FILE      Backup DB (default \"main\") to FILE\n"
-  ".bail ON|OFF           Stop after hitting an error.  Default OFF\n"
+  ".bail on|off           Stop after hitting an error.  Default OFF\n"
   ".clone NEWDB           Clone data into NEWDB from the existing database\n"
   ".databases             List names and files of attached databases\n"
   ".dump ?TABLE? ...      Dump the database in an SQL text format\n"
   "                         If TABLE specified, only dump tables matching\n"
   "                         LIKE pattern TABLE.\n"
-  ".echo ON|OFF           Turn command echo on or off\n"
+  ".echo on|off           Turn command echo on or off\n"
   ".exit                  Exit this program\n"
-  ".explain ?ON|OFF?      Turn output mode suitable for EXPLAIN on or off.\n"
+  ".explain ?on|off?      Turn output mode suitable for EXPLAIN on or off.\n"
   "                         With no args, it turns EXPLAIN on.\n"
-  ".headers ON|OFF        Turn display of headers on or off\n"
+  ".headers on|off        Turn display of headers on or off\n"
   ".help                  Show this message\n"
   ".import FILE TABLE     Import data from FILE into TABLE\n"
   ".indices ?TABLE?       Show names of all indices\n"
@@ -1603,9 +1605,9 @@ static char zHelp[] =
   "                         tabs     Tab-separated values\n"
   "                         tcl      TCL list elements\n"
   ".nullvalue STRING      Use STRING in place of NULL values\n"
+  ".once FILENAME         Output for the next SQL command only to FILENAME\n"
   ".open ?FILENAME?       Close existing database and reopen FILENAME\n"
-  ".output FILENAME       Send output to FILENAME\n"
-  ".output stdout         Send output to the screen\n"
+  ".output ?FILENAME?     Send output to FILENAME or stdout\n"
   ".print STRING...       Print literal STRING\n"
   ".prompt MAIN CONTINUE  Replace the standard prompts\n"
   ".quit                  Exit this program\n"
@@ -1618,22 +1620,19 @@ static char zHelp[] =
   ".separator STRING      Change separator used by output mode and .import\n"
   ".shell CMD ARGS...     Run CMD ARGS... in a system shell\n"
   ".show                  Show the current values for various settings\n"
-  ".stats ON|OFF          Turn stats on or off\n"
+  ".stats on|off          Turn stats on or off\n"
   ".system CMD ARGS...    Run CMD ARGS... in a system shell\n"
   ".tables ?TABLE?        List names of tables\n"
   "                         If TABLE specified, only list tables matching\n"
   "                         LIKE pattern TABLE.\n"
   ".timeout MS            Try opening locked tables for MS milliseconds\n"
+  ".timer on|off          Turn SQL timer on or off\n"
   ".trace FILE|off        Output each SQL statement as it is run\n"
   ".vfsname ?AUX?         Print the name of the VFS stack\n"
   ".width NUM1 NUM2 ...   Set column widths for \"column\" mode\n"
   "                         Negative values right-justify\n"
 ;
 
-static char zTimerHelp[] =
-  ".timer ON|OFF          Turn the CPU timer measurement on or off\n"
-;
-
 /* Forward reference */
 static int process_input(struct callback_data *p, FILE *in);
 
@@ -1675,6 +1674,7 @@ static void open_db(struct callback_data *p, int keepAlive){
 static void resolve_backslashes(char *z){
   int i, j;
   char c;
+  while( *z && *z!='\\' ) z++;
   for(i=j=0; (c = z[i])!=0; i++, j++){
     if( c=='\\' ){
       c = z[++i];
@@ -1700,7 +1700,7 @@ static void resolve_backslashes(char *z){
     }
     z[j] = c;
   }
-  z[j] = 0;
+  if( j<i ) z[j] = 0;
 }
 
 /*
@@ -2144,6 +2144,19 @@ static void tryToClone(struct callback_data *p, const char *zNewDb){
   sqlite3_close(newDb);
 }
 
+/*
+** Change the output file back to stdout
+*/
+static void output_reset(struct callback_data *p){
+  if( p->outfile[0]=='|' ){
+    pclose(p->out);
+  }else{
+    output_file_close(p->out);
+  }
+  p->outfile[0] = 0;
+  p->out = stdout;
+}
+
 /*
 ** If an input line begins with "." then invoke this routine to
 ** process that line.
@@ -2242,8 +2255,13 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     sqlite3_close(pDest);
   }else
 
-  if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 && nArg>1 && nArg<3 ){
-    bail_on_error = booleanValue(azArg[1]);
+  if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
+    if( nArg==2 ){
+      bail_on_error = booleanValue(azArg[1]);
+    }else{
+      fprintf(stderr, "Usage: .bail on|off\n");
+      rc = 1;
+    }
   }else
 
   /* The undocumented ".breakpoint" command causes a call to the no-op
@@ -2253,11 +2271,16 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     test_breakpoint();
   }else
 
-  if( c=='c' && strncmp(azArg[0], "clone", n)==0 && nArg>1 && nArg<3 ){
-    tryToClone(p, azArg[1]);
+  if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
+    if( nArg==2 ){
+      tryToClone(p, azArg[1]);
+    }else{
+      fprintf(stderr, "Usage: .clone FILENAME\n");
+      rc = 1;
+    }
   }else
 
-  if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 && nArg==1 ){
+  if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
     struct callback_data data;
     char *zErrMsg = 0;
     open_db(p, 0);
@@ -2276,11 +2299,16 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     }
   }else
 
-  if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
+  if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
     open_db(p, 0);
     /* When playing back a "dump", the content might appear in an order
     ** which causes immediate foreign key constraints to be violated.
     ** So disable foreign-key constraint enforcement to prevent problems. */
+    if( nArg!=1 && nArg!=2 ){
+      fprintf(stderr, "Usage: .dump ?LIKE-PATTERN?\n");
+      rc = 1;
+      goto meta_command_exit;
+    }
     fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
     fprintf(p->out, "BEGIN TRANSACTION;\n");
     p->writableSchema = 0;
@@ -2325,12 +2353,22 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
   }else
 
-  if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
-    p->echoOn = booleanValue(azArg[1]);
+  if( c=='e' && strncmp(azArg[0], "echo", n)==0 ){
+    if( nArg==2 ){
+      p->echoOn = booleanValue(azArg[1]);
+    }else{
+      fprintf(stderr, "Usage: .echo on|off\n");
+      rc = 1;
+    }
   }else
 
-  if( c=='e' && strncmp(azArg[0], "eqp", n)==0 && nArg>1 && nArg<3 ){
-    p->autoEQP = booleanValue(azArg[1]);
+  if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
+    if( nArg==2 ){
+      p->autoEQP = booleanValue(azArg[1]);
+    }else{
+      fprintf(stderr, "Usage: .eqp on|off\n");
+      rc = 1;
+    }   
   }else
 
   if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
@@ -2338,7 +2376,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     rc = 2;
   }else
 
-  if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
+  if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
     int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
     if(val == 1) {
       if(!p->explainPrev.valid) {
@@ -2373,19 +2411,20 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     }
   }else
 
-  if( c=='h' && (strncmp(azArg[0], "header", n)==0 ||
-                 strncmp(azArg[0], "headers", n)==0) && nArg>1 && nArg<3 ){
-    p->showHeader = booleanValue(azArg[1]);
+  if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
+    if( nArg==2 ){
+      p->showHeader = booleanValue(azArg[1]);
+    }else{
+      fprintf(stderr, "Usage: .headers on|off\n");
+      rc = 1;
+    }
   }else
 
   if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
-    fprintf(stderr,"%s",zHelp);
-    if( HAS_TIMER ){
-      fprintf(stderr,"%s",zTimerHelp);
-    }
+    fprintf(p->out, "%s", zHelp);
   }else
 
-  if( c=='i' && strncmp(azArg[0], "import", n)==0 && nArg==3 ){
+  if( c=='i' && strncmp(azArg[0], "import", n)==0 ){
     char *zTable = azArg[2];    /* Insert data into this table */
     char *zFile = azArg[1];     /* Name of file to extra content from */
     sqlite3_stmt *pStmt = NULL; /* A statement */
@@ -2398,6 +2437,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     CSVReader sCsv;             /* Reader context */
     int (*xCloser)(FILE*);      /* Procedure to close th3 connection */
 
+    if( nArg!=3 ){
+      fprintf(stderr, "Usage: .import FILE TABLE\n");
+      goto meta_command_exit;
+    }
     seenInterrupt = 0;
     memset(&sCsv, 0, sizeof(sCsv));
     open_db(p, 0);
@@ -2536,7 +2579,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     if( needCommit ) sqlite3_exec(db, "COMMIT", 0, 0, 0);
   }else
 
-  if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg<3 ){
+  if( c=='i' && strncmp(azArg[0], "indices", n)==0 ){
     struct callback_data data;
     char *zErrMsg = 0;
     open_db(p, 0);
@@ -2553,7 +2596,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
         "ORDER BY 1",
         callback, &data, &zErrMsg
       );
-    }else{
+    }else if( nArg==2 ){
       zShellStatic = azArg[1];
       rc = sqlite3_exec(p->db,
         "SELECT name FROM sqlite_master "
@@ -2565,6 +2608,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){
         callback, &data, &zErrMsg
       );
       zShellStatic = 0;
+    }else{
+      fprintf(stderr, "Usage: .indices ?LIKE-PATTERN?\n");
+      rc = 1;
+      goto meta_command_exit;
     }
     if( zErrMsg ){
       fprintf(stderr,"Error: %s\n", zErrMsg);
@@ -2600,9 +2647,14 @@ static int do_meta_command(char *zLine, struct callback_data *p){
 #endif
 
 #ifndef SQLITE_OMIT_LOAD_EXTENSION
-  if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
+  if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
     const char *zFile, *zProc;
     char *zErrMsg = 0;
+    if( nArg<2 ){
+      fprintf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
+      rc = 1;
+      goto meta_command_exit;
+    }
     zFile = azArg[1];
     zProc = nArg>=3 ? azArg[2] : 0;
     open_db(p, 0);
@@ -2615,38 +2667,41 @@ static int do_meta_command(char *zLine, struct callback_data *p){
   }else
 #endif
 
-  if( c=='l' && strncmp(azArg[0], "log", n)==0 && nArg>=2 ){
-    const char *zFile = azArg[1];
-    output_file_close(p->pLog);
-    p->pLog = output_file_open(zFile);
+  if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
+    if( nArg!=2 ){
+      fprintf(stderr, "Usage: .log FILENAME\n");
+      rc = 1;
+    }else{
+      const char *zFile = azArg[1];
+      output_file_close(p->pLog);
+      p->pLog = output_file_open(zFile);
+    }
   }else
 
-  if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==2 ){
-    int n2 = strlen30(azArg[1]);
-    if( (n2==4 && strncmp(azArg[1],"line",n2)==0)
-        ||
-        (n2==5 && strncmp(azArg[1],"lines",n2)==0) ){
+  if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
+    const char *zMode = nArg>=2 ? azArg[1] : "";
+    int n2 = (int)strlen(zMode);
+    int c2 = zMode[0];
+    if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
       p->mode = MODE_Line;
-    }else if( (n2==6 && strncmp(azArg[1],"column",n2)==0)
-              ||
-              (n2==7 && strncmp(azArg[1],"columns",n2)==0) ){
+    }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
       p->mode = MODE_Column;
-    }else if( n2==4 && strncmp(azArg[1],"list",n2)==0 ){
+    }else if( c2=='l' && n2>2 && strncmp(azArg[1],"list",n2)==0 ){
       p->mode = MODE_List;
-    }else if( n2==4 && strncmp(azArg[1],"html",n2)==0 ){
+    }else if( c2=='h' && strncmp(azArg[1],"html",n2)==0 ){
       p->mode = MODE_Html;
-    }else if( n2==3 && strncmp(azArg[1],"tcl",n2)==0 ){
+    }else if( c2=='t' && strncmp(azArg[1],"tcl",n2)==0 ){
       p->mode = MODE_Tcl;
       sqlite3_snprintf(sizeof(p->separator), p->separator, " ");
-    }else if( n2==3 && strncmp(azArg[1],"csv",n2)==0 ){
+    }else if( c2=='c' && strncmp(azArg[1],"csv",n2)==0 ){
       p->mode = MODE_Csv;
       sqlite3_snprintf(sizeof(p->separator), p->separator, ",");
-    }else if( n2==4 && strncmp(azArg[1],"tabs",n2)==0 ){
+    }else if( c2=='t' && strncmp(azArg[1],"tabs",n2)==0 ){
       p->mode = MODE_List;
       sqlite3_snprintf(sizeof(p->separator), p->separator, "\t");
-    }else if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
+    }else if( c2=='i' && strncmp(azArg[1],"insert",n2)==0 ){
       p->mode = MODE_Insert;
-      set_table_name(p, "table");
+      set_table_name(p, nArg>=3 ? azArg[2] : "table");
     }else {
       fprintf(stderr,"Error: mode should be one of: "
          "column csv html insert line list tabs tcl\n");
@@ -2654,23 +2709,16 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     }
   }else
 
-  if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg==3 ){
-    int n2 = strlen30(azArg[1]);
-    if( n2==6 && strncmp(azArg[1],"insert",n2)==0 ){
-      p->mode = MODE_Insert;
-      set_table_name(p, azArg[2]);
-    }else {
-      fprintf(stderr, "Error: invalid arguments: "
-        " \"%s\". Enter \".help\" for help\n", azArg[2]);
+  if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
+    if( nArg==2 ){
+      sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
+                       "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
+    }else{
+      fprintf(stderr, "Usage: .nullvalue STRING\n");
       rc = 1;
     }
   }else
 
-  if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
-    sqlite3_snprintf(sizeof(p->nullvalue), p->nullvalue,
-                     "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
-  }else
-
   if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
     sqlite3 *savedDb = p->db;
     const char *zSavedFilename = p->zDbFilename;
@@ -2691,32 +2739,45 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     }
   }else
 
-  if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
-    if( p->outfile[0]=='|' ){
-      pclose(p->out);
+  if( c=='o'
+   && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
+  ){
+    const char *zFile = nArg>=2 ? azArg[1] : "stdout";
+    if( nArg>2 ){
+      fprintf(stderr, "Usage: .%s FILE\n", azArg[0]);
+      rc = 1;
+      goto meta_command_exit;
+    }
+    if( n>1 && strncmp(azArg[0], "once", n)==0 ){
+      if( nArg<2 ){
+        fprintf(stderr, "Usage: .once FILE\n");
+        rc = 1;
+        goto meta_command_exit;
+      }
+      p->outCount = 2;
     }else{
-      output_file_close(p->out);
+      p->outCount = 0;
     }
-    p->outfile[0] = 0;
-    if( azArg[1][0]=='|' ){
-      p->out = popen(&azArg[1][1], "w");
+    output_reset(p);
+    if( zFile[0]=='|' ){
+      p->out = popen(zFile + 1, "w");
       if( p->out==0 ){
-        fprintf(stderr,"Error: cannot open pipe \"%s\"\n", &azArg[1][1]);
+        fprintf(stderr,"Error: cannot open pipe \"%s\"\n", zFile + 1);
         p->out = stdout;
         rc = 1;
       }else{
-        sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
+        sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
       }
     }else{
-      p->out = output_file_open(azArg[1]);
+      p->out = output_file_open(zFile);
       if( p->out==0 ){
-        if( strcmp(azArg[1],"off")!=0 ){
-          fprintf(stderr,"Error: cannot write to \"%s\"\n", azArg[1]);
+        if( strcmp(zFile,"off")!=0 ){
+          fprintf(stderr,"Error: cannot write to \"%s\"\n", zFile);
         }
         p->out = stdout;
         rc = 1;
       } else {
-        sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", azArg[1]);
+        sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
       }
     }
   }else
@@ -2730,7 +2791,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     fprintf(p->out, "\n");
   }else
 
-  if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
+  if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
     if( nArg >= 2) {
       strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
     }
@@ -2739,12 +2800,18 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     }
   }else
 
-  if( c=='q' && strncmp(azArg[0], "quit", n)==0 && nArg==1 ){
+  if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
     rc = 2;
   }else
 
-  if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
-    FILE *alt = fopen(azArg[1], "rb");
+  if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
+    FILE *alt;
+    if( nArg!=2 ){
+      fprintf(stderr, "Usage: .read FILE\n");
+      rc = 1;
+      goto meta_command_exit;
+    }
+    alt = fopen(azArg[1], "rb");
     if( alt==0 ){
       fprintf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
       rc = 1;
@@ -2754,7 +2821,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     }
   }else
 
-  if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 && nArg>1 && nArg<4){
+  if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
     const char *zSrcFile;
     const char *zDb;
     sqlite3 *pSrc;
@@ -2764,9 +2831,13 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     if( nArg==2 ){
       zSrcFile = azArg[1];
       zDb = "main";
-    }else{
+    }else if( nArg==3 ){
       zSrcFile = azArg[2];
       zDb = azArg[1];
+    }else{
+      fprintf(stderr, "Usage: .restore ?DB? FILE\n");
+      rc = 1;
+      goto meta_command_exit;
     }
     rc = sqlite3_open(zSrcFile, &pSrc);
     if( rc!=SQLITE_OK ){
@@ -2801,14 +2872,14 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     sqlite3_close(pSrc);
   }else
 
-  if( c=='s' && strncmp(azArg[0], "schema", n)==0 && nArg<3 ){
+  if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
     struct callback_data data;
     char *zErrMsg = 0;
     open_db(p, 0);
     memcpy(&data, p, sizeof(data));
     data.showHeader = 0;
     data.mode = MODE_Semi;
-    if( nArg>1 ){
+    if( nArg==2 ){
       int i;
       for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
       if( strcmp(azArg[1],"sqlite_master")==0 ){
@@ -2852,7 +2923,7 @@ static int do_meta_command(char *zLine, struct callback_data *p){
           callback, &data, &zErrMsg);
         zShellStatic = 0;
       }
-    }else{
+    }else if( nArg==1 ){
       rc = sqlite3_exec(p->db,
          "SELECT sql FROM "
          "  (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
@@ -2862,6 +2933,10 @@ static int do_meta_command(char *zLine, struct callback_data *p){
          "ORDER BY rowid",
          callback, &data, &zErrMsg
       );
+    }else{
+      fprintf(stderr, "Usage: .schema ?LIKE-PATTERN?\n");
+      rc = 1;
+      goto meta_command_exit;
     }
     if( zErrMsg ){
       fprintf(stderr,"Error: %s\n", zErrMsg);
@@ -2891,24 +2966,33 @@ static int do_meta_command(char *zLine, struct callback_data *p){
       for(i=1; i<nArg; i++){
         char zBuf[200];
         v = integerValue(azArg[i]);
-        sqlite3_snprintf(sizeof(zBuf), zBuf, "%s: %lld 0x%llx\n", azArg[i], v, v);
+        sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
         fprintf(p->out, "%s", zBuf);
       }
     }
   }else
 #endif
 
-  if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
-    sqlite3_snprintf(sizeof(p->separator), p->separator,
-                     "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
+  if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
+    if( nArg==2 ){
+      sqlite3_snprintf(sizeof(p->separator), p->separator,
+                       "%.*s", (int)sizeof(p->separator)-1, azArg[1]);
+    }else{
+      fprintf(stderr, "Usage: .separator STRING\n");
+      rc = 1;
+    }
   }else
 
   if( c=='s'
    && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
-   && nArg>=2
   ){
     char *zCmd;
     int i;
+    if( nArg<2 ){
+      fprintf(stderr, "Usage: .system COMMAND\n");
+      rc = 1;
+      goto meta_command_exit;
+    }
     zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
     for(i=2; i<nArg; i++){
       zCmd = sqlite3_mprintf(strchr(azArg[i],' ')==0?"%z %s":"%z \"%s\"",
@@ -2918,8 +3002,13 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     sqlite3_free(zCmd);
   }else
 
-  if( c=='s' && strncmp(azArg[0], "show", n)==0 && nArg==1 ){
+  if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
     int i;
+    if( nArg!=1 ){
+      fprintf(stderr, "Usage: .show\n");
+      rc = 1;
+      goto meta_command_exit;
+    }
     fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
     fprintf(p->out,"%9.9s: %s\n","eqp", p->autoEQP ? "on" : "off");
     fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
@@ -2941,11 +3030,16 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     fprintf(p->out,"\n");
   }else
 
-  if( c=='s' && strncmp(azArg[0], "stats", n)==0 && nArg>1 && nArg<3 ){
-    p->statsOn = booleanValue(azArg[1]);
+  if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
+    if( nArg==2 ){
+      p->statsOn = booleanValue(azArg[1]);
+    }else{
+      fprintf(stderr, "Usage: .stats on|off\n");
+      rc = 1;
+    }
   }else
 
-  if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 && nArg<3 ){
+  if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
     sqlite3_stmt *pStmt;
     char **azResult;
     int nRow, nAlloc;
@@ -3151,20 +3245,32 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     }
   }else
 
-  if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 && nArg==2 ){
+  if( c=='t' && n>4 && strncmp(azArg[0], "timeout", n)==0 ){
     open_db(p, 0);
-    sqlite3_busy_timeout(p->db, (int)integerValue(azArg[1]));
+    sqlite3_busy_timeout(p->db, nArg>=2 ? (int)integerValue(azArg[1]) : 0);
   }else
     
-  if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
-   && nArg==2
-  ){
-    enableTimer = booleanValue(azArg[1]);
+  if( c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 ){
+    if( nArg==2 ){
+      enableTimer = booleanValue(azArg[1]);
+      if( enableTimer && !HAS_TIMER ){
+        fprintf(stderr, "Error: timer not available on this system.\n");
+        enableTimer = 0;
+      }
+    }else{
+      fprintf(stderr, "Usage: .timer on|off\n");
+      rc = 1;
+    }
   }else
   
-  if( c=='t' && strncmp(azArg[0], "trace", n)==0 && nArg>1 ){
+  if( c=='t' && strncmp(azArg[0], "trace", n)==0 ){
     open_db(p, 0);
     output_file_close(p->traceOut);
+    if( nArg!=2 ){
+      fprintf(stderr, "Usage: .trace FILE|off\n");
+      rc = 1;
+      goto meta_command_exit;
+    }
     p->traceOut = output_file_open(azArg[1]);
 #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
     if( p->traceOut==0 ){
@@ -3195,11 +3301,11 @@ static int do_meta_command(char *zLine, struct callback_data *p){
 #if defined(SQLITE_DEBUG) && defined(SQLITE_ENABLE_WHERETRACE)
   if( c=='w' && strncmp(azArg[0], "wheretrace", n)==0 ){
     extern int sqlite3WhereTrace;
-    sqlite3WhereTrace = booleanValue(azArg[1]);
+    sqlite3WhereTrace = nArg>=2 ? booleanValue(azArg[1]) : 0xff;
   }else
 #endif
 
-  if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
+  if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
     int j;
     assert( nArg<=ArraySize(azArg) );
     for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
@@ -3213,6 +3319,11 @@ static int do_meta_command(char *zLine, struct callback_data *p){
     rc = 1;
   }
 
+meta_command_exit:
+  if( p->outCount ){
+    p->outCount--;
+    if( p->outCount==0 ) output_reset(p);
+  }
   return rc;
 }
 
@@ -3380,6 +3491,10 @@ static int process_input(struct callback_data *p, FILE *in){
         errCnt++;
       }
       nSql = 0;
+      if( p->outCount ){
+        output_reset(p);
+        p->outCount = 0;
+      }
     }else if( nSql && _all_whitespace(zSql) ){
       if( p->echoOn ) printf("%s\n", zSql);
       nSql = 0;
index 6ea4f4a82c498304576b56b08d14b8b1044d47e4..e6fb0c28d26c0107ae155384f942c5df843eba1b 100644 (file)
@@ -268,7 +268,7 @@ do_test shell1-3.1.4 {
 # .bail ON|OFF           Stop after hitting an error.  Default OFF
 do_test shell1-3.2.1 {
   catchcmd "test.db" ".bail"
-} {1 {Error: unknown command or invalid arguments:  "bail". Enter ".help" for help}}
+} {1 {Usage: .bail on|off}}
 do_test shell1-3.2.2 {
   catchcmd "test.db" ".bail ON"
 } {0 {}}
@@ -278,16 +278,16 @@ do_test shell1-3.2.3 {
 do_test shell1-3.2.4 {
   # too many arguments
   catchcmd "test.db" ".bail OFF BAD"
-} {1 {Error: unknown command or invalid arguments:  "bail". Enter ".help" for help}}
+} {1 {Usage: .bail on|off}}
 
 # .databases             List names and files of attached databases
 do_test shell1-3.3.1 {
   catchcmd "-csv test.db" ".databases"
 } "/0 +.*main +[string map {/ .} [string range [get_pwd] 0 10]].*/"
 do_test shell1-3.3.2 {
-  # too many arguments
+  # extra arguments ignored
   catchcmd "test.db" ".databases BAD"
-} {1 {Error: unknown command or invalid arguments:  "databases". Enter ".help" for help}}
+} "/0 +.*main +[string map {/ .} [string range [get_pwd] 0 10]].*/"
 
 # .dump ?TABLE? ...      Dump the database in an SQL text format
 #                          If TABLE specified, only dump tables matching
@@ -305,12 +305,12 @@ do_test shell1-3.4.2 {
 do_test shell1-3.4.3 {
   # too many arguments
   catchcmd "test.db" ".dump FOO BAD"
-} {1 {Error: unknown command or invalid arguments:  "dump". Enter ".help" for help}}
+} {1 {Usage: .dump ?LIKE-PATTERN?}}
 
 # .echo ON|OFF           Turn command echo on or off
 do_test shell1-3.5.1 {
   catchcmd "test.db" ".echo"
-} {1 {Error: unknown command or invalid arguments:  "echo". Enter ".help" for help}}
+} {1 {Usage: .echo on|off}}
 do_test shell1-3.5.2 {
   catchcmd "test.db" ".echo ON"
 } {0 {}}
@@ -320,7 +320,7 @@ do_test shell1-3.5.3 {
 do_test shell1-3.5.4 {
   # too many arguments
   catchcmd "test.db" ".echo OFF BAD"
-} {1 {Error: unknown command or invalid arguments:  "echo". Enter ".help" for help}}
+} {1 {Usage: .echo on|off}}
 
 # .exit                  Exit this program
 do_test shell1-3.6.1 {
@@ -339,15 +339,15 @@ do_test shell1-3.7.3 {
   catchcmd "test.db" ".explain OFF"
 } {0 {}}
 do_test shell1-3.7.4 {
-  # too many arguments
+  # extra arguments ignored
   catchcmd "test.db" ".explain OFF BAD"
-} {1 {Error: unknown command or invalid arguments:  "explain". Enter ".help" for help}}
+} {0 {}}
 
 
 # .header(s) ON|OFF      Turn display of headers on or off
 do_test shell1-3.9.1 {
   catchcmd "test.db" ".header"
-} {1 {Error: unknown command or invalid arguments:  "header". Enter ".help" for help}}
+} {1 {Usage: .headers on|off}}
 do_test shell1-3.9.2 {
   catchcmd "test.db" ".header ON"
 } {0 {}}
@@ -357,11 +357,11 @@ do_test shell1-3.9.3 {
 do_test shell1-3.9.4 {
   # too many arguments
   catchcmd "test.db" ".header OFF BAD"
-} {1 {Error: unknown command or invalid arguments:  "header". Enter ".help" for help}}
+} {1 {Usage: .headers on|off}}
 
 do_test shell1-3.9.5 {
   catchcmd "test.db" ".headers"
-} {1 {Error: unknown command or invalid arguments:  "headers". Enter ".help" for help}}
+} {1 {Usage: .headers on|off}}
 do_test shell1-3.9.6 {
   catchcmd "test.db" ".headers ON"
 } {0 {}}
@@ -371,7 +371,7 @@ do_test shell1-3.9.7 {
 do_test shell1-3.9.8 {
   # too many arguments
   catchcmd "test.db" ".headers OFF BAD"
-} {1 {Error: unknown command or invalid arguments:  "headers". Enter ".help" for help}}
+} {1 {Usage: .headers on|off}}
 
 # .help                  Show this message
 do_test shell1-3.10.1 {
@@ -393,17 +393,17 @@ do_test shell1-3.10.2 {
 # .import FILE TABLE     Import data from FILE into TABLE
 do_test shell1-3.11.1 {
   catchcmd "test.db" ".import"
-} {1 {Error: unknown command or invalid arguments:  "import". Enter ".help" for help}}
+} {1 {Usage: .import FILE TABLE}}
 do_test shell1-3.11.2 {
   catchcmd "test.db" ".import FOO"
-} {1 {Error: unknown command or invalid arguments:  "import". Enter ".help" for help}}
+} {1 {Usage: .import FILE TABLE}}
 #do_test shell1-3.11.2 {
 #  catchcmd "test.db" ".import FOO BAR"
 #} {1 {Error: no such table: BAR}}
 do_test shell1-3.11.3 {
   # too many arguments
   catchcmd "test.db" ".import FOO BAR BAD"
-} {1 {Error: unknown command or invalid arguments:  "import". Enter ".help" for help}}
+} {1 {Usage: .import FILE TABLE}}
 
 # .indices ?TABLE?       Show names of all indices
 #                          If TABLE specified, only show indices for tables
@@ -417,7 +417,7 @@ do_test shell1-3.12.2 {
 do_test shell1-3.12.3 {
   # too many arguments
   catchcmd "test.db" ".indices FOO BAD"
-} {1 {Error: unknown command or invalid arguments:  "indices". Enter ".help" for help}}
+} {1 {Usage: .indices ?LIKE-PATTERN?}}
 
 # .mode MODE ?TABLE?     Set output mode where MODE is one of:
 #                          csv      Comma-separated values
@@ -430,7 +430,7 @@ do_test shell1-3.12.3 {
 #                          tcl      TCL list elements
 do_test shell1-3.13.1 {
   catchcmd "test.db" ".mode"
-} {1 {Error: unknown command or invalid arguments:  "mode". Enter ".help" for help}}
+} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}
 do_test shell1-3.13.2 {
   catchcmd "test.db" ".mode FOO"
 } {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}
@@ -459,9 +459,9 @@ do_test shell1-3.13.10 {
   catchcmd "test.db" ".mode tcl"
 } {0 {}}
 do_test shell1-3.13.11 {
-  # too many arguments
+  # extra arguments ignored
   catchcmd "test.db" ".mode tcl BAD"
-} {1 {Error: invalid arguments:  "BAD". Enter ".help" for help}}
+} {0 {}}
 
 # don't allow partial mode type matches
 do_test shell1-3.13.12 {
@@ -472,31 +472,31 @@ do_test shell1-3.13.13 {
 } {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}
 do_test shell1-3.13.14 {
   catchcmd "test.db" ".mode lin"
-} {1 {Error: mode should be one of: column csv html insert line list tabs tcl}}
+} {0 {}}
 
 # .nullvalue STRING      Print STRING in place of NULL values
 do_test shell1-3.14.1 {
   catchcmd "test.db" ".nullvalue"
-} {1 {Error: unknown command or invalid arguments:  "nullvalue". Enter ".help" for help}}
+} {1 {Usage: .nullvalue STRING}}
 do_test shell1-3.14.2 {
   catchcmd "test.db" ".nullvalue FOO"
 } {0 {}}
 do_test shell1-3.14.3 {
   # too many arguments
   catchcmd "test.db" ".nullvalue FOO BAD"
-} {1 {Error: unknown command or invalid arguments:  "nullvalue". Enter ".help" for help}}
+} {1 {Usage: .nullvalue STRING}}
 
 # .output FILENAME       Send output to FILENAME
 do_test shell1-3.15.1 {
   catchcmd "test.db" ".output"
-} {1 {Error: unknown command or invalid arguments:  "output". Enter ".help" for help}}
+} {0 {}}
 do_test shell1-3.15.2 {
   catchcmd "test.db" ".output FOO"
 } {0 {}}
 do_test shell1-3.15.3 {
   # too many arguments
   catchcmd "test.db" ".output FOO BAD"
-} {1 {Error: unknown command or invalid arguments:  "output". Enter ".help" for help}}
+} {1 {Usage: .output FILE}}
 
 # .output stdout         Send output to the screen
 do_test shell1-3.16.1 {
@@ -505,12 +505,12 @@ do_test shell1-3.16.1 {
 do_test shell1-3.16.2 {
   # too many arguments
   catchcmd "test.db" ".output stdout BAD"
-} {1 {Error: unknown command or invalid arguments:  "output". Enter ".help" for help}}
+} {1 {Usage: .output FILE}}
 
 # .prompt MAIN CONTINUE  Replace the standard prompts
 do_test shell1-3.17.1 {
   catchcmd "test.db" ".prompt"
-} {1 {Error: unknown command or invalid arguments:  "prompt". Enter ".help" for help}}
+} {0 {}}
 do_test shell1-3.17.2 {
   catchcmd "test.db" ".prompt FOO"
 } {0 {}}
@@ -520,7 +520,7 @@ do_test shell1-3.17.3 {
 do_test shell1-3.17.4 {
   # too many arguments
   catchcmd "test.db" ".prompt FOO BAR BAD"
-} {1 {Error: unknown command or invalid arguments:  "prompt". Enter ".help" for help}}
+} {0 {}}
 
 # .quit                  Exit this program
 do_test shell1-3.18.1 {
@@ -529,12 +529,12 @@ do_test shell1-3.18.1 {
 do_test shell1-3.18.2 {
   # too many arguments
   catchcmd "test.db" ".quit BAD"
-} {1 {Error: unknown command or invalid arguments:  "quit". Enter ".help" for help}}
+} {0 {}}
 
 # .read FILENAME         Execute SQL in FILENAME
 do_test shell1-3.19.1 {
   catchcmd "test.db" ".read"
-} {1 {Error: unknown command or invalid arguments:  "read". Enter ".help" for help}}
+} {1 {Usage: .read FILE}}
 do_test shell1-3.19.2 {
   forcedelete FOO
   catchcmd "test.db" ".read FOO"
@@ -542,12 +542,12 @@ do_test shell1-3.19.2 {
 do_test shell1-3.19.3 {
   # too many arguments
   catchcmd "test.db" ".read FOO BAD"
-} {1 {Error: unknown command or invalid arguments:  "read". Enter ".help" for help}}
+} {1 {Usage: .read FILE}}
 
 # .restore ?DB? FILE     Restore content of DB (default "main") from FILE
 do_test shell1-3.20.1 {
   catchcmd "test.db" ".restore"
-} {1 {Error: unknown command or invalid arguments:  "restore". Enter ".help" for help}}
+} {1 {Usage: .restore ?DB? FILE}}
 do_test shell1-3.20.2 {
   catchcmd "test.db" ".restore FOO"
 } {0 {}}
@@ -557,7 +557,7 @@ do_test shell1-3.20.3 {
 do_test shell1-3.20.4 {
   # too many arguments
   catchcmd "test.db" ".restore FOO BAR BAD"
-} {1 {Error: unknown command or invalid arguments:  "restore". Enter ".help" for help}}
+} {1 {Usage: .restore ?DB? FILE}}
 
 # .schema ?TABLE?        Show the CREATE statements
 #                          If TABLE specified, only show tables matching
@@ -571,7 +571,7 @@ do_test shell1-3.21.2 {
 do_test shell1-3.21.3 {
   # too many arguments
   catchcmd "test.db" ".schema FOO BAD"
-} {1 {Error: unknown command or invalid arguments:  "schema". Enter ".help" for help}}
+} {1 {Usage: .schema ?LIKE-PATTERN?}}
 
 do_test shell1-3.21.4 {
   catchcmd "test.db" {
@@ -588,14 +588,14 @@ db eval {DROP VIEW v1; DROP VIEW v2; DROP TABLE t1;}
 # .separator STRING      Change separator used by output mode and .import
 do_test shell1-3.22.1 {
   catchcmd "test.db" ".separator"
-} {1 {Error: unknown command or invalid arguments:  "separator". Enter ".help" for help}}
+} {1 {Usage: .separator STRING}}
 do_test shell1-3.22.2 {
   catchcmd "test.db" ".separator FOO"
 } {0 {}}
 do_test shell1-3.22.3 {
   # too many arguments
   catchcmd "test.db" ".separator FOO BAD"
-} {1 {Error: unknown command or invalid arguments:  "separator". Enter ".help" for help}}
+} {1 {Usage: .separator STRING}}
 
 # .show                  Show the current values for various settings
 do_test shell1-3.23.1 {
@@ -613,12 +613,12 @@ do_test shell1-3.23.1 {
 do_test shell1-3.23.2 {
   # too many arguments
   catchcmd "test.db" ".show BAD"
-} {1 {Error: unknown command or invalid arguments:  "show". Enter ".help" for help}}
+} {1 {Usage: .show}}
 
 # .stats ON|OFF          Turn stats on or off
 do_test shell1-3.23b.1 {
   catchcmd "test.db" ".stats"
-} {1 {Error: unknown command or invalid arguments:  "stats". Enter ".help" for help}}
+} {1 {Usage: .stats on|off}}
 do_test shell1-3.23b.2 {
   catchcmd "test.db" ".stats ON"
 } {0 {}}
@@ -628,7 +628,7 @@ do_test shell1-3.23b.3 {
 do_test shell1-3.23b.4 {
   # too many arguments
   catchcmd "test.db" ".stats OFF BAD"
-} {1 {Error: unknown command or invalid arguments:  "stats". Enter ".help" for help}}
+} {1 {Usage: .stats on|off}}
 
 # .tables ?TABLE?        List names of tables
 #                          If TABLE specified, only list tables matching
@@ -642,12 +642,12 @@ do_test shell1-3.24.2 {
 do_test shell1-3.24.3 {
   # too many arguments
   catchcmd "test.db" ".tables FOO BAD"
-} {1 {Error: unknown command or invalid arguments:  "tables". Enter ".help" for help}}
+} {0 {}}
 
 # .timeout MS            Try opening locked tables for MS milliseconds
 do_test shell1-3.25.1 {
   catchcmd "test.db" ".timeout"
-} {1 {Error: unknown command or invalid arguments:  "timeout". Enter ".help" for help}}
+} {0 {}}
 do_test shell1-3.25.2 {
   catchcmd "test.db" ".timeout zzz"
   # this should be treated the same as a '0' timeout
@@ -658,12 +658,12 @@ do_test shell1-3.25.3 {
 do_test shell1-3.25.4 {
   # too many arguments
   catchcmd "test.db" ".timeout 1 BAD"
-} {1 {Error: unknown command or invalid arguments:  "timeout". Enter ".help" for help}}
+} {0 {}}
 
 # .width NUM NUM ...     Set column widths for "column" mode
 do_test shell1-3.26.1 {
   catchcmd "test.db" ".width"
-} {1 {Error: unknown command or invalid arguments:  "width". Enter ".help" for help}}
+} {0 {}}
 do_test shell1-3.26.2 {
   catchcmd "test.db" ".width xxx"
   # this should be treated the same as a '0' width for col 1
@@ -689,7 +689,7 @@ do_test shell1-3.26.6 {
 # .timer ON|OFF          Turn the CPU timer measurement on or off
 do_test shell1-3.27.1 {
   catchcmd "test.db" ".timer"
-} {1 {Error: unknown command or invalid arguments:  "timer". Enter ".help" for help}}
+} {1 {Usage: .timer on|off}}
 do_test shell1-3.27.2 {
   catchcmd "test.db" ".timer ON"
 } {0 {}}
@@ -699,7 +699,7 @@ do_test shell1-3.27.3 {
 do_test shell1-3.27.4 {
   # too many arguments
   catchcmd "test.db" ".timer OFF BAD"
-} {1 {Error: unknown command or invalid arguments:  "timer". Enter ".help" for help}}
+} {1 {Usage: .timer on|off}}
 
 do_test shell1-3-28.1 {
   catchcmd test.db \
index 5af44c8fd7cb05d160bfef7c01771473d43bb9e7..c29faf00cfa18c085bdb862caa7d5693c4508cdb 100644 (file)
@@ -63,7 +63,7 @@ do_test shell4-1.2.2 {
 # .stats ON|OFF          Turn stats on or off
 do_test shell4-1.3.1 {
   catchcmd "test.db" ".stats"
-} {1 {Error: unknown command or invalid arguments:  "stats". Enter ".help" for help}}
+} {1 {Usage: .stats on|off}}
 do_test shell4-1.3.2 {
   catchcmd "test.db" ".stats ON"
 } {0 {}}
@@ -73,7 +73,7 @@ do_test shell4-1.3.3 {
 do_test shell4-1.3.4 {
   # too many arguments
   catchcmd "test.db" ".stats OFF BAD"
-} {1 {Error: unknown command or invalid arguments:  "stats". Enter ".help" for help}}
+} {1 {Usage: .stats on|off}}
 
 # NB. whitespace is important
 do_test shell4-1.4.1 {
index a14c84a48c2e4cb1eec20e70057cb5e59583e5fe..734833f6fcf539170df888f3c947d8c55a8899e7 100644 (file)
@@ -40,29 +40,29 @@ forcedelete test.db test.db-journal test.db-wal
 # .import FILE TABLE     Import data from FILE into TABLE
 do_test shell5-1.1.1 {
   catchcmd "test.db" ".import"
-} {1 {Error: unknown command or invalid arguments:  "import". Enter ".help" for help}}
+} {1 {Usage: .import FILE TABLE}}
 do_test shell5-1.1.2 {
   catchcmd "test.db" ".import FOO"
-} {1 {Error: unknown command or invalid arguments:  "import". Enter ".help" for help}}
+} {1 {Usage: .import FILE TABLE}}
 #do_test shell5-1.1.2 {
 #  catchcmd "test.db" ".import FOO BAR"
 #} {1 {Error: no such table: BAR}}
 do_test shell5-1.1.3 {
   # too many arguments
   catchcmd "test.db" ".import FOO BAR BAD"
-} {1 {Error: unknown command or invalid arguments:  "import". Enter ".help" for help}}
+} {1 {Usage: .import FILE TABLE}}
 
 # .separator STRING      Change separator used by output mode and .import
-do_test shell1-1.2.1 {
+do_test shell5-1.2.1 {
   catchcmd "test.db" ".separator"
-} {1 {Error: unknown command or invalid arguments:  "separator". Enter ".help" for help}}
-do_test shell1-1.2.2 {
+} {1 {Usage: .separator STRING}}
+do_test shell5-1.2.2 {
   catchcmd "test.db" ".separator FOO"
 } {0 {}}
-do_test shell1-1.2.3 {
+do_test shell5-1.2.3 {
   # too many arguments
   catchcmd "test.db" ".separator FOO BAD"
-} {1 {Error: unknown command or invalid arguments:  "separator". Enter ".help" for help}}
+} {1 {Usage: .separator STRING}}
 
 # separator should default to "|"
 do_test shell5-1.3.1 {