Skip to content

Commit 617ce96

Browse files
kbleesgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Stepan Kasal <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a15d4af commit 617ce96

File tree

2 files changed

+22
-6
lines changed

2 files changed

+22
-6
lines changed

compat/mingw.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,9 +320,11 @@ int mingw_raise(int sig);
320320
int winansi_fputs(const char *str, FILE *stream);
321321
int winansi_printf(const char *format, ...) __attribute__((format (printf, 1, 2)));
322322
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);
323324
#define fputs winansi_fputs
324325
#define printf(...) winansi_printf(__VA_ARGS__)
325326
#define fprintf(...) winansi_fprintf(__VA_ARGS__)
327+
#define vfprintf winansi_vfprintf
326328

327329
/*
328330
* git specific compatibility

compat/winansi.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
*/
44

55
#include "../git-compat-util.h"
6+
#include <malloc.h>
67

78
/*
89
Functions to be wrapped:
910
*/
1011
#undef printf
1112
#undef fprintf
1213
#undef fputs
14+
#undef vfprintf
1315
/* TODO: write */
1416

1517
/*
@@ -46,6 +48,18 @@ static void init(void)
4648
initialized = 1;
4749
}
4850

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+
}
4963

5064
#define FOREGROUND_ALL (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
5165
#define BACKGROUND_ALL (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE)
@@ -245,13 +259,15 @@ static int ansi_emulate(const char *str, FILE *stream)
245259
int rv = 0;
246260
const char *pos = str;
247261

262+
fflush(stream);
263+
248264
while (*pos) {
249265
pos = strstr(str, "\033[");
250266
if (pos) {
251267
size_t len = pos - str;
252268

253269
if (len) {
254-
size_t out_len = fwrite(str, 1, len, stream);
270+
size_t out_len = write_console(str, len);
255271
rv += out_len;
256272
if (out_len < len)
257273
return rv;
@@ -260,14 +276,12 @@ static int ansi_emulate(const char *str, FILE *stream)
260276
str = pos + 2;
261277
rv += 2;
262278

263-
fflush(stream);
264-
265279
pos = set_attr(str);
266280
rv += pos - str;
267281
str = pos;
268282
} else {
269-
rv += strlen(str);
270-
fputs(str, stream);
283+
size_t len = strlen(str);
284+
rv += write_console(str, len);
271285
return rv;
272286
}
273287
}
@@ -294,7 +308,7 @@ int winansi_fputs(const char *str, FILE *stream)
294308
return EOF;
295309
}
296310

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)
298312
{
299313
int len, rv;
300314
char small_buf[256];

0 commit comments

Comments
 (0)