]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Get CLI utf8_fgets() to not consume more input than it returns. Get console setup...
authorlarrybr <larrybr@noemail.net>
Thu, 13 Apr 2023 14:14:27 +0000 (14:14 +0000)
committerlarrybr <larrybr@noemail.net>
Thu, 13 Apr 2023 14:14:27 +0000 (14:14 +0000)
FossilOrigin-Name: b4fa233d3dda54fa83771844cf5156bf1275c687925340af17a7713a9400dfef

manifest
manifest.uuid
src/shell.c.in

index ef57a3a675b6279f4eba606409d66ff5920f7806..260a215b52986518402042eeca475760aaea9d8e 100644 (file)
--- 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.
index 230ab719ef49ff116cf799e04d18917b8a6c4de2..065235828db8659bfd0f2c23a68c956c55d03f15 100644 (file)
@@ -1 +1 @@
-824382393d92d9eb6df8701de7c263280150569a708759c4a539acc6d8d38821
\ No newline at end of file
+b4fa233d3dda54fa83771844cf5156bf1275c687925340af17a7713a9400dfef
\ No newline at end of file
index c7c0d537ec888ff614dbef61d565b772265aa5d2..12748b29a321da52064bd1fb078f18b323795bf7 100644 (file)
@@ -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. */