-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
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
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.
#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
** 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;
}
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);
** 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 );
** 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);
}
}
#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 ){
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;
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;
if( console_utf8 && stdin_is_interactive ){
instream_prepare();
}else{
+ setBinaryMode(stdin, 0);
console_utf8 = 0;
}
#endif