]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Cause CLI to use console_io library.
authorlarrybr <larrybr@noemail.net>
Mon, 6 Nov 2023 03:09:10 +0000 (03:09 +0000)
committerlarrybr <larrybr@noemail.net>
Mon, 6 Nov 2023 03:09:10 +0000 (03:09 +0000)
FossilOrigin-Name: bf66a7c1d330b04fd3c3e50f43ebe1e41307db59d7189798acafb3de77e0c8b2

manifest
manifest.uuid
src/console_io.c
src/console_io.h
src/shell.c.in

index c7f8c4dc5eb12f25e638ca7057ba4055e69fb158..f339a104d063dbb7c9d60fb8e1b64b3b98ce5f6b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Make\sMSVC\saccept\sit,\stoo.\s(Cannot\suse\sstatic\sconst\sint\sas\spart\sof\sa\sconstant\sexpression?)
-D 2023-11-06T00:15:14.079
+C Cause\sCLI\sto\suse\sconsole_io\slibrary.
+D 2023-11-06T03:09:10.820
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -669,8 +669,8 @@ F src/btreeInt.h ef12a72b708677e48d6bc8dcd66fed25434740568b89e2cfa368093cfc5b9d1
 F src/build.c 189e4517d67f09f0a3e0d8e1faa6e2ef0c2e95f6ac82e33c912cb7efa2a359cc
 F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
-F src/console_io.c f1d63f8fd12236fb2e7d57dee3fd4f068c881649b267e716804da84ae1672b31 x
-F src/console_io.h 88b5376f02550b03a0d0f44e71fe6b8dccc025b33f7822780fed9cfe58961fe3
+F src/console_io.c 54dfcb0c76e946a1b96d819e4f4b64b16e7c5e6a12b002206531b487ec0af5a0 x
+F src/console_io.h df286a858032fb626a7eb339ce0ab5d50b5387c2075536f602f9625d73215e7e
 F src/ctime.c 23331529e654be40ca97d171cbbffe9b3d4c71cc53b78fe5501230675952da8b
 F src/date.c eebc54a00e888d3c56147779e9f361b77d62fd69ff2008c5373946aa1ba1d574
 F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782
@@ -727,7 +727,7 @@ F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c d017bad7ba8e778617701a0e986fdeb393d67d6afa84fb28ef4e8b8ad2acf916
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
 F src/select.c a19daa26e95f7245106a31f288b2f50c72d1f2cc156703f04c8c91450e111515
-F src/shell.c.in aebfbedaa7706d2c73ab7366a19fc8bc40ea68b70d2529f7feef54e6eb077ea2
+F src/shell.c.in 86d63996bc534872d20978b1a85d1f8bb20c84d4087c4abae2e7a35f840b93a9
 F src/sqlite.h.in ef0e41e83ad1ac0dcc9ec9939bf541a44b1c5de821bee2d6c61754c3252f3276
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54
@@ -2144,8 +2144,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 2b850aca1e76805a0358064318a765fa66ce394d015936fd47683d74ca4c187e
-R 93fbedf6374d1b71d34353b4143eaca1
+P bb278d2496b27d2e2ee3cedd6fc54394e71ab2ba5d3d51593f97e897b8b306a4
+R 1fc68e9eabc68f8f7161c78d8df5cb64
 U larrybr
-Z f691c4a528e1fad9be92f83414b324ea
+Z ceef29f2dca26d535bb75e96dff32841
 # Remove this line to create a well-formed Fossil manifest.
index 9470d0e1027618e516762e1131e4b2b6f165ff87..9e8e1296e27dfb12f3a31ab03b890486e95beaf6 100644 (file)
@@ -1 +1 @@
-bb278d2496b27d2e2ee3cedd6fc54394e71ab2ba5d3d51593f97e897b8b306a4
\ No newline at end of file
+bf66a7c1d330b04fd3c3e50f43ebe1e41307db59d7189798acafb3de77e0c8b2
\ No newline at end of file
index c137fea245436f89ccb9b2ddaa3b8c7c8d05e3dc..fed9142cfb9292f65cb966f596aaa0660fa40fab 100755 (executable)
 # define SQLITE_CDECL
 #endif
 
+#ifndef SHELL_NO_SYSINC
 #include <stdarg.h>
 #include <string.h>
 #include "console_io.h"
 #include "sqlite3.h"
+#endif
 
 #if defined(_WIN32) || defined(WIN32)
-# include <io.h>
-# include <fcntl.h>
+# ifndef SHELL_NO_SYSINC
+#  include <io.h>
+#  include <fcntl.h>
+# endif
 # ifdef SHELL_LEGACY_CONSOLE_IO
 #  define SHELL_CON_TRANSLATE 2 /* Use UTF-8/MBCS translation for console I/O */
 # else
 #  define SHELL_CON_TRANSLATE 1 /* Use WCHAR Windows APIs for console I/O */
 # endif
 #else
-# include <unistd.h>
+# ifndef SHELL_NO_SYSINC
+#  include <unistd.h>
+# endif
 # define SHELL_CON_TRANSLATE 0 /* Use plain C library stream I/O at console */
 #endif
 
@@ -215,7 +221,7 @@ INT_LINKAGE int fprintfUtf8(FILE *pfO, const char *zFormat, ...){
     /* Legacy translation to active code page, then MBCS chars out. */
     char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0);
     if( z2!=NULL ){
-      rv = strlen(z2);
+      rv = (int)strlen(z2);
       vfprintf(pfO, "%s", z2);
       sqlite3_free(z2);
     }
@@ -224,7 +230,7 @@ INT_LINKAGE int fprintfUtf8(FILE *pfO, const char *zFormat, ...){
     if( z1!=NULL ){
       int nwc;
       WCHAR *zw2 = 0;
-      rv = strlen(z1);
+      rv = (int)strlen(z1);
       nwc = MultiByteToWideChar(CP_UTF8,0,z1,rv,0,0);
       if( nwc>0 ){
         zw2 = sqlite3_malloc64((nwc+1)*sizeof(WCHAR));
index 2178eee539130ecbbd0c04bd4257008a9225712b..6c3e16cd752a5dca91e2c815eb2fc8cbcad9eabe 100644 (file)
@@ -36,6 +36,8 @@
 #  include <io.h>
 #  include <fcntl.h>
 # endif
+#else
+# define SHELL_NO_SYSINC /* Better yet, modify mkshellc.tcl for this. */
 #endif
 
 #ifndef SQLITE3_H
index 3cfe1a94a457b4a2684f176a125b565cdcd3c3fa..f05234b3ef7535fe84029094e098d3a55b54b8db 100644 (file)
@@ -234,30 +234,13 @@ typedef unsigned char u8;
 
 /* string conversion routines only needed on Win32 */
 extern char *sqlite3_win32_unicode_to_utf8(LPCWSTR);
-extern char *sqlite3_win32_mbcs_to_utf8_v2(const char *, int);
-extern char *sqlite3_win32_utf8_to_mbcs_v2(const char *, int);
 extern LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText);
 #endif
 
-/* On Windows, we normally run with output mode of TEXT so that \n characters
-** are automatically translated into \r\n.  However, this behavior needs
-** to be disabled in some cases (ex: when generating CSV output and when
-** rendering quoted strings that contain \n characters).  The following
-** routines take care of that.
-*/
-#if (defined(_WIN32) || defined(WIN32)) && !SQLITE_OS_WINRT
-static void setBinaryMode(FILE *file, int isOutput){
-  if( isOutput ) fflush(file);
-  _setmode(_fileno(file), _O_BINARY);
-}
-static void setTextMode(FILE *file, int isOutput){
-  if( isOutput ) fflush(file);
-  _setmode(_fileno(file), _O_TEXT);
-}
-#else
-# define setBinaryMode(X,Y)
-# define setTextMode(X,Y)
-#endif
+#define INT_LINKAGE static
+
+INCLUDE console_io.h
+INCLUDE console_io.c
 
 /* True if the timer is enabled */
 static int enableTimer = 0;
@@ -449,25 +432,6 @@ static int bail_on_error = 0;
 */
 static int stdin_is_interactive = 1;
 
-/*
-** If build is for non-RT Windows, without 3rd-party line editing,
-** console input and output may be done in a UTF-8 compatible way,
-** if the OS is capable of it and the --no-utf8 option is not seen.
-*/
-#if (defined(_WIN32) || defined(WIN32)) && SHELL_USE_LOCAL_GETLINE \
-  && !defined(SHELL_OMIT_WIN_UTF8) && !SQLITE_OS_WINRT
-# define SHELL_WIN_UTF8_OPT 1
-/* Record whether to do UTF-8 console I/O translation per stream. */
-  static int console_utf8_in = 0;
-  static int console_utf8_out = 0;
-/* Record whether can do UTF-8 or --no-utf8 seen in invocation. */
-  static int mbcs_opted = 1; /* Assume cannot do until shown otherwise. */
-#else
-# define console_utf8_in 0
-# define console_utf8_out 0
-# define SHELL_WIN_UTF8_OPT 0
-#endif
-
 /*
 ** On Windows systems we have to know if standard output is a console
 ** in order to translate UTF-8 into MBCS.  The following variable is
@@ -600,243 +564,14 @@ static char *dynamicContinuePrompt(void){
 }
 #endif /* !defined(SQLITE_OMIT_DYNAPROMPT) */
 
-#if SHELL_WIN_UTF8_OPT
-/* Following struct is used for UTF-8 console I/O. */
-static struct ConsoleState {
-  int stdinEof;      /* EOF has been seen on console input */
-  int infsMode;      /* Input file stream mode upon shell start */
-  UINT inCodePage;   /* Input code page upon shell start */
-  UINT outCodePage;  /* Output code page upon shell start */
-  HANDLE hConsole;   /* Console input or output handle */
-  DWORD consoleMode; /* Console mode upon shell start */
-} conState = { 0, 0, 0, 0, INVALID_HANDLE_VALUE, 0 };
-
-#ifndef _O_U16TEXT /* For build environments lacking this constant: */
-# define _O_U16TEXT 0x20000
-#endif
-
-/*
-** If given stream number is a console, return 1 and get some attributes,
-** else return 0 and set the output attributes to invalid values.
-*/
-static short console_attrs(unsigned stnum, HANDLE *pH, DWORD *pConsMode){
-  static int stid[3] = { STD_INPUT_HANDLE,STD_OUTPUT_HANDLE,STD_ERROR_HANDLE };
-  HANDLE h;
-  *pH = INVALID_HANDLE_VALUE;
-  *pConsMode = 0;
-  if( stnum > 2 ) return 0;
-  h = GetStdHandle(stid[stnum]);
-  if( h!=*pH && GetFileType(h)==FILE_TYPE_CHAR && GetConsoleMode(h,pConsMode) ){
-    *pH = h;
-    return 1;
-  }
-  return 0;
-}
-
-/*
-** Perform a runtime test of Windows console to determine if it can
-** do char-stream I/O correctly when the code page is set to CP_UTF8.
-** Returns are: 1 => yes it can, 0 => no it cannot
-**
-** The console's output code page is momentarily set, then restored.
-** So this should only be run when the process is given use of the
-** console for either input or output.
-*/
-static short ConsoleDoesUTF8(void){
-  UINT ocp = GetConsoleOutputCP();
-  const char TrialUtf8[] = { '\xC8', '\xAB' }; /* "ȫ" or 2 MBCS characters */
-  WCHAR aReadBack[1] = { 0 }; /* Read back as 0x022B when decoded as UTF-8. */
-  CONSOLE_SCREEN_BUFFER_INFO csbInfo = {0};
-  /* Create an inactive screen buffer with which to do the experiment. */
-  HANDLE hCSB = CreateConsoleScreenBuffer(GENERIC_READ|GENERIC_WRITE, 0, 0,
-                                          CONSOLE_TEXTMODE_BUFFER, NULL);
-  if( hCSB!=INVALID_HANDLE_VALUE ){
-    COORD cpos = {0,0};
-    DWORD rbc;
-    SetConsoleCursorPosition(hCSB, cpos);
-    SetConsoleOutputCP(CP_UTF8);
-    /* Write 2 chars which are a single character in UTF-8 but more in MBCS. */
-    WriteConsoleA(hCSB, TrialUtf8, sizeof(TrialUtf8), NULL, NULL);
-    ReadConsoleOutputCharacterW(hCSB, &aReadBack[0], 1, cpos, &rbc);
-    GetConsoleScreenBufferInfo(hCSB, &csbInfo);
-    SetConsoleOutputCP(ocp);
-    CloseHandle(hCSB);
-  }
-  /* Return 1 if cursor advanced by 1 position, else 0. */
-  return (short)(csbInfo.dwCursorPosition.X == 1 && aReadBack[0] == 0x022B);
-}
-
-static short in_console = 0;
-static short out_console = 0;
-
-/*
-** Determine whether either normal I/O stream is the console,
-** and whether it can do UTF-8 translation, setting globals
-** in_console, out_console and mbcs_opted accordingly.
-*/
-static void probe_console(void){
-  HANDLE h;
-  DWORD cMode;
-  in_console = console_attrs(0, &h, &cMode);
-  out_console = console_attrs(1, &h, &cMode);
-  if( in_console || out_console ) mbcs_opted = !ConsoleDoesUTF8();
-}
-
-/*
-** If console is used for normal I/O, absent a --no-utf8 option,
-** prepare console for UTF-8 input (from either typing or suitable
-** paste operations) and/or for UTF-8 output rendering.
-**
-** The console state upon entry is preserved, in conState, so that
-** console_restore() can later restore the same console state.
-**
-** The globals console_utf8_in and console_utf8_out are set, for
-** later use in selecting UTF-8 or MBCS console I/O translations.
-** This routine depends upon globals set by probe_console().
-*/
-static void console_prepare_utf8(void){
-  struct ConsoleState csWork = { 0, 0, 0, 0, INVALID_HANDLE_VALUE, 0 };
-
-  console_utf8_in = console_utf8_out = 0;
-  if( (!in_console && !out_console) || mbcs_opted ) return;
-  console_attrs((in_console)? 0 : 1, &conState.hConsole, &conState.consoleMode);
-  conState.inCodePage = GetConsoleCP();
-  conState.outCodePage = GetConsoleOutputCP();
-  if( in_console ){
-    SetConsoleCP(CP_UTF8);
-    SetConsoleMode(conState.hConsole, conState.consoleMode
-                   | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
-    conState.infsMode = _setmode(_fileno(stdin), _O_U16TEXT);
-    console_utf8_in = 1;
-  }
-  if( out_console ){
-    SetConsoleOutputCP(CP_UTF8);
-    console_utf8_out = 1;
-  }
-}
-
-/*
-** Undo the effects of console_prepare_utf8(), if any.
-*/
-static void SQLITE_CDECL console_restore(void){
-  if( (console_utf8_in||console_utf8_out)
-      && conState.hConsole!=INVALID_HANDLE_VALUE ){
-    if( console_utf8_in ){
-      SetConsoleCP(conState.inCodePage);
-      _setmode(_fileno(stdin), conState.infsMode);
-    }
-    if( console_utf8_out ) SetConsoleOutputCP(conState.outCodePage);
-    SetConsoleMode(conState.hConsole, conState.consoleMode);
-    /* Avoid multiple calls. */
-    conState.hConsole = INVALID_HANDLE_VALUE;
-    conState.consoleMode = 0;
-    console_utf8_in = 0;
-    console_utf8_out = 0;
-  }
-}
-
-/*
-** Collect input like fgets(...) with special provisions for input
-** from the Windows console to get around its strange coding issues.
-** Defers to plain fgets() when input is not interactive or when the
-** UTF-8 input is unavailable or opted out.
-*/
-static char* utf8_fgets(char *buf, int ncmax, FILE *fin){
-  if( fin==0 ) fin = stdin;
-  if( fin==stdin && stdin_is_interactive && console_utf8_in ){
-# define SQLITE_IALIM 150
-    wchar_t wbuf[SQLITE_IALIM];
-    int lend = 0;
-    int noc = 0;
-    if( ncmax==0 || conState.stdinEof ) return 0;
-    buf[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(conState.hConsole, 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 ){
-          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 ){
-              conState.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);
-  }
-}
-
-# define fgets(b,n,f) utf8_fgets(b,n,f)
-#endif /* SHELL_WIN_UTF8_OPT */
-
-/*
-** Render output like fprintf().  Except, if the output is going to the
-** console and if this is running on a Windows machine, and if UTF-8
-** output unavailable (or available but opted out), translate the
-** output from UTF-8 into MBCS for output through 8-bit stdout stream.
-** (Without -no-utf8, no translation is needed and must not be done.)
-*/
-#if defined(_WIN32) || defined(WIN32)
-void utf8_printf(FILE *out, const char *zFormat, ...){
-  va_list ap;
-  va_start(ap, zFormat);
-  if( stdout_is_console && (out==stdout || out==stderr) && !console_utf8_out ){
-    char *z1 = sqlite3_vmprintf(zFormat, ap);
-    char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0);
-    sqlite3_free(z1);
-    fputs(z2, out);
-    sqlite3_free(z2);
-  }else{
-    vfprintf(out, zFormat, ap);
-  }
-  va_end(ap);
-}
-#elif !defined(utf8_printf)
-# define utf8_printf fprintf
-#endif
-
-/*
-** Render output like fprintf().  This should not be used on anything that
-** includes string formatting (e.g. "%s").
-*/
-#if !defined(raw_printf)
-# define raw_printf fprintf
-#endif
+/* From here onward, fgets() is redirected to the console_io library. */
+#define fgets(b,n,f) fgetsUtf8(b,n,f)
+/* And, (varargs) utf8_printf(f,z,...) is redirected to the same. */
+#define utf8_printf fprintfUtf8
 
 /* Indicate out-of-memory and exit. */
 static void shell_out_of_memory(void){
-  raw_printf(stderr,"Error: out of memory\n");
+  utf8_printf(stderr,"Error: out of memory\n");
   exit(1);
 }
 
@@ -1021,23 +756,6 @@ static char *local_getline(char *zLine, FILE *in){
       break;
     }
   }
-#if defined(_WIN32) || defined(WIN32)
-  /* For interactive input on Windows systems, with -no-utf8,
-  ** translate the multi-byte characterset characters into UTF-8.
-  ** This is the translation that predates console UTF-8 input. */
-  if( stdin_is_interactive && in==stdin && !console_utf8_in ){
-    char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0);
-    if( zTrans ){
-      i64 nTrans = strlen(zTrans)+1;
-      if( nTrans>nLine ){
-        zLine = realloc(zLine, nTrans);
-        shell_check_oom(zLine);
-      }
-      memcpy(zLine, zTrans, nTrans);
-      sqlite3_free(zTrans);
-    }
-  }
-#endif /* defined(_WIN32) || defined(WIN32) */
   return zLine;
 }
 
@@ -1761,7 +1479,7 @@ static void failIfSafeMode(
     va_start(ap, zErrMsg);
     zMsg = sqlite3_vmprintf(zErrMsg, ap);
     va_end(ap);
-    raw_printf(stderr, "line %d: ", p->lineno);
+    utf8_printf(stderr, "line %d: ", p->lineno);
     utf8_printf(stderr, "%s\n", zMsg);
     exit(1);
   }
@@ -1947,7 +1665,7 @@ static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
   }
   zStr[i*2] = '\0';
 
-  raw_printf(out,"X'%s'", zStr);
+  utf8_printf(out,"X'%s'", zStr);
   sqlite3_free(zStr);
 }
 
@@ -1986,7 +1704,7 @@ static void output_quoted_string(FILE *out, const char *z){
   if( c==0 ){
     utf8_printf(out,"'%s'",z);
   }else{
-    raw_printf(out, "'");
+    utf8_printf(out, "'");
     while( *z ){
       for(i=0; (c = z[i])!=0 && c!='\''; i++){}
       if( c=='\'' ) i++;
@@ -1995,7 +1713,7 @@ static void output_quoted_string(FILE *out, const char *z){
         z += i;
       }
       if( c=='\'' ){
-        raw_printf(out, "'");
+        utf8_printf(out, "'");
         continue;
       }
       if( c==0 ){
@@ -2003,7 +1721,7 @@ static void output_quoted_string(FILE *out, const char *z){
       }
       z++;
     }
-    raw_printf(out, "'");
+    utf8_printf(out, "'");
   }
   setTextMode(out, 1);
 }
@@ -2035,14 +1753,14 @@ static void output_quoted_escaped_string(FILE *out, const char *z){
       if( z[i]=='\r' ) nCR++;
     }
     if( nNL ){
-      raw_printf(out, "replace(");
+      utf8_printf(out, "replace(");
       zNL = unused_string(z, "\\n", "\\012", zBuf1);
     }
     if( nCR ){
-      raw_printf(out, "replace(");
+      utf8_printf(out, "replace(");
       zCR = unused_string(z, "\\r", "\\015", zBuf2);
     }
-    raw_printf(out, "'");
+    utf8_printf(out, "'");
     while( *z ){
       for(i=0; (c = z[i])!=0 && c!='\n' && c!='\r' && c!='\''; i++){}
       if( c=='\'' ) i++;
@@ -2051,7 +1769,7 @@ static void output_quoted_escaped_string(FILE *out, const char *z){
         z += i;
       }
       if( c=='\'' ){
-        raw_printf(out, "'");
+        utf8_printf(out, "'");
         continue;
       }
       if( c==0 ){
@@ -2059,17 +1777,17 @@ static void output_quoted_escaped_string(FILE *out, const char *z){
       }
       z++;
       if( c=='\n' ){
-        raw_printf(out, "%s", zNL);
+        utf8_printf(out, "%s", zNL);
         continue;
       }
-      raw_printf(out, "%s", zCR);
+      utf8_printf(out, "%s", zCR);
     }
-    raw_printf(out, "'");
+    utf8_printf(out, "'");
     if( nCR ){
-      raw_printf(out, ",'%s',char(13))", zCR);
+      utf8_printf(out, ",'%s',char(13))", zCR);
     }
     if( nNL ){
-      raw_printf(out, ",'%s',char(10))", zNL);
+      utf8_printf(out, ",'%s',char(10))", zNL);
     }
   }
   setTextMode(out, 1);
@@ -2098,7 +1816,7 @@ static void output_c_string(FILE *out, const char *z){
       fputc('\\', out);
       fputc('r', out);
     }else if( !isprint(c&0xff) ){
-      raw_printf(out, "\\%03o", c&0xff);
+      utf8_printf(out, "\\%03o", c&0xff);
     }else{
       fputc(c, out);
     }
@@ -2132,7 +1850,7 @@ static void output_json_string(FILE *out, const char *z, i64 n){
       }else if( c=='\t' ){
         fputc('t', out);
       }else{
-         raw_printf(out, "u%04x",c);
+         utf8_printf(out, "u%04x",c);
       }
     }else{
       fputc(c, out);
@@ -2160,15 +1878,15 @@ static void output_html_string(FILE *out, const char *z){
       utf8_printf(out,"%.*s",i,z);
     }
     if( z[i]=='<' ){
-      raw_printf(out,"&lt;");
+      utf8_printf(out,"&lt;");
     }else if( z[i]=='&' ){
-      raw_printf(out,"&amp;");
+      utf8_printf(out,"&amp;");
     }else if( z[i]=='>' ){
-      raw_printf(out,"&gt;");
+      utf8_printf(out,"&gt;");
     }else if( z[i]=='\"' ){
-      raw_printf(out,"&quot;");
+      utf8_printf(out,"&quot;");
     }else if( z[i]=='\'' ){
-      raw_printf(out,"&#39;");
+      utf8_printf(out,"&#39;");
     }else{
       break;
     }
@@ -2337,14 +2055,14 @@ static int shellAuth(
   az[3] = zA4;
   utf8_printf(p->out, "authorizer: %s", azAction[op]);
   for(i=0; i<4; i++){
-    raw_printf(p->out, " ");
+    utf8_printf(p->out, " ");
     if( az[i] ){
       output_c_string(p->out, az[i]);
     }else{
-      raw_printf(p->out, "NULL");
+      utf8_printf(p->out, "NULL");
     }
   }
-  raw_printf(p->out, "\n");
+  utf8_printf(p->out, "\n");
   if( p->bSafeMode ) (void)safeModeAuth(pClientData, op, zA1, zA2, zA3, zA4);
   return SQLITE_OK;
 }
@@ -2510,13 +2228,13 @@ static int progress_handler(void *pClientData) {
   ShellState *p = (ShellState*)pClientData;
   p->nProgress++;
   if( p->nProgress>=p->mxProgress && p->mxProgress>0 ){
-    raw_printf(p->out, "Progress limit reached (%u)\n", p->nProgress);
+    utf8_printf(p->out, "Progress limit reached (%u)\n", p->nProgress);
     if( p->flgProgress & SHELL_PROGRESS_RESET ) p->nProgress = 0;
     if( p->flgProgress & SHELL_PROGRESS_ONCE ) p->mxProgress = 0;
     return 1;
   }
   if( (p->flgProgress & SHELL_PROGRESS_QUIET)==0 ){
-    raw_printf(p->out, "Progress %u\n", p->nProgress);
+    utf8_printf(p->out, "Progress %u\n", p->nProgress);
   }
   return 0;
 }
@@ -2532,7 +2250,7 @@ static void print_dashes(FILE *out, int N){
     fputs(zDash, out);
     N -= nDash;
   }
-  raw_printf(out, "%.*s", N, zDash);
+  utf8_printf(out, "%.*s", N, zDash);
 }
 
 /*
@@ -2737,22 +2455,22 @@ static int shell_callback(
     }
     case MODE_Html: {
       if( p->cnt++==0 && p->showHeader ){
-        raw_printf(p->out,"<TR>");
+        utf8_printf(p->out,"<TR>");
         for(i=0; i<nArg; i++){
-          raw_printf(p->out,"<TH>");
+          utf8_printf(p->out,"<TH>");
           output_html_string(p->out, azCol[i]);
-          raw_printf(p->out,"</TH>\n");
+          utf8_printf(p->out,"</TH>\n");
         }
-        raw_printf(p->out,"</TR>\n");
+        utf8_printf(p->out,"</TR>\n");
       }
       if( azArg==0 ) break;
-      raw_printf(p->out,"<TR>");
+      utf8_printf(p->out,"<TR>");
       for(i=0; i<nArg; i++){
-        raw_printf(p->out,"<TD>");
+        utf8_printf(p->out,"<TD>");
         output_html_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
-        raw_printf(p->out,"</TD>\n");
+        utf8_printf(p->out,"</TD>\n");
       }
-      raw_printf(p->out,"</TR>\n");
+      utf8_printf(p->out,"</TR>\n");
       break;
     }
     case MODE_Tcl: {
@@ -2792,23 +2510,23 @@ static int shell_callback(
       if( azArg==0 ) break;
       utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
       if( p->showHeader ){
-        raw_printf(p->out,"(");
+        utf8_printf(p->out,"(");
         for(i=0; i<nArg; i++){
-          if( i>0 ) raw_printf(p->out, ",");
+          if( i>0 ) utf8_printf(p->out, ",");
           if( quoteChar(azCol[i]) ){
             char *z = sqlite3_mprintf("\"%w\"", azCol[i]);
             shell_check_oom(z);
             utf8_printf(p->out, "%s", z);
             sqlite3_free(z);
           }else{
-            raw_printf(p->out, "%s", azCol[i]);
+            utf8_printf(p->out, "%s", azCol[i]);
           }
         }
-        raw_printf(p->out,")");
+        utf8_printf(p->out,")");
       }
       p->cnt++;
       for(i=0; i<nArg; i++){
-        raw_printf(p->out, i>0 ? "," : " VALUES(");
+        utf8_printf(p->out, i>0 ? "," : " VALUES(");
         if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
           utf8_printf(p->out,"NULL");
         }else if( aiType && aiType[i]==SQLITE_TEXT ){
@@ -2825,9 +2543,9 @@ static int shell_callback(
           sqlite3_uint64 ur;
           memcpy(&ur,&r,sizeof(r));
           if( ur==0x7ff0000000000000LL ){
-            raw_printf(p->out, "9.0e+999");
+            utf8_printf(p->out, "9.0e+999");
           }else if( ur==0xfff0000000000000LL ){
-            raw_printf(p->out, "-9.0e+999");
+            utf8_printf(p->out, "-9.0e+999");
           }else{
             sqlite3_int64 ir = (sqlite3_int64)r;
             if( r==(double)ir ){
@@ -2835,7 +2553,7 @@ static int shell_callback(
             }else{
               sqlite3_snprintf(50,z,"%!.20g", r);
             }
-            raw_printf(p->out, "%s", z);
+            utf8_printf(p->out, "%s", z);
           }
         }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
           const void *pBlob = sqlite3_column_blob(p->pStmt, i);
@@ -2849,7 +2567,7 @@ static int shell_callback(
           output_quoted_escaped_string(p->out, azArg[i]);
         }
       }
-      raw_printf(p->out,");\n");
+      utf8_printf(p->out,");\n");
       break;
     }
     case MODE_Json: {
@@ -2871,12 +2589,12 @@ static int shell_callback(
           sqlite3_uint64 ur;
           memcpy(&ur,&r,sizeof(r));
           if( ur==0x7ff0000000000000LL ){
-            raw_printf(p->out, "9.0e+999");
+            utf8_printf(p->out, "9.0e+999");
           }else if( ur==0xfff0000000000000LL ){
-            raw_printf(p->out, "-9.0e+999");
+            utf8_printf(p->out, "-9.0e+999");
           }else{
             sqlite3_snprintf(50,z,"%!.20g", r);
-            raw_printf(p->out, "%s", z);
+            utf8_printf(p->out, "%s", z);
           }
         }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
           const void *pBlob = sqlite3_column_blob(p->pStmt, i);
@@ -2916,7 +2634,7 @@ static int shell_callback(
           char z[50];
           double r = sqlite3_column_double(p->pStmt, i);
           sqlite3_snprintf(50,z,"%!.20g", r);
-          raw_printf(p->out, "%s", z);
+          utf8_printf(p->out, "%s", z);
         }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
           const void *pBlob = sqlite3_column_blob(p->pStmt, i);
           int nBlob = sqlite3_column_bytes(p->pStmt, i);
@@ -3142,9 +2860,9 @@ static int run_table_dump_query(
     if( z==0 ) z = "";
     while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
     if( z[0] ){
-      raw_printf(p->out, "\n;\n");
+      utf8_printf(p->out, "\n;\n");
     }else{
-      raw_printf(p->out, ";\n");
+      utf8_printf(p->out, ";\n");
     }
     rc = sqlite3_step(pSelect);
   }
@@ -3242,7 +2960,7 @@ static void displayStatLine(
   }else{
     sqlite3_snprintf(sizeof(zLine), zLine, zFormat, iHiwtr);
   }
-  raw_printf(p->out, "%-36s %s\n", zLabel, zLine);
+  utf8_printf(p->out, "%-36s %s\n", zLabel, zLine);
 }
 
 /*
@@ -3264,7 +2982,7 @@ static int display_stats(
     sqlite3_stmt *pStmt = pArg->pStmt;
     char z[100];
     nCol = sqlite3_column_count(pStmt);
-    raw_printf(out, "%-36s %d\n", "Number of output columns:", nCol);
+    utf8_printf(out, "%-36s %d\n", "Number of output columns:", nCol);
     for(i=0; i<nCol; i++){
       sqlite3_snprintf(sizeof(z),z,"Column %d %nname:", i, &x);
       utf8_printf(out, "%-36s %s\n", z, sqlite3_column_name(pStmt,i));
@@ -3286,7 +3004,7 @@ static int display_stats(
   if( pArg->statsOn==3 ){
     if( pArg->pStmt ){
       iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP,bReset);
-      raw_printf(pArg->out, "VM-steps: %d\n", iCur);
+      utf8_printf(pArg->out, "VM-steps: %d\n", iCur);
     }
     return 0;
   }
@@ -3315,45 +3033,45 @@ static int display_stats(
       iHiwtr = iCur = -1;
       sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED,
                         &iCur, &iHiwtr, bReset);
-      raw_printf(pArg->out,
+      utf8_printf(pArg->out,
               "Lookaside Slots Used:                %d (max %d)\n",
               iCur, iHiwtr);
       sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT,
                         &iCur, &iHiwtr, bReset);
-      raw_printf(pArg->out, "Successful lookaside attempts:       %d\n",
+      utf8_printf(pArg->out, "Successful lookaside attempts:       %d\n",
               iHiwtr);
       sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE,
                         &iCur, &iHiwtr, bReset);
-      raw_printf(pArg->out, "Lookaside failures due to size:      %d\n",
+      utf8_printf(pArg->out, "Lookaside failures due to size:      %d\n",
               iHiwtr);
       sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL,
                         &iCur, &iHiwtr, bReset);
-      raw_printf(pArg->out, "Lookaside failures due to OOM:       %d\n",
+      utf8_printf(pArg->out, "Lookaside failures due to OOM:       %d\n",
               iHiwtr);
     }
     iHiwtr = iCur = -1;
     sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
-    raw_printf(pArg->out, "Pager Heap Usage:                    %d bytes\n",
+    utf8_printf(pArg->out, "Pager Heap Usage:                    %d bytes\n",
             iCur);
     iHiwtr = iCur = -1;
     sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
-    raw_printf(pArg->out, "Page cache hits:                     %d\n", iCur);
+    utf8_printf(pArg->out, "Page cache hits:                     %d\n", iCur);
     iHiwtr = iCur = -1;
     sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
-    raw_printf(pArg->out, "Page cache misses:                   %d\n", iCur);
+    utf8_printf(pArg->out, "Page cache misses:                   %d\n", iCur);
     iHiwtr = iCur = -1;
     sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_WRITE, &iCur, &iHiwtr, 1);
-    raw_printf(pArg->out, "Page cache writes:                   %d\n", iCur);
+    utf8_printf(pArg->out, "Page cache writes:                   %d\n", iCur);
     iHiwtr = iCur = -1;
     sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_SPILL, &iCur, &iHiwtr, 1);
-    raw_printf(pArg->out, "Page cache spills:                   %d\n", iCur);
+    utf8_printf(pArg->out, "Page cache spills:                   %d\n", iCur);
     iHiwtr = iCur = -1;
     sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
-    raw_printf(pArg->out, "Schema Heap Usage:                   %d bytes\n",
+    utf8_printf(pArg->out, "Schema Heap Usage:                   %d bytes\n",
             iCur);
     iHiwtr = iCur = -1;
     sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
-    raw_printf(pArg->out, "Statement Heap/Lookaside Usage:      %d bytes\n",
+    utf8_printf(pArg->out, "Statement Heap/Lookaside Usage:      %d bytes\n",
             iCur);
   }
 
@@ -3361,27 +3079,27 @@ static int display_stats(
     int iHit, iMiss;
     iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
                                bReset);
-    raw_printf(pArg->out, "Fullscan Steps:                      %d\n", iCur);
+    utf8_printf(pArg->out, "Fullscan Steps:                      %d\n", iCur);
     iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
-    raw_printf(pArg->out, "Sort Operations:                     %d\n", iCur);
+    utf8_printf(pArg->out, "Sort Operations:                     %d\n", iCur);
     iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
-    raw_printf(pArg->out, "Autoindex Inserts:                   %d\n", iCur);
+    utf8_printf(pArg->out, "Autoindex Inserts:                   %d\n", iCur);
     iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT,
                                bReset);
     iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS,
                                 bReset);
     if( iHit || iMiss ){
-      raw_printf(pArg->out, "Bloom filter bypass taken:           %d/%d\n",
+      utf8_printf(pArg->out, "Bloom filter bypass taken:           %d/%d\n",
             iHit, iHit+iMiss);
     }
     iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
-    raw_printf(pArg->out, "Virtual Machine Steps:               %d\n", iCur);
+    utf8_printf(pArg->out, "Virtual Machine Steps:               %d\n", iCur);
     iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset);
-    raw_printf(pArg->out, "Reprepare operations:                %d\n", iCur);
+    utf8_printf(pArg->out, "Reprepare operations:                %d\n", iCur);
     iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
-    raw_printf(pArg->out, "Number of times run:                 %d\n", iCur);
+    utf8_printf(pArg->out, "Number of times run:                 %d\n", iCur);
     iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_MEMUSED, bReset);
-    raw_printf(pArg->out, "Memory used by prepared stmt:        %d\n", iCur);
+    utf8_printf(pArg->out, "Memory used by prepared stmt:        %d\n", iCur);
   }
 
 #ifdef __linux__
@@ -4132,7 +3850,7 @@ static void exec_prepared_stmt_columnar(
         }else if( p->cMode==MODE_Box ){
           print_box_row_separator(p, nColumn, BOX_123, BOX_1234, BOX_134);
         }else if( p->cMode==MODE_Column ){
-          raw_printf(p->out, "\n");
+          utf8_printf(p->out, "\n");
         }
       }
       j = -1;
@@ -4297,8 +4015,8 @@ static int expertFinish(
 
       if( bVerbose ){
         const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES);
-        raw_printf(out, "-- Candidates -----------------------------\n");
-        raw_printf(out, "%s\n", zCand);
+        utf8_printf(out, "-- Candidates -----------------------------\n");
+        utf8_printf(out, "%s\n", zCand);
       }
       for(i=0; i<nQuery; i++){
         const char *zSql = sqlite3_expert_report(p, i, EXPERT_REPORT_SQL);
@@ -4306,11 +4024,11 @@ static int expertFinish(
         const char *zEQP = sqlite3_expert_report(p, i, EXPERT_REPORT_PLAN);
         if( zIdx==0 ) zIdx = "(no new indexes)\n";
         if( bVerbose ){
-          raw_printf(out, "-- Query %d --------------------------------\n",i+1);
-          raw_printf(out, "%s\n\n", zSql);
+          utf8_printf(out, "-- Query %d --------------------------------\n",i+1);
+          utf8_printf(out, "%s\n\n", zSql);
         }
-        raw_printf(out, "%s\n", zIdx);
-        raw_printf(out, "%s\n", zEQP);
+        utf8_printf(out, "%s\n", zIdx);
+        utf8_printf(out, "%s\n", zEQP);
       }
     }
   }
@@ -4345,18 +4063,18 @@ static int expertDotCommand(
     }
     else if( n>=2 && 0==cli_strncmp(z, "-sample", n) ){
       if( i==(nArg-1) ){
-        raw_printf(stderr, "option requires an argument: %s\n", z);
+        utf8_printf(stderr, "option requires an argument: %s\n", z);
         rc = SQLITE_ERROR;
       }else{
         iSample = (int)integerValue(azArg[++i]);
         if( iSample<0 || iSample>100 ){
-          raw_printf(stderr, "value out of range: %s\n", azArg[i]);
+          utf8_printf(stderr, "value out of range: %s\n", azArg[i]);
           rc = SQLITE_ERROR;
         }
       }
     }
     else{
-      raw_printf(stderr, "unknown option: %s\n", z);
+      utf8_printf(stderr, "unknown option: %s\n", z);
       rc = SQLITE_ERROR;
     }
   }
@@ -4364,7 +4082,7 @@ static int expertDotCommand(
   if( rc==SQLITE_OK ){
     pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr);
     if( pState->expert.pExpert==0 ){
-      raw_printf(stderr, "sqlite3_expert_new: %s\n",
+      utf8_printf(stderr, "sqlite3_expert_new: %s\n",
                  zErr ? zErr : "out of memory");
       rc = SQLITE_ERROR;
     }else{
@@ -4692,9 +4410,9 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
   noSys    = (p->shellFlgs & SHFLG_DumpNoSys)!=0;
 
   if( cli_strcmp(zTable, "sqlite_sequence")==0 && !noSys ){
-    if( !dataOnly ) raw_printf(p->out, "DELETE FROM sqlite_sequence;\n");
+    if( !dataOnly ) utf8_printf(p->out, "DELETE FROM sqlite_sequence;\n");
   }else if( sqlite3_strglob("sqlite_stat?", zTable)==0 && !noSys ){
-    if( !dataOnly ) raw_printf(p->out, "ANALYZE sqlite_schema;\n");
+    if( !dataOnly ) utf8_printf(p->out, "ANALYZE sqlite_schema;\n");
   }else if( cli_strncmp(zTable, "sqlite_", 7)==0 ){
     return 0;
   }else if( dataOnly ){
@@ -4702,7 +4420,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
   }else if( cli_strncmp(zSql, "CREATE VIRTUAL TABLE", 20)==0 ){
     char *zIns;
     if( !p->writableSchema ){
-      raw_printf(p->out, "PRAGMA writable_schema=ON;\n");
+      utf8_printf(p->out, "PRAGMA writable_schema=ON;\n");
       p->writableSchema = 1;
     }
     zIns = sqlite3_mprintf(
@@ -4772,7 +4490,7 @@ static int dump_callback(void *pArg, int nArg, char **azArg, char **azNotUsed){
     p->mode = p->cMode = MODE_Insert;
     rc = shell_exec(p, sSelect.z, 0);
     if( (rc&0xff)==SQLITE_CORRUPT ){
-      raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
+      utf8_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
       toggleSelectOrder(p->db);
       shell_exec(p, sSelect.z, 0);
       toggleSelectOrder(p->db);
@@ -4803,7 +4521,7 @@ static int run_schema_dump_query(
   if( rc==SQLITE_CORRUPT ){
     char *zQ2;
     int len = strlen30(zQuery);
-    raw_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
+    utf8_printf(p->out, "/****** CORRUPTION ERROR *******/\n");
     if( zErr ){
       utf8_printf(p->out, "/****** %s ******/\n", zErr);
       sqlite3_free(zErr);
@@ -5252,7 +4970,7 @@ static char *readFile(const char *zName, int *pnByte){
   if( in==0 ) return 0;
   rc = fseek(in, 0, SEEK_END);
   if( rc!=0 ){
-    raw_printf(stderr, "Error: '%s' not seekable\n", zName);
+    utf8_printf(stderr, "Error: '%s' not seekable\n", zName);
     fclose(in);
     return 0;
   }
@@ -5260,7 +4978,7 @@ static char *readFile(const char *zName, int *pnByte){
   rewind(in);
   pBuf = sqlite3_malloc64( nIn+1 );
   if( pBuf==0 ){
-    raw_printf(stderr, "Error: out of memory\n");
+    utf8_printf(stderr, "Error: out of memory\n");
     fclose(in);
     return 0;
   }
@@ -5268,7 +4986,7 @@ static char *readFile(const char *zName, int *pnByte){
   fclose(in);
   if( nRead!=1 ){
     sqlite3_free(pBuf);
-    raw_printf(stderr, "Error: cannot read '%s'\n", zName);
+    utf8_printf(stderr, "Error: cannot read '%s'\n", zName);
     return 0;
   }
   pBuf[nIn] = 0;
@@ -6465,7 +6183,7 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
     memcpy(aHdr, pb, 100);
     sqlite3_finalize(pStmt);
   }else{
-    raw_printf(stderr, "unable to read database header\n");
+    utf8_printf(stderr, "unable to read database header\n");
     sqlite3_finalize(pStmt);
     return 1;
   }
@@ -6481,12 +6199,12 @@ static int shell_dbinfo_command(ShellState *p, int nArg, char **azArg){
     utf8_printf(p->out, "%-20s %u", aField[i].zName, val);
     switch( ofst ){
       case 56: {
-        if( val==1 ) raw_printf(p->out, " (utf8)");
-        if( val==2 ) raw_printf(p->out, " (utf16le)");
-        if( val==3 ) raw_printf(p->out, " (utf16be)");
+        if( val==1 ) utf8_printf(p->out, " (utf8)");
+        if( val==2 ) utf8_printf(p->out, " (utf16le)");
+        if( val==3 ) utf8_printf(p->out, " (utf16be)");
       }
     }
-    raw_printf(p->out, "\n");
+    utf8_printf(p->out, "\n");
   }
   if( zDb==0 ){
     zSchemaTab = sqlite3_mprintf("main.sqlite_schema");
@@ -6830,7 +6548,7 @@ static int lintFkeyIndexes(
       zIndent = "    ";
     }
     else{
-      raw_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n",
+      utf8_printf(stderr, "Usage: %s %s ?-verbose? ?-groupbyparent?\n",
           azArg[0], azArg[1]
       );
       return SQLITE_ERROR;
@@ -6876,22 +6594,22 @@ static int lintFkeyIndexes(
       if( rc!=SQLITE_OK ) break;
 
       if( res<0 ){
-        raw_printf(stderr, "Error: internal error");
+        utf8_printf(stderr, "Error: internal error");
         break;
       }else{
         if( bGroupByParent
         && (bVerbose || res==0)
         && (zPrev==0 || sqlite3_stricmp(zParent, zPrev))
         ){
-          raw_printf(out, "-- Parent table %s\n", zParent);
+          utf8_printf(out, "-- Parent table %s\n", zParent);
           sqlite3_free(zPrev);
           zPrev = sqlite3_mprintf("%s", zParent);
         }
 
         if( res==0 ){
-          raw_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget);
+          utf8_printf(out, "%s%s --> %s\n", zIndent, zCI, zTarget);
         }else if( bVerbose ){
-          raw_printf(out, "%s/* no extra indexes required for %s -> %s */\n",
+          utf8_printf(out, "%s/* no extra indexes required for %s -> %s */\n",
               zIndent, zFrom, zTarget
           );
         }
@@ -6900,16 +6618,16 @@ static int lintFkeyIndexes(
     sqlite3_free(zPrev);
 
     if( rc!=SQLITE_OK ){
-      raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
+      utf8_printf(stderr, "%s\n", sqlite3_errmsg(db));
     }
 
     rc2 = sqlite3_finalize(pSql);
     if( rc==SQLITE_OK && rc2!=SQLITE_OK ){
       rc = rc2;
-      raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
+      utf8_printf(stderr, "%s\n", sqlite3_errmsg(db));
     }
   }else{
-    raw_printf(stderr, "%s\n", sqlite3_errmsg(db));
+    utf8_printf(stderr, "%s\n", sqlite3_errmsg(db));
   }
 
   return rc;
@@ -6929,9 +6647,9 @@ static int lintDotCommand(
   return lintFkeyIndexes(pState, azArg, nArg);
 
  usage:
-  raw_printf(stderr, "Usage %s sub-command ?switches...?\n", azArg[0]);
-  raw_printf(stderr, "Where sub-commands are:\n");
-  raw_printf(stderr, "    fkey-indexes\n");
+  utf8_printf(stderr, "Usage %s sub-command ?switches...?\n", azArg[0]);
+  utf8_printf(stderr, "Where sub-commands are:\n");
+  utf8_printf(stderr, "    fkey-indexes\n");
   return SQLITE_ERROR;
 }
 
@@ -6946,7 +6664,7 @@ static void shellPrepare(
   if( *pRc==SQLITE_OK ){
     int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
     if( rc!=SQLITE_OK ){
-      raw_printf(stderr, "sql error: %s (%d)\n",
+      utf8_printf(stderr, "sql error: %s (%d)\n",
           sqlite3_errmsg(db), sqlite3_errcode(db)
       );
       *pRc = rc;
@@ -6999,7 +6717,7 @@ void shellFinalize(
     int rc = sqlite3_finalize(pStmt);
     if( *pRc==SQLITE_OK ){
       if( rc!=SQLITE_OK ){
-        raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
+        utf8_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
       }
       *pRc = rc;
     }
@@ -7020,7 +6738,7 @@ void shellReset(
   if( *pRc==SQLITE_OK ){
     if( rc!=SQLITE_OK ){
       sqlite3 *db = sqlite3_db_handle(pStmt);
-      raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
+      utf8_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
     }
     *pRc = rc;
   }
@@ -7852,7 +7570,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){
   if( sqlite3_recover_errcode(p)!=SQLITE_OK ){
     const char *zErr = sqlite3_recover_errmsg(p);
     int errCode = sqlite3_recover_errcode(p);
-    raw_printf(stderr, "sql error: %s (%d)\n", zErr, errCode);
+    utf8_printf(stderr, "sql error: %s (%d)\n", zErr, errCode);
   }
   rc = sqlite3_recover_finish(p);
   return rc;
@@ -8130,7 +7848,7 @@ static int do_meta_command(char *zLine, ShellState *p){
 #ifndef SQLITE_OMIT_AUTHORIZATION
   if( c=='a' && cli_strncmp(azArg[0], "auth", n)==0 ){
     if( nArg!=2 ){
-      raw_printf(stderr, "Usage: .auth ON|OFF\n");
+      utf8_printf(stderr, "Usage: .auth ON|OFF\n");
       rc = 1;
       goto meta_command_exit;
     }
@@ -8186,12 +7904,12 @@ static int do_meta_command(char *zLine, ShellState *p){
         zDb = zDestFile;
         zDestFile = azArg[j];
       }else{
-        raw_printf(stderr, "Usage: .backup ?DB? ?OPTIONS? FILENAME\n");
+        utf8_printf(stderr, "Usage: .backup ?DB? ?OPTIONS? FILENAME\n");
         return 1;
       }
     }
     if( zDestFile==0 ){
-      raw_printf(stderr, "missing FILENAME argument on .backup\n");
+      utf8_printf(stderr, "missing FILENAME argument on .backup\n");
       return 1;
     }
     if( zDb==0 ) zDb = "main";
@@ -8229,7 +7947,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     if( nArg==2 ){
       bail_on_error = booleanValue(azArg[1]);
     }else{
-      raw_printf(stderr, "Usage: .bail on|off\n");
+      utf8_printf(stderr, "Usage: .bail on|off\n");
       rc = 1;
     }
   }else
@@ -8243,9 +7961,9 @@ static int do_meta_command(char *zLine, ShellState *p){
         setTextMode(p->out, 1);
       }
     }else{
-      raw_printf(stderr, "The \".binary\" command is deprecated."
+      utf8_printf(stderr, "The \".binary\" command is deprecated."
                          " Use \".crnl\" instead.\n");
-      raw_printf(stderr, "Usage: .binary on|off\n");
+      utf8_printf(stderr, "Usage: .binary on|off\n");
       rc = 1;
     }
   }else
@@ -8273,7 +7991,7 @@ static int do_meta_command(char *zLine, ShellState *p){
         rc = 1;
       }
     }else{
-      raw_printf(stderr, "Usage: .cd DIRECTORY\n");
+      utf8_printf(stderr, "Usage: .cd DIRECTORY\n");
       rc = 1;
     }
   }else
@@ -8283,7 +8001,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     if( nArg==2 ){
       setOrClearFlag(p, SHFLG_CountChanges, azArg[1]);
     }else{
-      raw_printf(stderr, "Usage: .changes on|off\n");
+      utf8_printf(stderr, "Usage: .changes on|off\n");
       rc = 1;
     }
   }else
@@ -8297,7 +8015,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     char *zRes = 0;
     output_reset(p);
     if( nArg!=2 ){
-      raw_printf(stderr, "Usage: .check GLOB-PATTERN\n");
+      utf8_printf(stderr, "Usage: .check GLOB-PATTERN\n");
       rc = 2;
     }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){
       rc = 2;
@@ -8320,7 +8038,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     if( nArg==2 ){
       tryToClone(p, azArg[1]);
     }else{
-      raw_printf(stderr, "Usage: .clone FILENAME\n");
+      utf8_printf(stderr, "Usage: .clone FILENAME\n");
       rc = 1;
     }
   }else
@@ -8359,7 +8077,7 @@ static int do_meta_command(char *zLine, ShellState *p){
       if( i<0 || i>=ArraySize(p->aAuxDb) ){
         /* No-op */
       }else if( p->pAuxDb == &p->aAuxDb[i] ){
-        raw_printf(stderr, "cannot close the active database connection\n");
+        utf8_printf(stderr, "cannot close the active database connection\n");
         rc = 1;
       }else if( p->aAuxDb[i].db ){
         session_close_all(p, i);
@@ -8367,7 +8085,7 @@ static int do_meta_command(char *zLine, ShellState *p){
         p->aAuxDb[i].db = 0;
       }
     }else{
-      raw_printf(stderr, "Usage: .connection [close] [CONNECTION-NUMBER]\n");
+      utf8_printf(stderr, "Usage: .connection [close] [CONNECTION-NUMBER]\n");
       rc = 1;
     }
   }else
@@ -8381,9 +8099,9 @@ static int do_meta_command(char *zLine, ShellState *p){
       }
     }else{
 #if !defined(_WIN32) && !defined(WIN32)
-      raw_printf(stderr, "The \".crnl\" is a no-op on non-Windows machines.\n");
+      utf8_printf(stderr, "The \".crnl\" is a no-op on non-Windows machines.\n");
 #endif
-      raw_printf(stderr, "Usage: .crnl on|off\n");
+      utf8_printf(stderr, "Usage: .crnl on|off\n");
       rc = 1;
     }
   }else
@@ -8494,7 +8212,7 @@ static int do_meta_command(char *zLine, ShellState *p){
         if( z[0]=='-' ) z++;
         if( cli_strcmp(z,"preserve-rowids")==0 ){
 #ifdef SQLITE_OMIT_VIRTUALTABLE
-          raw_printf(stderr, "The --preserve-rowids option is not compatible"
+          utf8_printf(stderr, "The --preserve-rowids option is not compatible"
                              " with SQLITE_OMIT_VIRTUALTABLE\n");
           rc = 1;
           sqlite3_free(zLike);
@@ -8513,7 +8231,7 @@ static int do_meta_command(char *zLine, ShellState *p){
           ShellSetFlag(p, SHFLG_DumpNoSys);
         }else
         {
-          raw_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]);
+          utf8_printf(stderr, "Unknown option \"%s\" on \".dump\"\n", azArg[i]);
           rc = 1;
           sqlite3_free(zLike);
           goto meta_command_exit;
@@ -8547,8 +8265,8 @@ static int do_meta_command(char *zLine, ShellState *p){
       /* When playing back a "dump", the content might appear in an order
       ** which causes immediate foreign key constraints to be violated.
       ** So disable foreign-key constraint enforcement to prevent problems. */
-      raw_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
-      raw_printf(p->out, "BEGIN TRANSACTION;\n");
+      utf8_printf(p->out, "PRAGMA foreign_keys=OFF;\n");
+      utf8_printf(p->out, "BEGIN TRANSACTION;\n");
     }
     p->writableSchema = 0;
     p->showHeader = 0;
@@ -8579,13 +8297,13 @@ static int do_meta_command(char *zLine, ShellState *p){
     }
     sqlite3_free(zLike);
     if( p->writableSchema ){
-      raw_printf(p->out, "PRAGMA writable_schema=OFF;\n");
+      utf8_printf(p->out, "PRAGMA writable_schema=OFF;\n");
       p->writableSchema = 0;
     }
     sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
     sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
     if( (p->shellFlgs & SHFLG_DumpDataOnly)==0 ){
-      raw_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n");
+      utf8_printf(p->out, p->nErr?"ROLLBACK; -- due to errors\n":"COMMIT;\n");
     }
     p->showHeader = savedShowHeader;
     p->shellFlgs = savedShellFlags;
@@ -8595,7 +8313,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     if( nArg==2 ){
       setOrClearFlag(p, SHFLG_Echo, azArg[1]);
     }else{
-      raw_printf(stderr, "Usage: .echo on|off\n");
+      utf8_printf(stderr, "Usage: .echo on|off\n");
       rc = 1;
     }
   }else
@@ -8626,7 +8344,7 @@ static int do_meta_command(char *zLine, ShellState *p){
         p->autoEQP = (u8)booleanValue(azArg[1]);
       }
     }else{
-      raw_printf(stderr, "Usage: .eqp off|on|trace|trigger|full\n");
+      utf8_printf(stderr, "Usage: .eqp off|on|trace|trigger|full\n");
       rc = 1;
     }
   }else
@@ -8665,7 +8383,7 @@ static int do_meta_command(char *zLine, ShellState *p){
 #ifndef SQLITE_OMIT_VIRTUALTABLE
   if( c=='e' && cli_strncmp(azArg[0], "expert", n)==0 ){
     if( p->bSafeMode ){
-      raw_printf(stderr,
+      utf8_printf(stderr,
         "Cannot run experimental commands such as \"%s\" in safe mode\n",
         azArg[0]);
       rc = 1;
@@ -8819,7 +8537,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     }else if( isOk==1 ){
       char zBuf[100];
       sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", iRes);
-      raw_printf(p->out, "%s\n", zBuf);
+      utf8_printf(p->out, "%s\n", zBuf);
     }
   }else
 
@@ -8834,7 +8552,7 @@ static int do_meta_command(char *zLine, ShellState *p){
       nArg = 1;
     }
     if( nArg!=1 ){
-      raw_printf(stderr, "Usage: .fullschema ?--indent?\n");
+      utf8_printf(stderr, "Usage: .fullschema ?--indent?\n");
       rc = 1;
       goto meta_command_exit;
     }
@@ -8860,15 +8578,15 @@ static int do_meta_command(char *zLine, ShellState *p){
       }
     }
     if( doStats==0 ){
-      raw_printf(p->out, "/* No STAT tables available */\n");
+      utf8_printf(p->out, "/* No STAT tables available */\n");
     }else{
-      raw_printf(p->out, "ANALYZE sqlite_schema;\n");
+      utf8_printf(p->out, "ANALYZE sqlite_schema;\n");
       data.cMode = data.mode = MODE_Insert;
       data.zDestTable = "sqlite_stat1";
       shell_exec(&data, "SELECT * FROM sqlite_stat1", 0);
       data.zDestTable = "sqlite_stat4";
       shell_exec(&data, "SELECT * FROM sqlite_stat4", 0);
-      raw_printf(p->out, "ANALYZE sqlite_schema;\n");
+      utf8_printf(p->out, "ANALYZE sqlite_schema;\n");
     }
   }else
 
@@ -8877,7 +8595,7 @@ static int do_meta_command(char *zLine, ShellState *p){
       p->showHeader = booleanValue(azArg[1]);
       p->shellFlgs |= SHFLG_HeaderSet;
     }else{
-      raw_printf(stderr, "Usage: .headers on|off\n");
+      utf8_printf(stderr, "Usage: .headers on|off\n");
       rc = 1;
     }
   }else
@@ -8969,19 +8687,19 @@ static int do_meta_command(char *zLine, ShellState *p){
       ** the column and row separator characters from the output mode. */
       nSep = strlen30(p->colSeparator);
       if( nSep==0 ){
-        raw_printf(stderr,
+        utf8_printf(stderr,
                    "Error: non-null column separator required for import\n");
         goto meta_command_exit;
       }
       if( nSep>1 ){
-        raw_printf(stderr,
+        utf8_printf(stderr,
               "Error: multi-character column separators not allowed"
               " for import\n");
         goto meta_command_exit;
       }
       nSep = strlen30(p->rowSeparator);
       if( nSep==0 ){
-        raw_printf(stderr,
+        utf8_printf(stderr,
             "Error: non-null row separator required for import\n");
         goto meta_command_exit;
       }
@@ -8996,7 +8714,7 @@ static int do_meta_command(char *zLine, ShellState *p){
         nSep = strlen30(p->rowSeparator);
       }
       if( nSep>1 ){
-        raw_printf(stderr, "Error: multi-character row separators not allowed"
+        utf8_printf(stderr, "Error: multi-character row separators not allowed"
                            " for import\n");
         goto meta_command_exit;
       }
@@ -9007,7 +8725,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     sCtx.nLine = 1;
     if( sCtx.zFile[0]=='|' ){
 #ifdef SQLITE_OMIT_POPEN
-      raw_printf(stderr, "Error: pipes are not supported in this OS\n");
+      utf8_printf(stderr, "Error: pipes are not supported in this OS\n");
       goto meta_command_exit;
 #else
       sCtx.in = popen(sCtx.zFile+1, "r");
@@ -9290,13 +9008,13 @@ static int do_meta_command(char *zLine, ShellState *p){
         utf8_printf(stderr, "Error in [%s]: %s\n", zSql, sqlite3_errmsg(p->db));
       }else{
         utf8_printf(stdout, "%s;\n", zSql);
-        raw_printf(stdout,
+        utf8_printf(stdout,
           "WARNING: writing to an imposter table will corrupt the \"%s\" %s!\n",
           azArg[1], isWO ? "table" : "index"
         );
       }
     }else{
-      raw_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
+      utf8_printf(stderr, "SQLITE_TESTCTRL_IMPOSTER returns %d\n", rc);
       rc = 1;
     }
     sqlite3_free(zSql);
@@ -9352,7 +9070,7 @@ static int do_meta_command(char *zLine, ShellState *p){
                sqlite3_limit(p->db, aLimit[i].limitCode, -1));
       }
     }else if( nArg>3 ){
-      raw_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
+      utf8_printf(stderr, "Usage: .limit NAME ?NEW-VALUE?\n");
       rc = 1;
       goto meta_command_exit;
     }else{
@@ -9397,7 +9115,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     failIfSafeMode(p, "cannot run .load in safe mode");
     if( nArg<2 || azArg[1][0]==0 ){
       /* Must have a non-empty FILE. (Will not load self.) */
-      raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
+      utf8_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
       rc = 1;
       goto meta_command_exit;
     }
@@ -9415,7 +9133,7 @@ static int do_meta_command(char *zLine, ShellState *p){
 
   if( c=='l' && cli_strncmp(azArg[0], "log", n)==0 ){
     if( nArg!=2 ){
-      raw_printf(stderr, "Usage: .log FILENAME\n");
+      utf8_printf(stderr, "Usage: .log FILENAME\n");
       rc = 1;
     }else{
       const char *zFile = azArg[1];
@@ -9423,7 +9141,7 @@ static int do_meta_command(char *zLine, ShellState *p){
        && cli_strcmp(zFile,"on")!=0
        && cli_strcmp(zFile,"off")!=0
       ){
-        raw_printf(stdout, "cannot set .log to anything other "
+        utf8_printf(stdout, "cannot set .log to anything other "
                    "than \"on\" or \"off\"\n");
         zFile = "off";
       }
@@ -9482,14 +9200,14 @@ static int do_meta_command(char *zLine, ShellState *p){
       if( p->mode==MODE_Column
        || (p->mode>=MODE_Markdown && p->mode<=MODE_Box)
       ){
-        raw_printf
+        utf8_printf
           (p->out,
            "current output mode: %s --wrap %d --wordwrap %s --%squote\n",
            modeDescr[p->mode], p->cmOpts.iWrap,
            p->cmOpts.bWordWrap ? "on" : "off",
            p->cmOpts.bQuote ? "" : "no");
       }else{
-        raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
+        utf8_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
       }
       zMode = modeDescr[p->mode];
     }
@@ -9548,7 +9266,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     }else if( cli_strncmp(zMode,"json",n2)==0 ){
       p->mode = MODE_Json;
     }else{
-      raw_printf(stderr, "Error: mode should be one of: "
+      utf8_printf(stderr, "Error: mode should be one of: "
          "ascii box column csv html insert json line list markdown "
          "qbox quote table tabs tcl\n");
       rc = 1;
@@ -9559,10 +9277,10 @@ static int do_meta_command(char *zLine, ShellState *p){
 #ifndef SQLITE_SHELL_FIDDLE
   if( c=='n' && cli_strcmp(azArg[0], "nonce")==0 ){
     if( nArg!=2 ){
-      raw_printf(stderr, "Usage: .nonce NONCE\n");
+      utf8_printf(stderr, "Usage: .nonce NONCE\n");
       rc = 1;
     }else if( p->zNonce==0 || cli_strcmp(azArg[1],p->zNonce)!=0 ){
-      raw_printf(stderr, "line %d: incorrect nonce: \"%s\"\n",
+      utf8_printf(stderr, "line %d: incorrect nonce: \"%s\"\n",
                  p->lineno, azArg[1]);
       exit(1);
     }else{
@@ -9578,7 +9296,7 @@ static int do_meta_command(char *zLine, ShellState *p){
       sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
                        "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
     }else{
-      raw_printf(stderr, "Usage: .nullvalue STRING\n");
+      utf8_printf(stderr, "Usage: .nullvalue STRING\n");
       rc = 1;
     }
   }else
@@ -9764,7 +9482,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     shell_check_oom(zFile);
     if( zFile[0]=='|' ){
 #ifdef SQLITE_OMIT_POPEN
-      raw_printf(stderr, "Error: pipes are not supported in this OS\n");
+      utf8_printf(stderr, "Error: pipes are not supported in this OS\n");
       rc = 1;
       p->out = stdout;
 #else
@@ -9902,10 +9620,10 @@ static int do_meta_command(char *zLine, ShellState *p){
   if( c=='p' && n>=3 && cli_strncmp(azArg[0], "print", n)==0 ){
     int i;
     for(i=1; i<nArg; i++){
-      if( i>1 ) raw_printf(p->out, " ");
+      if( i>1 ) utf8_printf(p->out, " ");
       utf8_printf(p->out, "%s", azArg[i]);
     }
-    raw_printf(p->out, "\n");
+    utf8_printf(p->out, "\n");
   }else
 
 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
@@ -9975,13 +9693,13 @@ static int do_meta_command(char *zLine, ShellState *p){
     int savedLineno = p->lineno;
     failIfSafeMode(p, "cannot run .read in safe mode");
     if( nArg!=2 ){
-      raw_printf(stderr, "Usage: .read FILE\n");
+      utf8_printf(stderr, "Usage: .read FILE\n");
       rc = 1;
       goto meta_command_exit;
     }
     if( azArg[1][0]=='|' ){
 #ifdef SQLITE_OMIT_POPEN
-      raw_printf(stderr, "Error: pipes are not supported in this OS\n");
+      utf8_printf(stderr, "Error: pipes are not supported in this OS\n");
       rc = 1;
       p->out = stdout;
 #else
@@ -10022,7 +9740,7 @@ static int do_meta_command(char *zLine, ShellState *p){
       zSrcFile = azArg[2];
       zDb = azArg[1];
     }else{
-      raw_printf(stderr, "Usage: .restore ?DB? FILE\n");
+      utf8_printf(stderr, "Usage: .restore ?DB? FILE\n");
       rc = 1;
       goto meta_command_exit;
     }
@@ -10050,7 +9768,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     if( rc==SQLITE_DONE ){
       rc = 0;
     }else if( rc==SQLITE_BUSY || rc==SQLITE_LOCKED ){
-      raw_printf(stderr, "Error: source database is busy\n");
+      utf8_printf(stderr, "Error: source database is busy\n");
       rc = 1;
     }else{
       utf8_printf(stderr, "Error: %s\n", sqlite3_errmsg(p->db));
@@ -10075,10 +9793,10 @@ static int do_meta_command(char *zLine, ShellState *p){
           p->db, SQLITE_DBCONFIG_STMT_SCANSTATUS, p->scanstatsOn, (int*)0
       );
 #ifndef SQLITE_ENABLE_STMT_SCANSTATUS
-      raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
+      utf8_printf(stderr, "Warning: .scanstats not available in this build.\n");
 #endif
     }else{
-      raw_printf(stderr, "Usage: .scanstats on|off|est\n");
+      utf8_printf(stderr, "Usage: .scanstats on|off|est\n");
       rc = 1;
     }
   }else
@@ -10113,7 +9831,7 @@ static int do_meta_command(char *zLine, ShellState *p){
       }else if( zName==0 ){
         zName = azArg[ii];
       }else{
-        raw_printf(stderr,
+        utf8_printf(stderr,
                    "Usage: .schema ?--indent? ?--nosys? ?LIKE-PATTERN?\n");
         rc = 1;
         goto meta_command_exit;
@@ -10220,7 +9938,7 @@ static int do_meta_command(char *zLine, ShellState *p){
       sqlite3_free(zErrMsg);
       rc = 1;
     }else if( rc != SQLITE_OK ){
-      raw_printf(stderr,"Error: querying schema information\n");
+      utf8_printf(stderr,"Error: querying schema information\n");
       rc = 1;
     }else{
       rc = 0;
@@ -10266,11 +9984,11 @@ static int do_meta_command(char *zLine, ShellState *p){
       if( nCmd!=2 ) goto session_syntax_error;
       if( pSession->p==0 ){
         session_not_open:
-        raw_printf(stderr, "ERROR: No sessions are open\n");
+        utf8_printf(stderr, "ERROR: No sessions are open\n");
       }else{
         rc = sqlite3session_attach(pSession->p, azCmd[1]);
         if( rc ){
-          raw_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
+          utf8_printf(stderr, "ERROR: sqlite3session_attach() returns %d\n", rc);
           rc = 0;
         }
       }
@@ -10305,7 +10023,7 @@ static int do_meta_command(char *zLine, ShellState *p){
         }
         if( pChng
           && fwrite(pChng, szChng, 1, out)!=1 ){
-          raw_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
+          utf8_printf(stderr, "ERROR: Failed to write entire %d-byte output\n",
                   szChng);
         }
         sqlite3_free(pChng);
@@ -10352,7 +10070,7 @@ static int do_meta_command(char *zLine, ShellState *p){
         nByte = sizeof(pSession->azFilter[0])*(nCmd-1);
         pSession->azFilter = sqlite3_malloc( nByte );
         if( pSession->azFilter==0 ){
-          raw_printf(stderr, "Error: out or memory\n");
+          utf8_printf(stderr, "Error: out or memory\n");
           exit(1);
         }
         for(ii=1; ii<nCmd; ii++){
@@ -10415,14 +10133,14 @@ static int do_meta_command(char *zLine, ShellState *p){
         }
       }
       if( pAuxDb->nSession>=ArraySize(pAuxDb->aSession) ){
-        raw_printf(stderr,
+        utf8_printf(stderr,
                    "Maximum of %d sessions\n", ArraySize(pAuxDb->aSession));
         goto meta_command_exit;
       }
       pSession = &pAuxDb->aSession[pAuxDb->nSession];
       rc = sqlite3session_create(p->db, azCmd[1], &pSession->p);
       if( rc ){
-        raw_printf(stderr, "Cannot open session: error code=%d\n", rc);
+        utf8_printf(stderr, "Cannot open session: error code=%d\n", rc);
         rc = 0;
         goto meta_command_exit;
       }
@@ -10484,7 +10202,7 @@ static int do_meta_command(char *zLine, ShellState *p){
       {
         utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n",
                     azArg[i], azArg[0]);
-        raw_printf(stderr, "Should be one of: --init -v\n");
+        utf8_printf(stderr, "Should be one of: --init -v\n");
         rc = 1;
         goto meta_command_exit;
       }
@@ -10513,7 +10231,7 @@ static int do_meta_command(char *zLine, ShellState *p){
           -1, &pStmt, 0);
       }
       if( rc ){
-        raw_printf(stderr, "Error querying the selftest table\n");
+        utf8_printf(stderr, "Error querying the selftest table\n");
         rc = 1;
         sqlite3_finalize(pStmt);
         goto meta_command_exit;
@@ -10570,7 +10288,7 @@ static int do_meta_command(char *zLine, ShellState *p){
 
   if( c=='s' && cli_strncmp(azArg[0], "separator", n)==0 ){
     if( nArg<2 || nArg>3 ){
-      raw_printf(stderr, "Usage: .separator COL ?ROW?\n");
+      utf8_printf(stderr, "Usage: .separator COL ?ROW?\n");
       rc = 1;
     }
     if( nArg>=2 ){
@@ -10620,7 +10338,7 @@ static int do_meta_command(char *zLine, ShellState *p){
           goto meta_command_exit;
         }
       }else if( zLike ){
-        raw_printf(stderr, "Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n");
+        utf8_printf(stderr, "Usage: .sha3sum ?OPTIONS? ?LIKE-PATTERN?\n");
         rc = 1;
         goto meta_command_exit;
       }else{
@@ -10769,7 +10487,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     int i, x;
     failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
     if( nArg<2 ){
-      raw_printf(stderr, "Usage: .system COMMAND\n");
+      utf8_printf(stderr, "Usage: .system COMMAND\n");
       rc = 1;
       goto meta_command_exit;
     }
@@ -10780,7 +10498,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     }
     x = zCmd!=0 ? system(zCmd) : 1;
     sqlite3_free(zCmd);
-    if( x ) raw_printf(stderr, "System command returns %d\n", x);
+    if( x ) utf8_printf(stderr, "System command returns %d\n", x);
   }else
 #endif /* !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_FIDDLE) */
 
@@ -10789,7 +10507,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     const char *zOut;
     int i;
     if( nArg!=1 ){
-      raw_printf(stderr, "Usage: .show\n");
+      utf8_printf(stderr, "Usage: .show\n");
       rc = 1;
       goto meta_command_exit;
     }
@@ -10812,15 +10530,15 @@ static int do_meta_command(char *zLine, ShellState *p){
     }
     utf8_printf(p->out, "%12.12s: ", "nullvalue");
       output_c_string(p->out, p->nullValue);
-      raw_printf(p->out, "\n");
+      utf8_printf(p->out, "\n");
     utf8_printf(p->out,"%12.12s: %s\n","output",
             strlen30(p->outfile) ? p->outfile : "stdout");
     utf8_printf(p->out,"%12.12s: ", "colseparator");
       output_c_string(p->out, p->colSeparator);
-      raw_printf(p->out, "\n");
+      utf8_printf(p->out, "\n");
     utf8_printf(p->out,"%12.12s: ", "rowseparator");
       output_c_string(p->out, p->rowSeparator);
-      raw_printf(p->out, "\n");
+      utf8_printf(p->out, "\n");
     switch( p->statsOn ){
       case 0:  zOut = "off";     break;
       default: zOut = "on";      break;
@@ -10830,9 +10548,9 @@ static int do_meta_command(char *zLine, ShellState *p){
     utf8_printf(p->out, "%12.12s: %s\n","stats", zOut);
     utf8_printf(p->out, "%12.12s: ", "width");
     for (i=0;i<p->nWidth;i++) {
-      raw_printf(p->out, "%d ", p->colWidth[i]);
+      utf8_printf(p->out, "%d ", p->colWidth[i]);
     }
-    raw_printf(p->out, "\n");
+    utf8_printf(p->out, "\n");
     utf8_printf(p->out, "%12.12s: %s\n", "filename",
                 p->pAuxDb->zDbFilename ? p->pAuxDb->zDbFilename : "");
   }else
@@ -10849,7 +10567,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     }else if( nArg==1 ){
       display_stats(p->db, p, 0);
     }else{
-      raw_printf(stderr, "Usage: .stats ?on|off|stmt|vmstep?\n");
+      utf8_printf(stderr, "Usage: .stats ?on|off|stmt|vmstep?\n");
       rc = 1;
     }
   }else
@@ -10875,7 +10593,7 @@ static int do_meta_command(char *zLine, ShellState *p){
       /* It is an historical accident that the .indexes command shows an error
       ** when called with the wrong number of arguments whereas the .tables
       ** command does not. */
-      raw_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
+      utf8_printf(stderr, "Usage: .indexes ?LIKE-PATTERN?\n");
       rc = 1;
       sqlite3_finalize(pStmt);
       goto meta_command_exit;
@@ -10954,7 +10672,7 @@ static int do_meta_command(char *zLine, ShellState *p){
           utf8_printf(p->out, "%s%-*s", zSp, maxlen,
                       azResult[j] ? azResult[j]:"");
         }
-        raw_printf(p->out, "\n");
+        utf8_printf(p->out, "\n");
       }
     }
 
@@ -10968,7 +10686,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     output_reset(p);
     p->out = output_file_open("testcase-out.txt", 0);
     if( p->out==0 ){
-      raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
+      utf8_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
     }
     if( nArg>=2 ){
       sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
@@ -11220,9 +10938,9 @@ static int do_meta_command(char *zLine, ShellState *p){
       utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage);
       rc = 1;
     }else if( isOk==1 ){
-      raw_printf(p->out, "%d\n", rc2);
+      utf8_printf(p->out, "%d\n", rc2);
     }else if( isOk==2 ){
-      raw_printf(p->out, "0x%08x\n", rc2);
+      utf8_printf(p->out, "0x%08x\n", rc2);
     }
   }else
 #endif /* !defined(SQLITE_UNTESTABLE) */
@@ -11236,11 +10954,11 @@ static int do_meta_command(char *zLine, ShellState *p){
     if( nArg==2 ){
       enableTimer = booleanValue(azArg[1]);
       if( enableTimer && !HAS_TIMER ){
-        raw_printf(stderr, "Error: timer not available on this system.\n");
+        utf8_printf(stderr, "Error: timer not available on this system.\n");
         enableTimer = 0;
       }
     }else{
-      raw_printf(stderr, "Usage: .timer on|off\n");
+      utf8_printf(stderr, "Usage: .timer on|off\n");
       rc = 1;
     }
   }else
@@ -11277,7 +10995,7 @@ static int do_meta_command(char *zLine, ShellState *p){
           mType |= SQLITE_TRACE_CLOSE;
         }
         else {
-          raw_printf(stderr, "Unknown option \"%s\" on \".trace\"\n", z);
+          utf8_printf(stderr, "Unknown option \"%s\" on \".trace\"\n", z);
           rc = 1;
           goto meta_command_exit;
         }
@@ -11301,7 +11019,7 @@ static int do_meta_command(char *zLine, ShellState *p){
     int lenOpt;
     char *zOpt;
     if( nArg<2 ){
-      raw_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n");
+      utf8_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n");
       rc = 1;
       goto meta_command_exit;
     }
@@ -11323,14 +11041,14 @@ static int do_meta_command(char *zLine, ShellState *p){
 #if SQLITE_USER_AUTHENTICATION
   if( c=='u' && cli_strncmp(azArg[0], "user", n)==0 ){
     if( nArg<2 ){
-      raw_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
+      utf8_printf(stderr, "Usage: .user SUBCOMMAND ...\n");
       rc = 1;
       goto meta_command_exit;
     }
     open_db(p, 0);
     if( cli_strcmp(azArg[1],"login")==0 ){
       if( nArg!=4 ){
-        raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
+        utf8_printf(stderr, "Usage: .user login USER PASSWORD\n");
         rc = 1;
         goto meta_command_exit;
       }
@@ -11342,41 +11060,41 @@ static int do_meta_command(char *zLine, ShellState *p){
       }
     }else if( cli_strcmp(azArg[1],"add")==0 ){
       if( nArg!=5 ){
-        raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
+        utf8_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
         rc = 1;
         goto meta_command_exit;
       }
       rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
                             booleanValue(azArg[4]));
       if( rc ){
-        raw_printf(stderr, "User-Add failed: %d\n", rc);
+        utf8_printf(stderr, "User-Add failed: %d\n", rc);
         rc = 1;
       }
     }else if( cli_strcmp(azArg[1],"edit")==0 ){
       if( nArg!=5 ){
-        raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
+        utf8_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
         rc = 1;
         goto meta_command_exit;
       }
       rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
                               booleanValue(azArg[4]));
       if( rc ){
-        raw_printf(stderr, "User-Edit failed: %d\n", rc);
+        utf8_printf(stderr, "User-Edit failed: %d\n", rc);
         rc = 1;
       }
     }else if( cli_strcmp(azArg[1],"delete")==0 ){
       if( nArg!=3 ){
-        raw_printf(stderr, "Usage: .user delete USER\n");
+        utf8_printf(stderr, "Usage: .user delete USER\n");
         rc = 1;
         goto meta_command_exit;
       }
       rc = sqlite3_user_delete(p->db, azArg[2]);
       if( rc ){
-        raw_printf(stderr, "User-Delete failed: %d\n", rc);
+        utf8_printf(stderr, "User-Delete failed: %d\n", rc);
         rc = 1;
       }
     }else{
-      raw_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
+      utf8_printf(stderr, "Usage: .user login|add|edit|delete ...\n");
       rc = 1;
       goto meta_command_exit;
     }
@@ -11410,9 +11128,9 @@ static int do_meta_command(char *zLine, ShellState *p){
       sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
       if( pVfs ){
         utf8_printf(p->out, "vfs.zName      = \"%s\"\n", pVfs->zName);
-        raw_printf(p->out, "vfs.iVersion   = %d\n", pVfs->iVersion);
-        raw_printf(p->out, "vfs.szOsFile   = %d\n", pVfs->szOsFile);
-        raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
+        utf8_printf(p->out, "vfs.iVersion   = %d\n", pVfs->iVersion);
+        utf8_printf(p->out, "vfs.szOsFile   = %d\n", pVfs->szOsFile);
+        utf8_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
       }
     }
   }else
@@ -11426,11 +11144,11 @@ static int do_meta_command(char *zLine, ShellState *p){
     for(pVfs=sqlite3_vfs_find(0); pVfs; pVfs=pVfs->pNext){
       utf8_printf(p->out, "vfs.zName      = \"%s\"%s\n", pVfs->zName,
            pVfs==pCurrent ? "  <--- CURRENT" : "");
-      raw_printf(p->out, "vfs.iVersion   = %d\n", pVfs->iVersion);
-      raw_printf(p->out, "vfs.szOsFile   = %d\n", pVfs->szOsFile);
-      raw_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
+      utf8_printf(p->out, "vfs.iVersion   = %d\n", pVfs->iVersion);
+      utf8_printf(p->out, "vfs.szOsFile   = %d\n", pVfs->szOsFile);
+      utf8_printf(p->out, "vfs.mxPathname = %d\n", pVfs->mxPathname);
       if( pVfs->pNext ){
-        raw_printf(p->out, "-----------------------------------\n");
+        utf8_printf(p->out, "-----------------------------------\n");
       }
     }
   }else
@@ -11665,7 +11383,7 @@ static int runOneSqlLine(ShellState *p, char *zSql, FILE *in, int startline){
     sqlite3_snprintf(sizeof(zLineBuf), zLineBuf,
             "changes: %lld   total_changes: %lld",
             sqlite3_changes64(p->db), sqlite3_total_changes64(p->db));
-    raw_printf(p->out, "%s\n", zLineBuf);
+    utf8_printf(p->out, "%s\n", zLineBuf);
   }
   return 0;
 }
@@ -11951,7 +11669,7 @@ static void process_sqliterc(
   if( sqliterc == NULL ){
     home_dir = find_home_dir(0);
     if( home_dir==0 ){
-      raw_printf(stderr, "-- warning: cannot find home directory;"
+      utf8_printf(stderr, "-- warning: cannot find home directory;"
                       " cannot read ~/.sqliterc\n");
       return;
     }
@@ -12036,9 +11754,6 @@ static const char zOptions[] =
   "   -table               set output mode to 'table'\n"
   "   -tabs                set output mode to 'tabs'\n"
   "   -unsafe-testing      allow unsafe commands and modes for testing\n"
-#if SHELL_WIN_UTF8_OPT && 0 /* Option is accepted, but is now the default. */
-  "   -utf8                setup interactive console code page for UTF-8\n"
-#endif
   "   -version             show SQLite version\n"
   "   -vfs NAME            use NAME as the default VFS\n"
 #ifdef SQLITE_ENABLE_VFSTRACE
@@ -12056,7 +11771,7 @@ static void usage(int showDetail){
   if( showDetail ){
     utf8_printf(stderr, "OPTIONS include:\n%s", zOptions);
   }else{
-    raw_printf(stderr, "Use the -help option for additional information\n");
+    utf8_printf(stderr, "Use the -help option for additional information\n");
   }
   exit(1);
 }
@@ -12162,6 +11877,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
 #  define data shellState
 #else
   ShellState data;
+  ConsoleStdConsStreams csStreams = CSCS_NoConsole;
 #endif
   const char *zInitFile = 0;
   int i;
@@ -12183,12 +11899,10 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
   stdout_is_console = 1;
   data.wasm.zDefaultDbName = "/fiddle.sqlite3";
 #else
-  stdin_is_interactive = isatty(0);
-  stdout_is_console = isatty(1);
-#endif
-#if SHELL_WIN_UTF8_OPT
-  probe_console(); /* Check for console I/O and UTF-8 capability. */
-  if( !mbcs_opted ) atexit(console_restore);
+  csStreams = consoleClassifySetup(stdin, stdout, stderr);
+  stdin_is_interactive = (csStreams & CSCS_InConsole)!=0;
+  stdout_is_console = (csStreams & CSCS_OutConsole)!=0;
+  atexit(consoleRestore);
 #endif
   atexit(sayAbnormalExit);
 #ifdef SQLITE_DEBUG
@@ -12322,14 +12036,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
       */
       stdin_is_interactive = 0;
     }else if( cli_strcmp(z,"-utf8")==0 ){
-#if SHELL_WIN_UTF8_OPT
-      /* Option accepted, but is ignored except for this diagnostic. */
-      if( mbcs_opted ) fprintf(stderr, "Cannot do UTF-8 at this console.\n");
-#endif /* SHELL_WIN_UTF8_OPT */
     }else if( cli_strcmp(z,"-no-utf8")==0 ){
-#if SHELL_WIN_UTF8_OPT
-      mbcs_opted = 1;
-#endif /* SHELL_WIN_UTF8_OPT */
     }else if( cli_strcmp(z,"-heap")==0 ){
 #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
       const char *zSize;
@@ -12687,7 +12394,7 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
       /* Acted upon in first pass. */
     }else{
       utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
-      raw_printf(stderr,"Use -help for a list of options.\n");
+      utf8_printf(stderr,"Use -help for a list of options.\n");
       return 1;
     }
     data.cMode = data.mode;
@@ -12729,13 +12436,8 @@ int SQLITE_CDECL wmain(int argc, wchar_t **wargv){
       char *zHistory;
       const char *zCharset = "";
       int nHistory;
-#if SHELL_WIN_UTF8_OPT
-      switch( console_utf8_in+2*console_utf8_out ){
-      default: case 0: break;
-      case 1: zCharset = " (utf8 in)"; break;
-      case 2: zCharset = " (utf8 out)"; break;
-      case 3: zCharset = " (utf8 I/O)"; break;
-      }
+#if SHELL_CON_TRANSLATE
+      zCharset = " (UTF-16 console I/O)";
 #endif
       printf(
         "SQLite version %s %.19s%s\n" /*extra-version-info*/