| | @@ -1116,47 +1116,65 @@ |
| 1116 | 1116 | #endif |
| 1117 | 1117 | return zValue; |
| 1118 | 1118 | } |
| 1119 | 1119 | |
| 1120 | 1120 | /* |
| 1121 | | -** Translate UTF8 to MBCS for display on the console. Return a pointer to the |
| 1122 | | -** translated text.. Call fossil_mbcs_free() to deallocate any memory |
| 1123 | | -** used to store the returned pointer when done. |
| 1121 | +** Display UTF8 on the console. Return the number of |
| 1122 | +** Characters written. If stdout or stderr is redirected |
| 1123 | +** to a file, so it is not a console, -1 is returned and |
| 1124 | +** nothing is written. |
| 1124 | 1125 | */ |
| 1125 | | -char *fossil_utf8_to_console(const char *zUtf8){ |
| 1126 | +int fossil_utf8_to_console(const char *zUtf8, int nByte, int toStdErr){ |
| 1126 | 1127 | #ifdef _WIN32 |
| 1127 | | - int nChar, nByte; |
| 1128 | + int nChar; |
| 1128 | 1129 | WCHAR *zUnicode; /* Unicode version of zUtf8 */ |
| 1129 | 1130 | char *zConsole; /* Console version of zUtf8 */ |
| 1130 | 1131 | int codepage; /* Console code page */ |
| 1131 | 1132 | |
| 1132 | | - nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, NULL, 0); |
| 1133 | | - zUnicode = malloc( nChar*sizeof(zUnicode[0]) ); |
| 1133 | + static int once = 1; |
| 1134 | + static int istty[2]; |
| 1135 | + if( once ){ |
| 1136 | + istty[0] = _isatty(fileno(stdout)); |
| 1137 | + istty[1] = _isatty(fileno(stderr)); |
| 1138 | + once = 0; |
| 1139 | + } |
| 1140 | + if( !istty[toStdErr] ){ |
| 1141 | + /* stdout/stderr is not a console. */ |
| 1142 | + return -1; |
| 1143 | + } |
| 1144 | + |
| 1145 | + nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, nByte, NULL, 0); |
| 1146 | + zUnicode = malloc( (nChar + 1) *sizeof(zUnicode[0]) ); |
| 1134 | 1147 | if( zUnicode==0 ){ |
| 1135 | 1148 | return 0; |
| 1136 | 1149 | } |
| 1137 | | - nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar); |
| 1150 | + nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, nByte, zUnicode, nChar); |
| 1138 | 1151 | if( nChar==0 ){ |
| 1139 | 1152 | free(zUnicode); |
| 1140 | 1153 | return 0; |
| 1141 | 1154 | } |
| 1155 | + zUnicode[nChar] = '\0'; |
| 1142 | 1156 | codepage = GetConsoleCP(); |
| 1143 | | - nByte = WideCharToMultiByte(codepage, 0, zUnicode, -1, 0, 0, 0, 0); |
| 1144 | | - zConsole = malloc( nByte ); |
| 1157 | + nByte = WideCharToMultiByte(codepage, 0, zUnicode, nChar, 0, 0, 0, 0); |
| 1158 | + zConsole = malloc( nByte + 1); |
| 1145 | 1159 | if( zConsole==0 ){ |
| 1146 | 1160 | free(zUnicode); |
| 1147 | 1161 | return 0; |
| 1148 | 1162 | } |
| 1149 | | - nByte = WideCharToMultiByte(codepage, 0, zUnicode, -1, zConsole, nByte, 0, 0); |
| 1163 | + nByte = WideCharToMultiByte(codepage, 0, zUnicode, nChar, zConsole, nByte, 0, 0); |
| 1164 | + zConsole[nByte] = '\0'; |
| 1150 | 1165 | free(zUnicode); |
| 1151 | 1166 | if( nByte == 0 ){ |
| 1152 | 1167 | free(zConsole); |
| 1153 | 1168 | zConsole = 0; |
| 1169 | + return 0; |
| 1154 | 1170 | } |
| 1155 | | - return zConsole; |
| 1171 | + fwrite(zConsole, 1, nByte, toStdErr ? stderr : stdout); |
| 1172 | + fflush(toStdErr ? stderr : stdout); |
| 1173 | + return nChar; |
| 1156 | 1174 | #else |
| 1157 | | - return (char*)zUtf8; /* No-op on unix */ |
| 1175 | + return -1; /* No-op on unix */ |
| 1158 | 1176 | #endif |
| 1159 | 1177 | } |
| 1160 | 1178 | |
| 1161 | 1179 | /* |
| 1162 | 1180 | ** Translate MBCS to UTF8. Return a pointer. Call fossil_mbcs_free() |
| 1163 | 1181 | |