summaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
authorLibravatar Karsten Blees <blees@dcon.de>2010-07-31 00:04:01 +0000
committerLibravatar Junio C Hamano <gitster@pobox.com>2014-06-10 13:32:37 -0700
commit617ce965aa3e5d44d0292c9094ee692f161a55d0 (patch)
tree3365f021f94a1e0f1a28ff440537c649b4d4e8b3 /compat
parentmingw: avoid const warning (diff)
downloadtgif-617ce965aa3e5d44d0292c9094ee692f161a55d0.tar.xz
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>
Diffstat (limited to 'compat')
-rw-r--r--compat/mingw.h2
-rw-r--r--compat/winansi.c26
2 files changed, 22 insertions, 6 deletions
diff --git a/compat/mingw.h b/compat/mingw.h
index 6dc8b1a1b4..d3cffb7994 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -320,9 +320,11 @@ int mingw_raise(int sig);
int winansi_fputs(const char *str, FILE *stream);
int winansi_printf(const char *format, ...) __attribute__((format (printf, 1, 2)));
int winansi_fprintf(FILE *stream, const char *format, ...) __attribute__((format (printf, 2, 3)));
+int winansi_vfprintf(FILE *stream, const char *format, va_list list);
#define fputs winansi_fputs
#define printf(...) winansi_printf(__VA_ARGS__)
#define fprintf(...) winansi_fprintf(__VA_ARGS__)
+#define vfprintf winansi_vfprintf
/*
* git specific compatibility
diff --git a/compat/winansi.c b/compat/winansi.c
index dedce2104e..abe0feaa2c 100644
--- a/compat/winansi.c
+++ b/compat/winansi.c
@@ -3,6 +3,7 @@
*/
#include "../git-compat-util.h"
+#include <malloc.h>
/*
Functions to be wrapped:
@@ -10,6 +11,7 @@
#undef printf
#undef fprintf
#undef fputs
+#undef vfprintf
/* TODO: write */
/*
@@ -46,6 +48,18 @@ static void init(void)
initialized = 1;
}
+static int write_console(const char *str, size_t len)
+{
+ /* convert utf-8 to utf-16, write directly to console */
+ int wlen = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
+ wchar_t *wbuf = (wchar_t *) alloca(wlen * sizeof(wchar_t));
+ MultiByteToWideChar(CP_UTF8, 0, str, len, wbuf, wlen);
+
+ WriteConsoleW(console, wbuf, wlen, NULL, NULL);
+
+ /* return original (utf-8 encoded) length */
+ return len;
+}
#define FOREGROUND_ALL (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
#define BACKGROUND_ALL (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE)
@@ -245,13 +259,15 @@ static int ansi_emulate(const char *str, FILE *stream)
int rv = 0;
const char *pos = str;
+ fflush(stream);
+
while (*pos) {
pos = strstr(str, "\033[");
if (pos) {
size_t len = pos - str;
if (len) {
- size_t out_len = fwrite(str, 1, len, stream);
+ size_t out_len = write_console(str, len);
rv += out_len;
if (out_len < len)
return rv;
@@ -260,14 +276,12 @@ static int ansi_emulate(const char *str, FILE *stream)
str = pos + 2;
rv += 2;
- fflush(stream);
-
pos = set_attr(str);
rv += pos - str;
str = pos;
} else {
- rv += strlen(str);
- fputs(str, stream);
+ size_t len = strlen(str);
+ rv += write_console(str, len);
return rv;
}
}
@@ -294,7 +308,7 @@ int winansi_fputs(const char *str, FILE *stream)
return EOF;
}
-static int winansi_vfprintf(FILE *stream, const char *format, va_list list)
+int winansi_vfprintf(FILE *stream, const char *format, va_list list)
{
int len, rv;
char small_buf[256];