/ Check-in [3d81dfe3]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Enhance the command-line shell so that it can handle MBCS characters on input and output.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 3d81dfe3bc5ca9588b7796769d9be7a182f38b1c
User & Date: drh 2015-12-30 17:03:40
Context
2015-12-30
18:18
Reduce the size of the CellInfo object from 32 to 24 bytes on 64-bit machines, for a small performance increase and library size reduction. check-in: 6a4cfc7a user: drh tags: trunk
17:03
Enhance the command-line shell so that it can handle MBCS characters on input and output. check-in: 3d81dfe3 user: drh tags: trunk
16:51
Changes to the way that the default BINARY collating sequence is recorded result in a slightly smaller and slightly faster executable. More work could be done to make this cleaner. check-in: 2081d757 user: drh tags: trunk
13:36
Enhance the command-line shell to handle MBCS characters on input and output. Closed-Leaf check-in: a0a08b8c user: drh tags: mbcs-shell
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/shell.c.

   325    325   
   326    326   /*
   327    327   ** Threat stdin as an interactive input if the following variable
   328    328   ** is true.  Otherwise, assume stdin is connected to a file or pipe.
   329    329   */
   330    330   static int stdin_is_interactive = 1;
   331    331   
          332  +/*
          333  +** On Windows systems we have to know if standard output is a console
          334  +** in order to translate UTF-8 into MBCS.  The following variable is
          335  +** true if translation is required.
          336  +*/
          337  +static int stdout_is_console = 1;
          338  +
   332    339   /*
   333    340   ** The following is the open SQLite database.  We make a pointer
   334    341   ** to this database a static variable so that it can be accessed
   335    342   ** by the SIGINT handler to interrupt database processing.
   336    343   */
   337    344   static sqlite3 *globalDb = 0;
   338    345   
................................................................................
   425    432     assert( 0==argc );
   426    433     assert( zShellStatic );
   427    434     UNUSED_PARAMETER(argc);
   428    435     UNUSED_PARAMETER(argv);
   429    436     sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
   430    437   }
   431    438   
          439  +
          440  +/*
          441  +** Compute a string length that is limited to what can be stored in
          442  +** lower 30 bits of a 32-bit signed integer.
          443  +*/
          444  +static int strlen30(const char *z){
          445  +  const char *z2 = z;
          446  +  while( *z2 ){ z2++; }
          447  +  return 0x3fffffff & (int)(z2 - z);
          448  +}
   432    449   
   433    450   /*
   434    451   ** This routine reads a line of text from FILE in, stores
   435    452   ** the text in memory obtained from malloc() and returns a pointer
   436    453   ** to the text.  NULL is returned at end of file, or if malloc()
   437    454   ** fails.
   438    455   **
................................................................................
   461    478       if( n>0 && zLine[n-1]=='\n' ){
   462    479         n--;
   463    480         if( n>0 && zLine[n-1]=='\r' ) n--;
   464    481         zLine[n] = 0;
   465    482         break;
   466    483       }
   467    484     }
          485  +#if defined(_WIN32) || defined(WIN32)
          486  +  /* For interactive input on Windows systems, translate the 
          487  +  ** multi-byte characterset characters into UTF-8. */
          488  +  if( stdin_is_interactive ){
          489  +    extern char *sqlite3_win32_mbcs_to_utf8(const char*);
          490  +    char *zTrans = sqlite3_win32_mbcs_to_utf8(zLine);
          491  +    if( zTrans ){
          492  +      int nTrans = strlen30(zTrans)+1;
          493  +      if( nTrans>nLine ){
          494  +        zLine = realloc(zLine, nTrans);
          495  +        if( zLine==0 ){
          496  +          sqlite3_free(zTrans);
          497  +          return 0;
          498  +        }
          499  +      }
          500  +      memcpy(zLine, zTrans, nTrans);
          501  +      sqlite3_free(zTrans);
          502  +    }
          503  +  }
          504  +#endif /* defined(_WIN32) || defined(WIN32) */
   468    505     return zLine;
   469    506   }
   470    507   
   471    508   /*
   472    509   ** Retrieve a single line of input text.
   473    510   **
   474    511   ** If in==0 then read from standard input and prompt before each line.
................................................................................
   498    535       zResult = shell_readline(zPrompt);
   499    536       if( zResult && *zResult ) shell_add_history(zResult);
   500    537   #endif
   501    538     }
   502    539     return zResult;
   503    540   }
   504    541   
          542  +/*
          543  +** Render output like fprintf().  Except, if the output is going to the
          544  +** console and if this is running on a Windows machine, translate the
          545  +** output from UTF-8 into MBCS.
          546  +*/
          547  +#if defined(_WIN32) || defined(WIN32)
          548  +void utf8_printf(FILE *out, const char *zFormat, ...){
          549  +  va_list ap;
          550  +  va_start(ap, zFormat);
          551  +  if( stdout_is_console && out==stdout ){
          552  +    extern char *sqlite3_win32_utf8_to_mbcs(const char*);
          553  +    char *z1 = sqlite3_vmprintf(zFormat, ap);
          554  +    char *z2 = sqlite3_win32_utf8_to_mbcs(z1);
          555  +    sqlite3_free(z1);
          556  +    fputs(z2, out);
          557  +    sqlite3_free(z2);
          558  +  }else{
          559  +    vfprintf(out, zFormat, ap);
          560  +  }
          561  +  va_end(ap);
          562  +}
          563  +#else
          564  +# define utf8_printf fprintf
          565  +#endif
          566  +
   505    567   /*
   506    568   ** Shell output mode information from before ".explain on", 
   507    569   ** saved so that it can be restored by ".explain off"
   508    570   */
   509    571   typedef struct SavedModeInfo SavedModeInfo;
   510    572   struct SavedModeInfo {
   511    573     int valid;          /* Is there legit data in here? */
................................................................................
   603    665   #define SEP_Record    "\x1E"
   604    666   
   605    667   /*
   606    668   ** Number of elements in an array
   607    669   */
   608    670   #define ArraySize(X)  (int)(sizeof(X)/sizeof(X[0]))
   609    671   
   610         -/*
   611         -** Compute a string length that is limited to what can be stored in
   612         -** lower 30 bits of a 32-bit signed integer.
   613         -*/
   614         -static int strlen30(const char *z){
   615         -  const char *z2 = z;
   616         -  while( *z2 ){ z2++; }
   617         -  return 0x3fffffff & (int)(z2 - z);
   618         -}
   619         -
   620    672   /*
   621    673   ** A callback for the sqlite3_log() interface.
   622    674   */
   623    675   static void shellLog(void *pArg, int iErrCode, const char *zMsg){
   624    676     ShellState *p = (ShellState*)pArg;
   625    677     if( p->pLog==0 ) return;
   626    678     fprintf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
................................................................................
   645    697     int i;
   646    698     int nSingle = 0;
   647    699     setBinaryMode(out);
   648    700     for(i=0; z[i]; i++){
   649    701       if( z[i]=='\'' ) nSingle++;
   650    702     }
   651    703     if( nSingle==0 ){
   652         -    fprintf(out,"'%s'",z);
          704  +    utf8_printf(out,"'%s'",z);
   653    705     }else{
   654    706       fprintf(out,"'");
   655    707       while( *z ){
   656    708         for(i=0; z[i] && z[i]!='\''; i++){}
   657    709         if( i==0 ){
   658    710           fprintf(out,"''");
   659    711           z++;
   660    712         }else if( z[i]=='\'' ){
   661         -        fprintf(out,"%.*s''",i,z);
          713  +        utf8_printf(out,"%.*s''",i,z);
   662    714           z += i+1;
   663    715         }else{
   664         -        fprintf(out,"%s",z);
          716  +        utf8_printf(out,"%s",z);
   665    717           break;
   666    718         }
   667    719       }
   668    720       fprintf(out,"'");
   669    721     }
   670    722     setTextMode(out);
   671    723   }
................................................................................
   713    765               && z[i]!='<' 
   714    766               && z[i]!='&' 
   715    767               && z[i]!='>' 
   716    768               && z[i]!='\"' 
   717    769               && z[i]!='\'';
   718    770           i++){}
   719    771       if( i>0 ){
   720         -      fprintf(out,"%.*s",i,z);
          772  +      utf8_printf(out,"%.*s",i,z);
   721    773       }
   722    774       if( z[i]=='<' ){
   723    775         fprintf(out,"&lt;");
   724    776       }else if( z[i]=='&' ){
   725    777         fprintf(out,"&amp;");
   726    778       }else if( z[i]=='>' ){
   727    779         fprintf(out,"&gt;");
................................................................................
   764    816   ** the separator, which may or may not be a comma.  p->nullValue is
   765    817   ** the null value.  Strings are quoted if necessary.  The separator
   766    818   ** is only issued if bSep is true.
   767    819   */
   768    820   static void output_csv(ShellState *p, const char *z, int bSep){
   769    821     FILE *out = p->out;
   770    822     if( z==0 ){
   771         -    fprintf(out,"%s",p->nullValue);
          823  +    utf8_printf(out,"%s",p->nullValue);
   772    824     }else{
   773    825       int i;
   774    826       int nSep = strlen30(p->colSeparator);
   775    827       for(i=0; z[i]; i++){
   776    828         if( needCsvQuote[((unsigned char*)z)[i]] 
   777    829            || (z[i]==p->colSeparator[0] && 
   778    830                (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
................................................................................
   784    836         putc('"', out);
   785    837         for(i=0; z[i]; i++){
   786    838           if( z[i]=='"' ) putc('"', out);
   787    839           putc(z[i], out);
   788    840         }
   789    841         putc('"', out);
   790    842       }else{
   791         -      fprintf(out, "%s", z);
          843  +      utf8_printf(out, "%s", z);
   792    844       }
   793    845     }
   794    846     if( bSep ){
   795         -    fprintf(p->out, "%s", p->colSeparator);
          847  +    utf8_printf(p->out, "%s", p->colSeparator);
   796    848     }
   797    849   }
   798    850   
   799    851   #ifdef SIGINT
   800    852   /*
   801    853   ** This routine runs when the user presses Ctrl-C
   802    854   */
................................................................................
   826    878       case MODE_Line: {
   827    879         int w = 5;
   828    880         if( azArg==0 ) break;
   829    881         for(i=0; i<nArg; i++){
   830    882           int len = strlen30(azCol[i] ? azCol[i] : "");
   831    883           if( len>w ) w = len;
   832    884         }
   833         -      if( p->cnt++>0 ) fprintf(p->out, "%s", p->rowSeparator);
          885  +      if( p->cnt++>0 ) utf8_printf(p->out, "%s", p->rowSeparator);
   834    886         for(i=0; i<nArg; i++){
   835         -        fprintf(p->out,"%*s = %s%s", w, azCol[i],
          887  +        utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
   836    888                   azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
   837    889         }
   838    890         break;
   839    891       }
   840    892       case MODE_Explain:
   841    893       case MODE_Column: {
   842    894         if( p->cnt++==0 ){
................................................................................
   854    906               if( w<n ) w = n;
   855    907             }
   856    908             if( i<ArraySize(p->actualWidth) ){
   857    909               p->actualWidth[i] = w;
   858    910             }
   859    911             if( p->showHeader ){
   860    912               if( w<0 ){
   861         -              fprintf(p->out,"%*.*s%s",-w,-w,azCol[i],
          913  +              utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
   862    914                         i==nArg-1 ? p->rowSeparator : "  ");
   863    915               }else{
   864         -              fprintf(p->out,"%-*.*s%s",w,w,azCol[i],
          916  +              utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i],
   865    917                         i==nArg-1 ? p->rowSeparator : "  ");
   866    918               }
   867    919             }
   868    920           }
   869    921           if( p->showHeader ){
   870    922             for(i=0; i<nArg; i++){
   871    923               int w;
   872    924               if( i<ArraySize(p->actualWidth) ){
   873    925                  w = p->actualWidth[i];
   874    926                  if( w<0 ) w = -w;
   875    927               }else{
   876    928                  w = 10;
   877    929               }
   878         -            fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
          930  +            fprintf(p->out,"%-*.*s%s",w,w,
          931  +                   "----------------------------------------------------------"
   879    932                      "----------------------------------------------------------",
   880    933                       i==nArg-1 ? p->rowSeparator : "  ");
   881    934             }
   882    935           }
   883    936         }
   884    937         if( azArg==0 ) break;
   885    938         for(i=0; i<nArg; i++){
................................................................................
   895    948           if( i==1 && p->aiIndent && p->pStmt ){
   896    949             if( p->iIndent<p->nIndent ){
   897    950               fprintf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
   898    951             }
   899    952             p->iIndent++;
   900    953           }
   901    954           if( w<0 ){
   902         -          fprintf(p->out,"%*.*s%s",-w,-w,
          955  +          utf8_printf(p->out,"%*.*s%s",-w,-w,
   903    956                 azArg[i] ? azArg[i] : p->nullValue,
   904    957                 i==nArg-1 ? p->rowSeparator : "  ");
   905    958           }else{
   906         -          fprintf(p->out,"%-*.*s%s",w,w,
          959  +          utf8_printf(p->out,"%-*.*s%s",w,w,
   907    960                 azArg[i] ? azArg[i] : p->nullValue,
   908    961                 i==nArg-1 ? p->rowSeparator : "  ");
   909    962           }
   910    963         }
   911    964         break;
   912    965       }
   913    966       case MODE_Semi:
   914    967       case MODE_List: {
   915    968         if( p->cnt++==0 && p->showHeader ){
   916    969           for(i=0; i<nArg; i++){
   917         -          fprintf(p->out,"%s%s",azCol[i],
          970  +          utf8_printf(p->out,"%s%s",azCol[i],
   918    971                     i==nArg-1 ? p->rowSeparator : p->colSeparator);
   919    972           }
   920    973         }
   921    974         if( azArg==0 ) break;
   922    975         for(i=0; i<nArg; i++){
   923    976           char *z = azArg[i];
   924    977           if( z==0 ) z = p->nullValue;
   925         -        fprintf(p->out, "%s", z);
          978  +        utf8_printf(p->out, "%s", z);
   926    979           if( i<nArg-1 ){
   927         -          fprintf(p->out, "%s", p->colSeparator);
          980  +          utf8_printf(p->out, "%s", p->colSeparator);
   928    981           }else if( p->mode==MODE_Semi ){
   929         -          fprintf(p->out, ";%s", p->rowSeparator);
          982  +          utf8_printf(p->out, ";%s", p->rowSeparator);
   930    983           }else{
   931         -          fprintf(p->out, "%s", p->rowSeparator);
          984  +          utf8_printf(p->out, "%s", p->rowSeparator);
   932    985           }
   933    986         }
   934    987         break;
   935    988       }
   936    989       case MODE_Html: {
   937    990         if( p->cnt++==0 && p->showHeader ){
   938    991           fprintf(p->out,"<TR>");
................................................................................
   953   1006         fprintf(p->out,"</TR>\n");
   954   1007         break;
   955   1008       }
   956   1009       case MODE_Tcl: {
   957   1010         if( p->cnt++==0 && p->showHeader ){
   958   1011           for(i=0; i<nArg; i++){
   959   1012             output_c_string(p->out,azCol[i] ? azCol[i] : "");
   960         -          if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
         1013  +          if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
   961   1014           }
   962         -        fprintf(p->out, "%s", p->rowSeparator);
         1015  +        utf8_printf(p->out, "%s", p->rowSeparator);
   963   1016         }
   964   1017         if( azArg==0 ) break;
   965   1018         for(i=0; i<nArg; i++){
   966   1019           output_c_string(p->out, azArg[i] ? azArg[i] : p->nullValue);
   967         -        if(i<nArg-1) fprintf(p->out, "%s", p->colSeparator);
         1020  +        if(i<nArg-1) utf8_printf(p->out, "%s", p->colSeparator);
   968   1021         }
   969         -      fprintf(p->out, "%s", p->rowSeparator);
         1022  +      utf8_printf(p->out, "%s", p->rowSeparator);
   970   1023         break;
   971   1024       }
   972   1025       case MODE_Csv: {
   973   1026         setBinaryMode(p->out);
   974   1027         if( p->cnt++==0 && p->showHeader ){
   975   1028           for(i=0; i<nArg; i++){
   976   1029             output_csv(p, azCol[i] ? azCol[i] : "", i<nArg-1);
   977   1030           }
   978         -        fprintf(p->out, "%s", p->rowSeparator);
         1031  +        utf8_printf(p->out, "%s", p->rowSeparator);
   979   1032         }
   980   1033         if( nArg>0 ){
   981   1034           for(i=0; i<nArg; i++){
   982   1035             output_csv(p, azArg[i], i<nArg-1);
   983   1036           }
   984         -        fprintf(p->out, "%s", p->rowSeparator);
         1037  +        utf8_printf(p->out, "%s", p->rowSeparator);
   985   1038         }
   986   1039         setTextMode(p->out);
   987   1040         break;
   988   1041       }
   989   1042       case MODE_Insert: {
   990   1043         p->cnt++;
   991   1044         if( azArg==0 ) break;
   992         -      fprintf(p->out,"INSERT INTO %s",p->zDestTable);
         1045  +      utf8_printf(p->out,"INSERT INTO %s",p->zDestTable);
   993   1046         if( p->showHeader ){
   994   1047           fprintf(p->out,"(");
   995   1048           for(i=0; i<nArg; i++){
   996   1049             char *zSep = i>0 ? ",": "";
   997         -          fprintf(p->out, "%s%s", zSep, azCol[i]);
         1050  +          utf8_printf(p->out, "%s%s", zSep, azCol[i]);
   998   1051           }
   999   1052           fprintf(p->out,")");
  1000   1053         }
  1001   1054         fprintf(p->out," VALUES(");
  1002   1055         for(i=0; i<nArg; i++){
  1003   1056           char *zSep = i>0 ? ",": "";
  1004   1057           if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
  1005   1058             fprintf(p->out,"%sNULL",zSep);
  1006   1059           }else if( aiType && aiType[i]==SQLITE_TEXT ){
  1007   1060             if( zSep[0] ) fprintf(p->out,"%s",zSep);
  1008   1061             output_quoted_string(p->out, azArg[i]);
  1009   1062           }else if( aiType && (aiType[i]==SQLITE_INTEGER
  1010   1063                                || aiType[i]==SQLITE_FLOAT) ){
  1011         -          fprintf(p->out,"%s%s",zSep, azArg[i]);
         1064  +          utf8_printf(p->out,"%s%s",zSep, azArg[i]);
  1012   1065           }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
  1013   1066             const void *pBlob = sqlite3_column_blob(p->pStmt, i);
  1014   1067             int nBlob = sqlite3_column_bytes(p->pStmt, i);
  1015   1068             if( zSep[0] ) fprintf(p->out,"%s",zSep);
  1016   1069             output_hex_blob(p->out, pBlob, nBlob);
  1017   1070           }else if( isNumber(azArg[i], 0) ){
  1018         -          fprintf(p->out,"%s%s",zSep, azArg[i]);
         1071  +          utf8_printf(p->out,"%s%s",zSep, azArg[i]);
  1019   1072           }else{
  1020   1073             if( zSep[0] ) fprintf(p->out,"%s",zSep);
  1021   1074             output_quoted_string(p->out, azArg[i]);
  1022   1075           }
  1023   1076         }
  1024   1077         fprintf(p->out,");\n");
  1025   1078         break;
  1026   1079       }
  1027   1080       case MODE_Ascii: {
  1028   1081         if( p->cnt++==0 && p->showHeader ){
  1029   1082           for(i=0; i<nArg; i++){
  1030         -          if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
  1031         -          fprintf(p->out,"%s",azCol[i] ? azCol[i] : "");
         1083  +          if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
         1084  +          utf8_printf(p->out,"%s",azCol[i] ? azCol[i] : "");
  1032   1085           }
  1033         -        fprintf(p->out, "%s", p->rowSeparator);
         1086  +        utf8_printf(p->out, "%s", p->rowSeparator);
  1034   1087         }
  1035   1088         if( azArg==0 ) break;
  1036   1089         for(i=0; i<nArg; i++){
  1037         -        if( i>0 ) fprintf(p->out, "%s", p->colSeparator);
  1038         -        fprintf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
         1090  +        if( i>0 ) utf8_printf(p->out, "%s", p->colSeparator);
         1091  +        utf8_printf(p->out,"%s",azArg[i] ? azArg[i] : p->nullValue);
  1039   1092         }
  1040         -      fprintf(p->out, "%s", p->rowSeparator);
         1093  +      utf8_printf(p->out, "%s", p->rowSeparator);
  1041   1094         break;
  1042   1095       }
  1043   1096     }
  1044   1097     return 0;
  1045   1098   }
  1046   1099   
  1047   1100   /*
................................................................................
  1163   1216       if( (rc&0xff)!=SQLITE_CORRUPT ) p->nErr++;
  1164   1217       return rc;
  1165   1218     }
  1166   1219     rc = sqlite3_step(pSelect);
  1167   1220     nResult = sqlite3_column_count(pSelect);
  1168   1221     while( rc==SQLITE_ROW ){
  1169   1222       if( zFirstRow ){
  1170         -      fprintf(p->out, "%s", zFirstRow);
         1223  +      utf8_printf(p->out, "%s", zFirstRow);
  1171   1224         zFirstRow = 0;
  1172   1225       }
  1173   1226       z = (const char*)sqlite3_column_text(pSelect, 0);
  1174         -    fprintf(p->out, "%s", z);
         1227  +    utf8_printf(p->out, "%s", z);
  1175   1228       for(i=1; i<nResult; i++){ 
  1176         -      fprintf(p->out, ",%s", sqlite3_column_text(pSelect, i));
         1229  +      utf8_printf(p->out, ",%s", sqlite3_column_text(pSelect, i));
  1177   1230       }
  1178   1231       if( z==0 ) z = "";
  1179   1232       while( z[0] && (z[0]!='-' || z[1]!='-') ) z++;
  1180   1233       if( z[0] ){
  1181   1234         fprintf(p->out, "\n;\n");
  1182   1235       }else{
  1183   1236         fprintf(p->out, ";\n");
................................................................................
  1357   1410           rEstLoop = (double)nLoop;
  1358   1411           if( k>0 ) fprintf(pArg->out, "-------- subquery %d -------\n", k);
  1359   1412         }
  1360   1413         n++;
  1361   1414         sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_NVISIT, (void*)&nVisit);
  1362   1415         sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EST, (void*)&rEst);
  1363   1416         sqlite3_stmt_scanstatus(p, i, SQLITE_SCANSTAT_EXPLAIN, (void*)&zExplain);
  1364         -      fprintf(pArg->out, "Loop %2d: %s\n", n, zExplain);
         1417  +      utf8_printf(pArg->out, "Loop %2d: %s\n", n, zExplain);
  1365   1418         rEstLoop *= rEst;
  1366   1419         fprintf(pArg->out, 
  1367   1420             "         nLoop=%-8lld nRow=%-8lld estRow=%-8lld estRow/Loop=%-8g\n",
  1368   1421             nLoop, nVisit, (sqlite3_int64)(rEstLoop+0.5), rEst
  1369   1422         );
  1370   1423       }
  1371   1424     }
................................................................................
  1518   1571           pArg->pStmt = pStmt;
  1519   1572           pArg->cnt = 0;
  1520   1573         }
  1521   1574   
  1522   1575         /* echo the sql statement if echo on */
  1523   1576         if( pArg && pArg->echoOn ){
  1524   1577           const char *zStmtSql = sqlite3_sql(pStmt);
  1525         -        fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
         1578  +        utf8_printf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
  1526   1579         }
  1527   1580   
  1528   1581         /* Show the EXPLAIN QUERY PLAN if .eqp is on */
  1529   1582         if( pArg && pArg->autoEQP ){
  1530   1583           sqlite3_stmt *pExplain;
  1531   1584           char *zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s",
  1532   1585                                        sqlite3_sql(pStmt));
  1533   1586           rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0);
  1534   1587           if( rc==SQLITE_OK ){
  1535   1588             while( sqlite3_step(pExplain)==SQLITE_ROW ){
  1536   1589               fprintf(pArg->out,"--EQP-- %d,", sqlite3_column_int(pExplain, 0));
  1537   1590               fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 1));
  1538   1591               fprintf(pArg->out,"%d,", sqlite3_column_int(pExplain, 2));
  1539         -            fprintf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
         1592  +            utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
  1540   1593             }
  1541   1594           }
  1542   1595           sqlite3_finalize(pExplain);
  1543   1596           sqlite3_free(zEQP);
  1544   1597         }
  1545   1598   
  1546   1599         /* If the shell is currently in ".explain" mode, gather the extra
................................................................................
  1673   1726         fprintf(p->out, "PRAGMA writable_schema=ON;\n");
  1674   1727         p->writableSchema = 1;
  1675   1728       }
  1676   1729       zIns = sqlite3_mprintf(
  1677   1730          "INSERT INTO sqlite_master(type,name,tbl_name,rootpage,sql)"
  1678   1731          "VALUES('table','%q','%q',0,'%q');",
  1679   1732          zTable, zTable, zSql);
  1680         -    fprintf(p->out, "%s\n", zIns);
         1733  +    utf8_printf(p->out, "%s\n", zIns);
  1681   1734       sqlite3_free(zIns);
  1682   1735       return 0;
  1683   1736     }else{
  1684         -    fprintf(p->out, "%s;\n", zSql);
         1737  +    utf8_printf(p->out, "%s;\n", zSql);
  1685   1738     }
  1686   1739   
  1687   1740     if( strcmp(zType, "table")==0 ){
  1688   1741       sqlite3_stmt *pTableInfo = 0;
  1689   1742       char *zSelect = 0;
  1690   1743       char *zTableInfo = 0;
  1691   1744       char *zTmp = 0;
................................................................................
  2122   2175   ** A routine for handling output from sqlite3_trace().
  2123   2176   */
  2124   2177   static void sql_trace_callback(void *pArg, const char *z){
  2125   2178     FILE *f = (FILE*)pArg;
  2126   2179     if( f ){
  2127   2180       int i = (int)strlen(z);
  2128   2181       while( i>0 && z[i-1]==';' ){ i--; }
  2129         -    fprintf(f, "%.*s;\n", i, z);
         2182  +    utf8_printf(f, "%.*s;\n", i, z);
  2130   2183     }
  2131   2184   }
  2132   2185   
  2133   2186   /*
  2134   2187   ** A no-op routine that runs with the ".breakpoint" doc-command.  This is
  2135   2188   ** a useful spot to set a debugger breakpoint.
  2136   2189   */
................................................................................
  2605   2658     }else{
  2606   2659       zSchemaTab = sqlite3_mprintf("\"%w\".sqlite_master", zDb);
  2607   2660     }
  2608   2661     for(i=0; i<ArraySize(aQuery); i++){
  2609   2662       char *zSql = sqlite3_mprintf(aQuery[i].zSql, zSchemaTab);
  2610   2663       int val = db_int(p, zSql);
  2611   2664       sqlite3_free(zSql);
  2612         -    fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
         2665  +    utf8_printf(p->out, "%-20s %d\n", aQuery[i].zName, val);
  2613   2666     }
  2614   2667     sqlite3_free(zSchemaTab);
  2615   2668     return 0;
  2616   2669   }
  2617   2670   
  2618   2671   /*
  2619   2672   ** Print the current sqlite3_errmsg() value to stderr and return 1.
................................................................................
  3445   3498       }
  3446   3499     }else
  3447   3500   
  3448   3501     if( c=='p' && n>=3 && strncmp(azArg[0], "print", n)==0 ){
  3449   3502       int i;
  3450   3503       for(i=1; i<nArg; i++){
  3451   3504         if( i>1 ) fprintf(p->out, " ");
  3452         -      fprintf(p->out, "%s", azArg[i]);
         3505  +      utf8_printf(p->out, "%s", azArg[i]);
  3453   3506       }
  3454   3507       fprintf(p->out, "\n");
  3455   3508     }else
  3456   3509   
  3457   3510     if( c=='p' && strncmp(azArg[0], "prompt", n)==0 ){
  3458   3511       if( nArg >= 2) {
  3459   3512         strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
................................................................................
  3639   3692     /* Undocumented commands for internal testing.  Subject to change
  3640   3693     ** without notice. */
  3641   3694     if( c=='s' && n>=10 && strncmp(azArg[0], "selftest-", 9)==0 ){
  3642   3695       if( strncmp(azArg[0]+9, "boolean", n-9)==0 ){
  3643   3696         int i, v;
  3644   3697         for(i=1; i<nArg; i++){
  3645   3698           v = booleanValue(azArg[i]);
  3646         -        fprintf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
         3699  +        utf8_printf(p->out, "%s: %d 0x%x\n", azArg[i], v, v);
  3647   3700         }
  3648   3701       }
  3649   3702       if( strncmp(azArg[0]+9, "integer", n-9)==0 ){
  3650   3703         int i; sqlite3_int64 v;
  3651   3704         for(i=1; i<nArg; i++){
  3652   3705           char zBuf[200];
  3653   3706           v = integerValue(azArg[i]);
  3654   3707           sqlite3_snprintf(sizeof(zBuf),zBuf,"%s: %lld 0x%llx\n", azArg[i],v,v);
  3655         -        fprintf(p->out, "%s", zBuf);
         3708  +        utf8_printf(p->out, "%s", zBuf);
  3656   3709         }
  3657   3710       }
  3658   3711     }else
  3659   3712   #endif
  3660   3713   
  3661   3714     if( c=='s' && strncmp(azArg[0], "separator", n)==0 ){
  3662   3715       if( nArg<2 || nArg>3 ){
................................................................................
  3822   3875         }
  3823   3876         nPrintCol = 80/(maxlen+2);
  3824   3877         if( nPrintCol<1 ) nPrintCol = 1;
  3825   3878         nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
  3826   3879         for(i=0; i<nPrintRow; i++){
  3827   3880           for(j=i; j<nRow; j+=nPrintRow){
  3828   3881             char *zSp = j<nPrintRow ? "" : "  ";
  3829         -          fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
         3882  +          utf8_printf(p->out, "%s%-*s", zSp, maxlen,
         3883  +                      azResult[j] ? azResult[j]:"");
  3830   3884           }
  3831   3885           fprintf(p->out, "\n");
  3832   3886         }
  3833   3887       }
  3834   3888   
  3835   3889       for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
  3836   3890       sqlite3_free(azResult);
................................................................................
  4543   4597     }
  4544   4598   #endif
  4545   4599     setBinaryMode(stdin);
  4546   4600     setvbuf(stderr, 0, _IONBF, 0); /* Make sure stderr is unbuffered */
  4547   4601     Argv0 = argv[0];
  4548   4602     main_init(&data);
  4549   4603     stdin_is_interactive = isatty(0);
         4604  +  stdout_is_console = isatty(1);
  4550   4605   
  4551   4606     /* Make sure we have a valid signal handler early, before anything
  4552   4607     ** else is done.
  4553   4608     */
  4554   4609   #ifdef SIGINT
  4555   4610     signal(SIGINT, interrupt_handler);
  4556   4611   #endif