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];