Win32: support Unicode console output

WriteConsoleW seems to be the only way to reliably print unicode to the console (without weird code page conversions). Also redirects vfprintf to the winansi.c version. Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Stepan Kasal <kasal@ucw.cz> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Karsten Blees committed Jul 31, 2010 at 00:04 UTC 617ce965aa3e5d44d0292c9094ee692f161a55d0
2 files changed +22 -6
compat/mingw.h
+2
@@ -320,9 +320,11 @@ int mingw_raise(int sig);
320 int winansi_fputs(const char *str, FILE *stream);
321 int winansi_printf(const char *format, ...) __attribute__((format (printf, 1, 2)));
322 int winansi_fprintf(FILE *stream, const char *format, ...) __attribute__((format (printf, 2, 3)));
323 +int winansi_vfprintf(FILE *stream, const char *format, va_list list);
324 #define fputs winansi_fputs
325 #define printf(...) winansi_printf(__VA_ARGS__)
326 #define fprintf(...) winansi_fprintf(__VA_ARGS__)
327 +#define vfprintf winansi_vfprintf
328
329 /*
330 * git specific compatibility
compat/winansi.c
+20 -6
@@ -3,6 +3,7 @@
3 */
4
5 #include "../git-compat-util.h"
6 +#include <malloc.h>
7
8 /*
9 Functions to be wrapped:
@@ -10,6 +11,7 @@
11 #undef printf
12 #undef fprintf
13 #undef fputs
14 +#undef vfprintf
15 /* TODO: write */
16
17 /*
@@ -46,6 +48,18 @@ static void init(void)
48 initialized = 1;
49 }
50
51 +static int write_console(const char *str, size_t len)
52 +{
53 + /* convert utf-8 to utf-16, write directly to console */
54 + int wlen = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
55 + wchar_t *wbuf = (wchar_t *) alloca(wlen * sizeof(wchar_t));
56 + MultiByteToWideChar(CP_UTF8, 0, str, len, wbuf, wlen);
57 +
58 + WriteConsoleW(console, wbuf, wlen, NULL, NULL);
59 +
60 + /* return original (utf-8 encoded) length */
61 + return len;
62 +}
63
64 #define FOREGROUND_ALL (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
65 #define BACKGROUND_ALL (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE)
@@ -245,13 +259,15 @@ static int ansi_emulate(const char *str, FILE *stream)
259 int rv = 0;
260 const char *pos = str;
261
262 + fflush(stream);
263 +
264 while (*pos) {
265 pos = strstr(str, "\033[");
266 if (pos) {
267 size_t len = pos - str;
268
269 if (len) {
254 - size_t out_len = fwrite(str, 1, len, stream);
270 + size_t out_len = write_console(str, len);
271 rv += out_len;
272 if (out_len < len)
273 return rv;
@@ -260,14 +276,12 @@ static int ansi_emulate(const char *str, FILE *stream)
276 str = pos + 2;
277 rv += 2;
278
263 - fflush(stream);
264 -
279 pos = set_attr(str);
280 rv += pos - str;
281 str = pos;
282 } else {
269 - rv += strlen(str);
270 - fputs(str, stream);
283 + size_t len = strlen(str);
284 + rv += write_console(str, len);
285 return rv;
286 }
287 }
@@ -294,7 +308,7 @@ int winansi_fputs(const char *str, FILE *stream)
308 return EOF;
309 }
310
297 -static int winansi_vfprintf(FILE *stream, const char *format, va_list list)
311 +int winansi_vfprintf(FILE *stream, const char *format, va_list list)
312 {
313 int len, rv;
314 char small_buf[256];