From 486e06ff867b4b09af30f51df2b9f390182f2878 Mon Sep 17 00:00:00 2001 From: Peter Harris Date: Wed, 9 Jul 2008 17:15:29 -0400 Subject: [PATCH] Windows ANSI - hook write() --- compat/mingw.h | 2 ++ compat/winansi.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/compat/mingw.h b/compat/mingw.h index 5f11114890..5d5a990c01 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -200,9 +200,11 @@ sig_handler_t mingw_signal(int sig, sig_handler_t handler); 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_write(int fd, const void *buf, size_t count); #define fputs winansi_fputs #define printf(...) winansi_printf(__VA_ARGS__) #define fprintf(...) winansi_fprintf(__VA_ARGS__) +#define write winansi_write /* * git specific compatibility diff --git a/compat/winansi.c b/compat/winansi.c index da13c3cf78..4266625dd2 100644 --- a/compat/winansi.c +++ b/compat/winansi.c @@ -11,7 +11,7 @@ #undef printf #undef fprintf #undef fputs -/* TODO: write */ +#undef write /* ANSI codes used by git: m, K @@ -379,3 +379,50 @@ int winansi_printf(const char *format, ...) return rv; } + +int winansi_write(int fd, const void *buf, size_t count) +{ + int rv = 0; + const char *pos = buf; + + init(); + + if (!console) + goto abort; + + if (!isatty(fd)) + goto abort; + + while (count) { + pos = memchr(buf, '\033', count - 1); + while (pos && pos[1] != '[') + pos = memchr(pos + 1, '\033', count - (pos - (char *)buf) - 2); + + if (pos) { + size_t len = pos - (const char *)buf; + + if (len) { + int output_len = write(fd, buf, len); + if (output_len <= 0 && rv) + return rv; + if (output_len < len) + return rv + output_len; + } + + pos = set_attr(pos + 2); + rv += pos - (const char *)buf; + count -= pos - (const char *)buf; + buf = pos; + } else { + int output_len; + output_len = write(fd, buf, count); + if (output_len > 0 || rv == 0) + rv += output_len; + return rv; + } + } + return rv; + +abort: + return write(fd, buf, count); +} -- 2.11.4.GIT