From: larrybr Date: Thu, 13 Apr 2023 14:14:27 +0000 (+0000) Subject: Get CLI utf8_fgets() to not consume more input than it returns. Get console setup... X-Git-Tag: version-3.42.0~141^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4e87950b48ba198c89ab9162a38cfc066edb8b30;p=thirdparty%2Fsqlite.git Get CLI utf8_fgets() to not consume more input than it returns. Get console setup restoration to happen for all non-crash exits. FossilOrigin-Name: b4fa233d3dda54fa83771844cf5156bf1275c687925340af17a7713a9400dfef --- diff --git a/manifest b/manifest index ef57a3a675..260a215b52 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C WIP:\sCLI\soption\sto\stake\scontrol\sof\sconsole\son\sWindows\sand\smake\sit\ssupport\sUTF-8\sinput\spasting\s(or\styping).\sNeeds\swork\sto\sbecome\srobust\sper\s"ToDo:". -D 2023-04-12T17:54:52.445 +C Get\sCLI\sutf8_fgets()\sto\snot\sconsume\smore\sinput\sthan\sit\sreturns.\sGet\sconsole\ssetup\srestoration\sto\shappen\sfor\sall\snon-crash\sexits. +D 2023-04-13T14:14:27.434 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -626,7 +626,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c F src/resolve.c 3e53e02ce87c9582bd7e7d22f13f4094a271678d9dc72820fa257a2abb5e4032 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c 93bb02212256b49a90589a4664031896e2b2991198153dff1a33a72f437dad94 -F src/shell.c.in 156279044afe3acdd48997531617c6bd1b5a37b5761b67900cc4dbfcc8af7130 +F src/shell.c.in d3a5bef33e4ad55f3feeaeb0deaed32dcb80252a5b2ca184d1eefa816a9f92cf F src/sqlite.h.in 4fff9c6cc5d4cbba9532a668112efb6dc469c425e1a2196664d7c07d508363ef F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4 @@ -2052,11 +2052,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 e1ff83fa2565334b28bd0d6582088c4ae0d2d9a590d973615a4a598683fe419c -R 42a09bb2160cadfa8aa798fa30b96ed8 -T *branch * cli-utf8 -T *sym-cli-utf8 * -T -sym-trunk * +P 824382393d92d9eb6df8701de7c263280150569a708759c4a539acc6d8d38821 +R 692e15a266cff0987f54e086d515e8e5 U larrybr -Z e14b183810e19b5d66903057d8becd3e +Z d0dd4db17efed3a7d98e05299e7fc21d # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 230ab719ef..065235828d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -824382393d92d9eb6df8701de7c263280150569a708759c4a539acc6d8d38821 \ No newline at end of file +b4fa233d3dda54fa83771844cf5156bf1275c687925340af17a7713a9400dfef \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index c7c0d537ec..12748b29a3 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -11,6 +11,7 @@ ************************************************************************* ** This file contains code to implement the "sqlite" command line ** utility for accessing SQLite databases. +ToDo: The -utf8 option may not play well with line editing input libraries. */ #if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS) /* This needs to come before any includes for MSVC compiler */ @@ -20,7 +21,7 @@ typedef unsigned int u32; typedef unsigned short int u16; /* -** Optionally #include a user-defined header, whereby compilation options +** optionally #include a user-defined header, whereby compilation options ** may be set prior to where they take effect, but after platform setup. ** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include ** file. Note that this macro has a like effect on sqlite3.c compilation. @@ -589,16 +590,17 @@ static char *dynamicContinuePrompt(void){ #if (defined(_WIN32) || defined(WIN32)) && !defined(SQLITE_SHELL_FIDDLE) static int infsMode; -static UINT codePage; +static UINT codePage = 0; static HANDLE hConsoleIn; static DWORD consoleMode; + /* ** Prepare input stream, (if known to be a WIN32 console), for UTF-8 ** input (from either typing or suitable paste operations) and for ** UTF-8 rendering. This may "fail" with a message to stderr, where ** the preparation is not done and common "code page" issues occur. */ -static void instream_prepare(){ +static void instream_prepare(void){ if( isatty(0) ){ if( !IsValidCodePage(CP_UTF8) ){ fprintf(stderr, "Cannot use UTF-8 code page.\n"); @@ -620,11 +622,12 @@ static void instream_prepare(){ /* ** Undo the effects of instream_prepare(), if any. */ -static void instream_restore(){ - if( console_utf8 ){ +static void SQLITE_CDECL instream_restore(void){ + if( console_utf8 && codePage!=0 ){ _setmode(_fileno(stdin), infsMode); SetConsoleCP(codePage); SetConsoleMode( hConsoleIn, consoleMode ); + console_utf8 = 0; /* Avoid multiple calls. */ } } @@ -633,25 +636,30 @@ static void instream_restore(){ ** from the Windows console to get around its strange coding issues. ** Defers to plain fgets() when input is not interactive or when the ** startup option, -utf8, has not been provided or taken effect. -** WIP: This routine needs work to consume only as many characters -** as can be fit into the provided input buffer. ToDo: That work. -** Avoiding this issue will require some refactoring of CLI input. */ static char* utf8_fgets(char *buf, int ncmax, FILE *fin){ + #define SQLITE_IA_LINE_LEN 150 if( fin==stdin && stdin_is_interactive && console_utf8 ){ - wchar_t * wbuf = (wchar_t*) malloc(ncmax * sizeof(wchar_t)); - wchar_t * wz; - int nmb; - if( wbuf==0 ) return 0; - if( 0 == (wz = fgetws(wbuf, ncmax, stdin)) - || 0 == (nmb = WideCharToMultiByte(CP_UTF8, 0, wz, -1, 0, 0, 0, 0)) - || nmb > ncmax ){ - buf = 0; - goto bail; - } - WideCharToMultiByte(CP_UTF8, 0, wz, -1, buf, nmb, 0, 0); - bail: - free(wbuf); + wchar_t wbuf[SQLITE_IA_LINE_LEN]; + int noc = 0; + if( ncmax == 0 ) return 0; + buf[0] = 0; + while( noc < ncmax-7-1 ){ + /* There is room for at least 2 more characters and the 0-terminator. */ + int na = (ncmax-1 - noc)/4; + wchar_t * wz; + if( na > SQLITE_IA_LINE_LEN ) na = SQLITE_IA_LINE_LEN; + wz = fgetws(wbuf, na, stdin); + if( wz != 0 ){ + int nmb = WideCharToMultiByte(CP_UTF8, 0, wz, -1, 0, 0, 0, 0); + if( nmb !=0 && noc+nmb <= ncmax ){ + WideCharToMultiByte(CP_UTF8, 0, wz, -1, buf+noc, nmb, 0, 0); + noc += nmb-1; /* Strip 0-terminator added by above call. */ + if( buf[noc-1] == '\n' ) break; + }else break; /* Drop apparent garbage in. (Could assert.) */ + }else break; + } + if( noc == 0 ) return 0; return buf; }else{ return fgets(buf, ncmax, fin); @@ -11789,7 +11797,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ char **argv; #endif #ifdef SQLITE_DEBUG - sqlite3_int64 mem_main_enter = sqlite3_memory_used(); + sqlite3_int64 mem_main_enter = 0; #endif char *zErrMsg = 0; #ifdef SQLITE_SHELL_FIDDLE @@ -11821,7 +11829,12 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ stdin_is_interactive = isatty(0); stdout_is_console = isatty(1); #endif - +#if (defined(_WIN32) || defined(WIN32)) && !defined(SQLITE_SHELL_FIDDLE) + atexit(instream_restore); /* Needs revision for CLI as library call */ +#endif +#ifdef SQLITE_DEBUG + mem_main_enter = sqlite3_memory_used(); +#endif #if !defined(_WIN32_WCE) if( getenv("SQLITE_DEBUG_BREAK") ){ if( isatty(0) && isatty(2) ){ @@ -12370,11 +12383,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){ rc = process_input(&data); } } -#if (defined(_WIN32) || defined(WIN32)) && !defined(SQLITE_SHELL_FIDDLE) - if( console_utf8 ){ - instream_restore(); - } -#endif #ifndef SQLITE_SHELL_FIDDLE /* In WASM mode we have to leave the db state in place so that ** client code can "push" SQL into it after this call returns. */