-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
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
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.
*************************************************************************
** 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 */
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.
#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");
/*
** 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. */
}
}
** 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);
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
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) ){
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. */