]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Cure CLI double-prompting (by ditching gcc fgetws()), general cleanup. Work remaining...
authorlarrybr <larrybr@noemail.net>
Fri, 14 Apr 2023 19:56:32 +0000 (19:56 +0000)
committerlarrybr <larrybr@noemail.net>
Fri, 14 Apr 2023 19:56:32 +0000 (19:56 +0000)
FossilOrigin-Name: 73a5f54231e9f6ad8f013df3987ea48c516080f9193ed873b56f982ee75658c2

manifest
manifest.uuid
src/shell.c.in

index 260a215b52986518402042eeca475760aaea9d8e..6dfe5033f4084dd0049cd60847eefce80ee214a3 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-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
+C Cure\sCLI\sdouble-prompting\s(by\sditching\sgcc\sfgetws()),\sgeneral\scleanup.\sWork\sremaining\sis\sto\savoid\seffect\sof\s-utf8\swhen\sa\sline\seditor\sis\slinked/used\sas\spart\sof\sCLI.
+D 2023-04-14T19:56:32.111
 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 d3a5bef33e4ad55f3feeaeb0deaed32dcb80252a5b2ca184d1eefa816a9f92cf
+F src/shell.c.in 23c6ed8477303108f53ec73c8333aaff8d11267276f3852597304d8915bc55d7
 F src/sqlite.h.in 4fff9c6cc5d4cbba9532a668112efb6dc469c425e1a2196664d7c07d508363ef
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4
@@ -2052,8 +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 824382393d92d9eb6df8701de7c263280150569a708759c4a539acc6d8d38821
-R 692e15a266cff0987f54e086d515e8e5
+P b4fa233d3dda54fa83771844cf5156bf1275c687925340af17a7713a9400dfef
+R c50b2d60063b3025d3b72bba985f6bbb
 U larrybr
-Z d0dd4db17efed3a7d98e05299e7fc21d
+Z 16fa3e5dbb2e04c40e7812c85b6fd381
 # Remove this line to create a well-formed Fossil manifest.
index 065235828db8659bfd0f2c23a68c956c55d03f15..d526131411bb25c4cfa7318cd9d85598f2767314 100644 (file)
@@ -1 +1 @@
-b4fa233d3dda54fa83771844cf5156bf1275c687925340af17a7713a9400dfef
\ No newline at end of file
+73a5f54231e9f6ad8f013df3987ea48c516080f9193ed873b56f982ee75658c2
\ No newline at end of file
index 12748b29a321da52064bd1fb078f18b323795bf7..2d954bb21892077b174d7adc436fdf0e0d01b7a3 100644 (file)
@@ -589,10 +589,12 @@ static char *dynamicContinuePrompt(void){
 #endif /* !defined(SQLITE_OMIT_DYNAPROMPT) */
 
 #if (defined(_WIN32) || defined(WIN32)) && !defined(SQLITE_SHELL_FIDDLE)
-static int infsMode;
-static UINT codePage = 0;
-static HANDLE hConsoleIn;
-static DWORD consoleMode;
+/* Following variables are used for -utf8 operation. */
+static int stdinEof = 0;  /* EOF seen on console input */
+static int infsMode;      /* Input file stream mode upon shell start */
+static UINT codePage = 0; /* Input code page upon shell start */
+static HANDLE hConsoleIn = INVALID_HANDLE_VALUE; /* Console input handle */
+static DWORD consoleMode; /* Console mode upon shell start */
 
 /*
 ** Prepare input stream, (if known to be a WIN32 console), for UTF-8
@@ -601,7 +603,8 @@ static DWORD consoleMode;
 ** the preparation is not done and common "code page" issues occur.
 */
 static void instream_prepare(void){
-  if( isatty(0) ){
+  hConsoleIn = GetStdHandle(STD_INPUT_HANDLE);
+  if( isatty(0) && GetFileType(hConsoleIn)==FILE_TYPE_CHAR ){
     if( !IsValidCodePage(CP_UTF8) ){
       fprintf(stderr, "Cannot use UTF-8 code page.\n");
       console_utf8 = 0;
@@ -609,7 +612,6 @@ static void instream_prepare(void){
     }
     codePage = GetConsoleCP();
     SetConsoleCP(CP_UTF8);
-    hConsoleIn = GetStdHandle(STD_INPUT_HANDLE);
     GetConsoleMode( hConsoleIn, &consoleMode);
     SetConsoleMode( hConsoleIn, consoleMode | ENABLE_LINE_INPUT );
     infsMode = _setmode(_fileno(stdin), _O_U16TEXT);
@@ -623,7 +625,7 @@ static void instream_prepare(void){
 ** Undo the effects of instream_prepare(), if any.
 */
 static void SQLITE_CDECL instream_restore(void){
-  if( console_utf8 && codePage!=0 ){
+  if( console_utf8 && codePage!=0 &&hConsoleIn != INVALID_HANDLE_VALUE ){
     _setmode(_fileno(stdin), infsMode);
     SetConsoleCP(codePage);
     SetConsoleMode( hConsoleIn, consoleMode );
@@ -638,28 +640,55 @@ static void SQLITE_CDECL instream_restore(void){
 ** startup option, -utf8, has not been provided or taken effect.
 */
 static char* utf8_fgets(char *buf, int ncmax, FILE *fin){
-  #define SQLITE_IA_LINE_LEN 150
+  if( fin==0 ) fin = stdin;
   if( fin==stdin && stdin_is_interactive && console_utf8 ){
-    wchar_t wbuf[SQLITE_IA_LINE_LEN];
+# define SQLITE_IALIM 150
+    wchar_t wbuf[SQLITE_IALIM];
+    int lend = 0;
     int noc = 0;
-    if( ncmax == 0 ) return 0;
+    if( ncmax == 0 || stdinEof ) 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);
+    while( noc < ncmax-7-1 && !lend ){
+      /* There is room for at least 2 more characters and a 0-terminator. */
+      int na = (ncmax > SQLITE_IALIM*4+1 + noc)
+        ? SQLITE_IALIM : (ncmax-1 - noc)/4;
+# undef SQLITE_IALIM
+      DWORD nbr = 0;
+      BOOL bRC = ReadConsoleW(hConsoleIn, wbuf, na, &nbr, 0);
+      if( !bRC || (noc==0 && nbr==0) ) return 0;
+      if( nbr > 0 ){
+        int nmb = WideCharToMultiByte(CP_UTF8, WC_COMPOSITECHECK|WC_DEFAULTCHAR,
+                                      wbuf,nbr, 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;
+          int iseg = noc;
+          nmb = WideCharToMultiByte(CP_UTF8, WC_COMPOSITECHECK|WC_DEFAULTCHAR,
+                                    wbuf,nbr, buf+noc,nmb, 0,0);
+          noc += nmb;
+          /* Fixup line-ends as coded by Windows for CR (or "Enter".)*/
+          if( noc > 0 ){
+            if( buf[noc-1]=='\n' ){
+              lend = 1;
+              if( noc > 1 && buf[noc-2]=='\r' ){
+                buf[noc-2] = '\n';
+                --noc;
+              }
+            }
+          }
+          /* Check for ^Z (anywhere in line) too. */
+          while( iseg < noc ){
+            if( buf[iseg]==0x1a ){
+              stdinEof = 1;
+              noc = iseg; /* Chop ^Z and anything following. */
+              break;
+            }
+            ++iseg;
+          }
         }else break; /* Drop apparent garbage in. (Could assert.) */
       }else break;
     }
+    /* If got nothing, (after ^Z chop), must be at end-of-file. */
     if( noc == 0 ) return 0;
+    buf[noc] = 0;
     return buf;
   }else{
     return fgets(buf, ncmax, fin);
@@ -889,14 +918,11 @@ static char *local_getline(char *zLine, FILE *in){
     }
   }
 #if defined(_WIN32) || defined(WIN32)
-  /* For interactive input on Windows systems, translate the
-  ** multi-byte characterset characters into UTF-8. */
-  if( stdin_is_interactive && in==stdin ){
-    // FILE *cil = fopen("cin.log", "wa");
-    // i64 nzl = strlen(zLine);
+  /* 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 && in==stdin && !console_utf8 ){
     char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
-    // fwrite(zLine, nzl, 1, cil);
-    // fwrite("\n", 1,1, cil);
     if( zTrans ){
       i64 nTrans = strlen(zTrans)+1;
       if( nTrans>nLine ){
@@ -904,11 +930,8 @@ static char *local_getline(char *zLine, FILE *in){
         shell_check_oom(zLine);
       }
       memcpy(zLine, zTrans, nTrans);
-      // fwrite(zLine, nTrans-1, 1, cil);
-      // fwrite("\n", 1,1, cil);
       sqlite3_free(zTrans);
     }
-    // fclose(cil);
   }
 #endif /* defined(_WIN32) || defined(WIN32) */
   return zLine;
@@ -11819,7 +11842,6 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
   int argcToFree = 0;
 #endif
 
-  setBinaryMode(stdin, 0);
   setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
 #ifdef SQLITE_SHELL_FIDDLE
   stdin_is_interactive = 0;
@@ -12306,6 +12328,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
   if( console_utf8 && stdin_is_interactive ){
     instream_prepare();
   }else{
+    setBinaryMode(stdin, 0);
     console_utf8 = 0;
   }
 #endif