From 57ab256d3c5776487e183da134630ecd5d9430b6 Mon Sep 17 00:00:00 2001 From: larrybr Date: Thu, 11 May 2023 17:04:15 +0000 Subject: [PATCH] For CLI: Cure an old leak and one segfault. Get all shell tests to pass (by altering expected error output in some cases.) Ready now for full use of CLI resource manager. FossilOrigin-Name: 0f55868e2c51775eaa717564f220acf6ddb2094d358d2011e6736f033e77d8dc --- manifest | 16 ++-- manifest.uuid | 2 +- src/shell.c.in | 194 +++++++++++++++++++++++++---------------------- test/shell1.test | 8 +- test/shell3.test | 2 +- 5 files changed, 121 insertions(+), 101 deletions(-) diff --git a/manifest b/manifest index 2f1e3eae9b..ed81523a8b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C WIP,\sCLI\sresource\smanager\sworked\sin,\sbarely\sused\syet.\s(Leaking\sone\sobject.) -D 2023-05-11T03:11:20.248 +C For\sCLI:\sCure\san\sold\sleak\sand\sone\ssegfault.\sGet\sall\sshell\stests\sto\spass\s(by\saltering\sexpected\serror\soutput\sin\ssome\scases.)\sReady\snow\sfor\sfull\suse\sof\sCLI\sresource\smanager. +D 2023-05-11T17:04:15.173 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -642,7 +642,7 @@ F src/resmanage.h 41e38ab8308611055582b031fdcbd179344025fce2f9814e3061b79f53efc3 F src/resolve.c 3e53e02ce87c9582bd7e7d22f13f4094a271678d9dc72820fa257a2abb5e4032 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c f9333ef8181192c22662f5cb8d257efc4a2880f9ee4853c6c4616f783d27e1b5 -F src/shell.c.in 154be768b7c1f1ba3de689f7567386647931e36030c50608d35e7e52d5d786c0 +F src/shell.c.in e20a50b2c8313d5e69ef7a3f6ab6c6ef6bdb3a3d7e3804ea7a60938defc40067 F src/shext_linkage.h 27dcf7624df05b2a7a6d367834339a6db3636f3035157f641f7db2ec499f8f6d F src/sqlite.h.in 27ca1d4b2eda8feee468af5735182390e8fe4696522751eec0136d17323201ad F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1509,9 +1509,9 @@ F test/sharedA.test 64bdd21216dda2c6a3bd3475348ccdc108160f34682c97f2f51c19fc0e21 F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707 F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 62896b0179d402468b54855209cb730e9f15df4896f9ef168113e69b7eec97bf +F test/shell1.test cac1fd2d681e0b79de9488069e4b2287da30788ce96a34788cbffbfe57e7b0a4 F test/shell2.test 71f2f0dbc9fc042f78bc4403b8d4cf0d5ff2ae5eb14285fdec6c1abc945bc87c -F test/shell3.test 9dd38fe5d98047dca5e71a09e64272b3fb75d8131bfb9137122785ed2c8c3802 +F test/shell3.test 5dc710deede6e811e7af2bd91867d4128f023edc5a6cff6b8ad89e32af54c033 F test/shell4.test 8116d7b9dbefe6e2237908afbd6738637e0426486373231d3ad8984471d4e04c F test/shell5.test ec82248dda87329f7dfced8637515b68db4ee75d94c8129dc017376fb61a8247 F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3 @@ -2079,8 +2079,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 1527d429d66505d4f4bb8635c4d9d7ab926037b136554605d67835ee5d19d2de -R 80825c1180825bb4f4ec0bb8962d01e6 +P dbd00bcaa081ec73c2cb6eef0be5f82c890c8293aa90876942bc049e71f3c83a +R 65a7c5b59b4918085541edb8d4653073 U larrybr -Z a4f9d6999be83f832b2f293999c7ee60 +Z 63232a4eaf0029d816f1a2d739e94039 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 16c1536eca..1b691b366f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dbd00bcaa081ec73c2cb6eef0be5f82c890c8293aa90876942bc049e71f3c83a \ No newline at end of file +0f55868e2c51775eaa717564f220acf6ddb2094d358d2011e6736f033e77d8dc \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 0ead7dbf32..d22aaff641 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -988,11 +988,18 @@ typedef struct InSource { ((pIS)==&termInSource && stdin_is_interactive ) /* This instance's address is taken as part of interactive input test. */ -static InSource termInSource = { 0 /*stdin*/, 0, 0, 0, "", 0}; -static InSource stdInSource = { 0 /*stdin*/, 0, 0, 0, "", 0}; +static InSource termInSource = { 0, 0, 0, 0, "", 0}; +static InSource stdInSource = { 0, 0, 0, 0, "", 0}; +static InSource cmdInSource = { 0, 0, 0, 0, "", 0}; static void init_std_inputs(FILE *pIn ){ termInSource.inFile = pIn; stdInSource.inFile = pIn; + cmdInSource.lineno = 0; +} +static void set_invocation_cmd(char *zDo){ + cmdInSource.iReadOffset = 0; + cmdInSource.zStrIn = zDo; + ++cmdInSource.lineno; } static char *strLineGet(char *zBuf, int ncMax, InSource *pInSrc){ @@ -1067,7 +1074,7 @@ static char *local_getline(char *zLine, InSource *pInSrc){ /* For interactive input on Windows systems, without -utf8, ** translate the multi-byte characterset characters into UTF-8. ** This is the translation that predates the -utf8 option. */ - if( stdin_is_interactive && pInSrc==&stdInSource + if( stdin_is_interactive && pInSrc==&termInSource # if SHELL_WIN_UTF8_OPT && !console_utf8 # endif /* SHELL_WIN_UTF8_OPT */ @@ -2034,6 +2041,7 @@ static int failIfSafeMode( va_end(ap); raw_printf(STD_ERR, "line %d: ", ISS(psx)->pInSource->lineno); utf8_printf(STD_ERR, "%s\n", zMsg); + sqlite3_free(zMsg); psx->shellAbruptExit = 0x202; return 1; } @@ -15499,6 +15507,7 @@ static DotCmdRC process_input(ShellInState *psi){ grow_line_buffer(&zLineAccum, &naAccum, ncLineIn+2); /* Copy line just input */ memcpy(zLineAccum, zLineInput, ncLineIn); + zLineAccum[ncLineIn] = 0; ncLineAcc = ncLineIn; pzLineUse = &zLineAccum; pncLineUse = &ncLineAcc; @@ -15508,8 +15517,21 @@ static DotCmdRC process_input(ShellInState *psi){ nGroupLines>0, &shellPrompts); if( zLineInput==0 ){ bInputEnd = 1; - inKind = Eof; + if( inKind==Sql && psi->pInSource==&cmdInSource ){ + /* As a special dispensation, SQL arguments on the command line + ** do not need to end with ';' (or a lone go.) */ + if( nGroupLines>1 ){ + grow_line_buffer(&zLineAccum, &naAccum, ncLineAcc+2); + } + strcpy( zLineAccum+ncLineAcc, ";" ); + if( 1==sqlite3_complete(*pzLineUse) ){ + zLineAccum[ncLineAcc] = 0; + disposition = Runnable; + continue; + } + } disposition = Erroneous; + inKind = Eof; if( bInteractive ) printf("\n"); continue; } @@ -15611,9 +15633,11 @@ static DotCmdRC process_input(ShellInState *psi){ free(zLineInput); /* Allocated via malloc() by readline or equivalents. */ sqlite3_free(zLineAccum); - /* Translate DCR_Return because it has been done here, not to propagate. */ - if( termKind==DCR_Return ) termKind = DCR_Ok; - + /* Translate DCR_Return because it has been done here, not to propagate + * unless input is from shell invocation argument. */ + if( termKind==DCR_Return && psi->pInSource!=&cmdInSource ){ + termKind = DCR_Ok; + } return termKind|(nErrors>0); } @@ -15700,7 +15724,7 @@ static int run_single_query(ShellExState *psx, char *zSql){ /* Some kind of error, to result in exit before REPL. */ if( zErrMsg!=0 ){ utf8_printf(STD_ERR,"Error: %s\n", zErrMsg); - free(zErrMsg); + sqlite3_free(zErrMsg); }else{ utf8_printf(STD_ERR,"Error: unable to process SQL \"%s\"\n", zSql); } @@ -15894,7 +15918,7 @@ static void verify_uninitialized(void){ ** Initialize the state information in data and datax. ** Does no heap allocation. */ - static void main_init(ShellInState *pData, ShellExState *pDatax) { +static void main_init(ShellInState *pData, ShellExState *pDatax) { memset(pData, 0, sizeof(*pData)); memset(pDatax, 0, sizeof(*pDatax)); pDatax->sizeofThis = sizeof(*pDatax); @@ -15922,6 +15946,8 @@ static void verify_uninitialized(void){ sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); init_std_inputs(stdin); + /* Source at EOF (for now), saying it is command line. */ + pData->pInSource = &cmdInSource; } /* @@ -16034,7 +16060,7 @@ static int scanInvokeArgs(int argc, char **argv, int pass, ShellInState *psi, */ stdin_is_interactive = 0; }else if( cli_strcmp(z,"-heap")==0 ){ - #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) +#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) const char *zSize; sqlite3_int64 szHeap; @@ -16043,9 +16069,9 @@ static int scanInvokeArgs(int argc, char **argv, int pass, ShellInState *psi, if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000; verify_uninitialized(); sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64); - #else +#else (void)cmdline_option_value(argc, argv, ++i); - #endif +#endif }else if( cli_strcmp(z,"-pagecache")==0 ){ sqlite3_int64 n, sz; void *pvCache = 0; @@ -16079,7 +16105,7 @@ static int scanInvokeArgs(int argc, char **argv, int pass, ShellInState *psi, case 2: sqlite3_config(SQLITE_CONFIG_MULTITHREAD); break; default: sqlite3_config(SQLITE_CONFIG_SERIALIZED); break; } - #ifdef SQLITE_ENABLE_VFSTRACE +#ifdef SQLITE_ENABLE_VFSTRACE }else if( cli_strcmp(z,"-vfstrace")==0 ){ extern int vfstrace_register( const char *zTraceName, @@ -16089,54 +16115,54 @@ static int scanInvokeArgs(int argc, char **argv, int pass, ShellInState *psi, int makeDefault ); vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,STD_ERR,1); - #endif - #ifdef SQLITE_ENABLE_MULTIPLEX +#endif +#ifdef SQLITE_ENABLE_MULTIPLEX }else if( cli_strcmp(z,"-multiplex")==0 ){ extern int sqlite3_multiple_initialize(const char*,int); sqlite3_multiplex_initialize(0, 1); - #endif +#endif }else if( cli_strcmp(z,"-mmap")==0 ){ sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i)); verify_uninitialized(); sqlite3_config(SQLITE_CONFIG_MMAP_SIZE, sz, sz); - #ifdef SQLITE_ENABLE_SORTER_REFERENCES +#ifdef SQLITE_ENABLE_SORTER_REFERENCES }else if( cli_strcmp(z,"-sorterref")==0 ){ sqlite3_int64 sz = integerValue(cmdline_option_value(argc,argv,++i)); verify_uninitialized(); sqlite3_config(SQLITE_CONFIG_SORTERREF_SIZE, (int)sz); - #endif +#endif }else if( cli_strcmp(z,"-vfs")==0 ){ pad->zVfs = cmdline_option_value(argc, argv, ++i); - #ifdef SQLITE_HAVE_ZLIB +#ifdef SQLITE_HAVE_ZLIB }else if( cli_strcmp(z,"-zip")==0 ){ psi->openMode = SHELL_OPEN_ZIPFILE; - #endif +#endif }else if( cli_strcmp(z,"-append")==0 ){ psi->openMode = SHELL_OPEN_APPENDVFS; - #ifndef SQLITE_OMIT_DESERIALIZE +#ifndef SQLITE_OMIT_DESERIALIZE }else if( cli_strcmp(z,"-deserialize")==0 ){ psi->openMode = SHELL_OPEN_DESERIALIZE; }else if( cli_strcmp(z,"-maxsize")==0 && i+1szMax = integerValue(argv[++i]); - #endif +#endif }else if( cli_strcmp(z,"-readonly")==0 ){ psi->openMode = SHELL_OPEN_READONLY; }else if( cli_strcmp(z,"-nofollow")==0 ){ psi->openFlags = SQLITE_OPEN_NOFOLLOW; - #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) }else if( cli_strncmp(z, "-A",2)==0 ){ /* All remaining command-line arguments are passed to the ".archive" ** command, so ignore them */ break; - #endif +#endif }else if( cli_strcmp(z, "-memtrace")==0 ){ sqlite3MemTraceActivate(STD_ERR); }else if( cli_strcmp(z,"-bail")==0 ){ bail_on_error = 1; - #if SHELL_EXTENSIONS +#if SHELL_EXTENSIONS }else if( cli_strcmp(z,"-shxopts")==0 ){ psi->bExtendedDotCmds = (u8)integerValue(argv[++i]); - #endif +#endif }else if( cli_strcmp(z,"-nonce")==0 ){ free(psi->zNonce); psi->zNonce = strdup(argv[++i]); @@ -16181,18 +16207,18 @@ static int scanInvokeArgs(int argc, char **argv, int pass, ShellInState *psi, zModeSet = z; }else if( cli_strcmp(z,"-tabs")==0 ){ zModeSet = z; - #ifdef SQLITE_HAVE_ZLIB +#ifdef SQLITE_HAVE_ZLIB }else if( cli_strcmp(z,"-zip")==0 ){ psi->openMode = SHELL_OPEN_ZIPFILE; - #endif +#endif }else if( cli_strcmp(z,"-append")==0 ){ psi->openMode = SHELL_OPEN_APPENDVFS; - #ifndef SQLITE_OMIT_DESERIALIZE +#ifndef SQLITE_OMIT_DESERIALIZE }else if( cli_strcmp(z,"-deserialize")==0 ){ psi->openMode = SHELL_OPEN_DESERIALIZE; }else if( cli_strcmp(z,"-maxsize")==0 && i+1szMax = integerValue(argv[++i]); - #endif +#endif }else if( cli_strcmp(z,"-readonly")==0 ){ psi->openMode = SHELL_OPEN_READONLY; }else if( cli_strcmp(z,"-nofollow")==0 ){ @@ -16231,10 +16257,10 @@ static int scanInvokeArgs(int argc, char **argv, int pass, ShellInState *psi, ShellSetFlagI(psi, SHFLG_Backslash); }else if( cli_strcmp(z,"-bail")==0 ){ /* No-op. The bail_on_error flag should already be set. */ - #if SHELL_EXTENSIONS +#if SHELL_EXTENSIONS }else if( cli_strcmp(z,"-shxopts")==0 ){ i++; /* Handled on first pass. */ - #endif +#endif }else if( cli_strcmp(z,"-version")==0 ){ fprintf(STD_OUT, "%s %s\n", sqlite3_libversion(), sqlite3_sourceid()); rc = 2; @@ -16243,9 +16269,9 @@ static int scanInvokeArgs(int argc, char **argv, int pass, ShellInState *psi, }else if( cli_strcmp(z,"-batch")==0 ){ stdin_is_interactive = 0; }else if( cli_strcmp(z,"-utf8")==0 ){ - #if SHELL_WIN_UTF8_OPT +#if SHELL_WIN_UTF8_OPT console_utf8 = 1; - #endif /* SHELL_WIN_UTF8_OPT */ +#endif /* SHELL_WIN_UTF8_OPT */ }else if( cli_strcmp(z,"-heap")==0 ){ i++; }else if( cli_strcmp(z,"-pagecache")==0 ){ @@ -16260,20 +16286,20 @@ static int scanInvokeArgs(int argc, char **argv, int pass, ShellInState *psi, i++; }else if( cli_strcmp(z,"-memtrace")==0 ){ i++; - #ifdef SQLITE_ENABLE_SORTER_REFERENCES +#ifdef SQLITE_ENABLE_SORTER_REFERENCES }else if( cli_strcmp(z,"-sorterref")==0 ){ i++; - #endif +#endif }else if( cli_strcmp(z,"-vfs")==0 ){ i++; - #ifdef SQLITE_ENABLE_VFSTRACE +#ifdef SQLITE_ENABLE_VFSTRACE }else if( cli_strcmp(z,"-vfstrace")==0 ){ i++; - #endif - #ifdef SQLITE_ENABLE_MULTIPLEX +#endif +#ifdef SQLITE_ENABLE_MULTIPLEX }else if( cli_strcmp(z,"-multiplex")==0 ){ i++; - #endif +#endif }else if( cli_strcmp(z,"-help")==0 ){ usage(1); }else if( cli_strcmp(z,"-cmd")==0 ){ @@ -16282,17 +16308,13 @@ static int scanInvokeArgs(int argc, char **argv, int pass, ShellInState *psi, ** 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; /* Pretend specified command is empty. */ - z = cmdline_option_value(argc,argv,++i); - if( z[0]=='.' ){ - drc = do_dot_command(z, psi->pSXS); - rc = (drc>2)? 2 : drc; - }else{ - rc = run_single_query(psi->pSXS, z); - } - if( rc && bail_on_error ){ + set_invocation_cmd(cmdline_option_value(argc,argv,++i)); + drc = process_input(psi); + rc = (drc>2)? 2 : drc; + if( rc>0 ){ break; } - #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) }else if( cli_strncmp(z, "-A", 2)==0 ){ if( pca->nCmd>0 ){ utf8_printf(STD_ERR, "Error: cannot mix regular SQL or dot-commands" @@ -16310,7 +16332,7 @@ static int scanInvokeArgs(int argc, char **argv, int pass, ShellInState *psi, rc = (drc>2)? 2 : drc; pad->readStdin = 0; break; - #endif +#endif }else if( cli_strcmp(z,"-safe")==0 ){ psi->bSafeMode = psi->bSafeModeFuture = 1; }else if( cli_strcmp(z,"-unsafe-testing")==0 ){ @@ -16466,7 +16488,7 @@ int SQLITE_CDECL SHELL_MAIN(int argc, wchar_t **wargv){ ** subsequent sqlite3_config() calls will work. So copy all results into ** memory that does not come from the SQLite memory allocator. */ - #if !SQLITE_SHELL_IS_UTF8 +#if !SQLITE_SHELL_IS_UTF8 sqlite3_initialize(); argvToFree = malloc(sizeof(argv[0])*argc*2); shell_check_oom(argvToFree); @@ -16484,16 +16506,16 @@ int SQLITE_CDECL SHELL_MAIN(int argc, wchar_t **wargv){ sqlite3_free(z); } sqlite3_shutdown(); - #endif +#endif assert( argc>=1 && argv && argv[0] ); Argv0 = argv[0]; - #if SHELL_DYNAMIC_EXTENSION +#if SHELL_DYNAMIC_EXTENSION initStartupDir(); if( isExtendedBasename(Argv0) ) data.bExtendedDotCmds = SHELL_ALL_EXTENSIONS; - #endif +#endif - #ifdef SQLITE_SHELL_DBNAME_PROC +#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 @@ -16503,22 +16525,22 @@ int SQLITE_CDECL SHELL_MAIN(int argc, wchar_t **wargv){ SQLITE_SHELL_DBNAME_PROC(&data.pAuxDb->zDbFilename); warnInmemoryDb = 0; } - #endif +#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, ** and the first command to execute. */ - #ifndef SQLITE_SHELL_FIDDLE +#ifndef SQLITE_SHELL_FIDDLE verify_uninitialized(); - #endif +#endif i = scanInvokeArgs(argc, argv, 1, &data, &cmdArgs, &argsData); - #ifndef SQLITE_SHELL_FIDDLE +#ifndef SQLITE_SHELL_FIDDLE verify_uninitialized(); - #endif +#endif - #ifdef SQLITE_SHELL_INIT_PROC +#ifdef SQLITE_SHELL_INIT_PROC { /* If the SQLITE_SHELL_INIT_PROC macro is defined, then it is the name ** of a C-function that will perform initialization actions on SQLite that @@ -16527,21 +16549,21 @@ int SQLITE_CDECL SHELL_MAIN(int argc, wchar_t **wargv){ extern void SQLITE_SHELL_INIT_PROC(void); SQLITE_SHELL_INIT_PROC(); } - #else +#else /* All the sqlite3_config() calls have now been made. So it is safe ** to call sqlite3_initialize() and process any command line -vfs option. */ sqlite3_initialize(); - #endif +#endif /* Register the control-C (SIGINT) handler. ** Make sure we have a valid signal handler early, before anything ** is done that might take long. */ pGlobalDbLock = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - #ifdef SIGINT +#ifdef SIGINT signal(SIGINT, interrupt_handler); - #elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE) +#elif (defined(_WIN32) || defined(WIN32)) && !defined(_WIN32_WCE) SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE); - #endif +#endif if( argsData.zVfs ){ sqlite3_vfs *pVfs = sqlite3_vfs_find(argsData.zVfs); @@ -16555,19 +16577,19 @@ int SQLITE_CDECL SHELL_MAIN(int argc, wchar_t **wargv){ } if( data.pAuxDb->zDbFilename==0 ){ - #ifndef SQLITE_OMIT_MEMORYDB +#ifndef SQLITE_OMIT_MEMORYDB data.pAuxDb->zDbFilename = ":memory:"; warnInmemoryDb = argc==1; - #else +#else utf8_printf(STD_ERR,"%s: Error: no database filename specified\n", Argv0); rc = 1; goto shell_bail; - #endif +#endif } data.out = STD_OUT; - #ifndef SQLITE_SHELL_FIDDLE +#ifndef SQLITE_SHELL_FIDDLE sqlite3_appendvfs_init(0,0,0); - #endif +#endif /* Go ahead and open the database file if it already exists. If the ** file does not exist, delay opening it. This prevents empty database @@ -16590,33 +16612,27 @@ int SQLITE_CDECL SHELL_MAIN(int argc, wchar_t **wargv){ ** settings in the initialization file. */ rc = scanInvokeArgs(argc, argv, 2, &data, &cmdArgs, &argsData); - if( (rc && bail_on_error) || rc>1 ){ - if( rc==2 ) rc = 0; + if( rc>0 ){ goto shell_bail; } - #if SHELL_WIN_UTF8_OPT +#if SHELL_WIN_UTF8_OPT if( console_utf8 && stdin_is_interactive ){ console_prepare(); }else{ setBinaryMode(stdin, 0); console_utf8 = 0; } - #endif +#endif if( !argsData.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. - */ + /* Run all arguments that are not the DB name or do not begin with '-' + ** as if they were separate command-line inputs. */ for(i=0; i2)? 2 : drc; - }else{ - rc = run_single_query(&datax, cmdArgs.azCmd[i]); - } - if( rc && bail_on_error ){ + set_invocation_cmd(cmdArgs.azCmd[i]); + drc = process_input(&data); + rc = (drc>2)? 2 : drc; + if( rc>0 ){ goto shell_bail; } } @@ -16653,11 +16669,11 @@ int SQLITE_CDECL SHELL_MAIN(int argc, wchar_t **wargv){ } } if( zHistory ){ shell_read_history(zHistory); } - #if HAVE_READLINE || HAVE_EDITLINE +#if HAVE_READLINE || HAVE_EDITLINE rl_attempted_completion_function = readline_completion; - #elif HAVE_LINENOISE +#elif HAVE_LINENOISE linenoiseSetCompletionCallback(linenoise_completion); - #endif +#endif } data.pInSource = &termInSource; /* read from stdin interactively */ drc = process_input(&data); diff --git a/test/shell1.test b/test/shell1.test index 7b82558da9..97a4c10314 100644 --- a/test/shell1.test +++ b/test/shell1.test @@ -53,7 +53,9 @@ do_test shell1-1.1.2 { # error on extra options do_test shell1-1.1.3 { catchcmd "test.db FOO test.db BAD" ".quit" -} {/1 .Error: in prepare, near "FOO": syntax error*/} +} {1 {Parse error near line 1: near "FOO": syntax error + FOO + ^--- error here}} # -help do_test shell1-1.2.1 { @@ -78,7 +80,9 @@ do_test shell1-1.3.2 { } {0 {}} do_test shell1-1.3.3 { catchcmd "-init FOO test.db BAD .quit" "" -} {/1 .Error: in prepare, near "BAD": syntax error*/} +} {1 {Parse error near line 1: near "BAD": syntax error + BAD + ^--- error here}} # -echo print commands before execution do_test shell1-1.4.1 { diff --git a/test/shell3.test b/test/shell3.test index d33994c172..0978f2ea3e 100644 --- a/test/shell3.test +++ b/test/shell3.test @@ -69,7 +69,7 @@ do_test shell3-1.6 { } {0 {}} do_test shell3-1.7 { catchcmd "foo.db \"CREATE TABLE\"" -} {1 {Error: in prepare, incomplete input}} +} {1 {Parse error near line 1: incomplete input}} #---------------------------------------------------------------------------- # shell3-2.*: Basic tests for running SQL file from command line. -- 2.47.3