-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
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
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
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
" -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)
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 ){
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,
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
#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;
}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]=='.' ){
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");
}
}
- 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
*/
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 {
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 {