2 * Copyright 2008 Peter Harris <git@peter.is-a-geek.org>
6 #include "../git-compat-util.h"
9 Functions to be wrapped:
17 ANSI codes used by git: m, K
19 This file is git-specific. Therefore, this file does not attempt
20 to implement any codes that are not used by git.
25 static HANDLE console;
26 static WORD plain_attr;
30 static void init(void)
32 CONSOLE_SCREEN_BUFFER_INFO sbi;
34 static int initialized = 0;
38 console = GetStdHandle(STD_OUTPUT_HANDLE);
39 if (console == INVALID_HANDLE_VALUE)
45 GetConsoleScreenBufferInfo(console, &sbi);
46 attr = plain_attr = sbi.wAttributes;
53 #define FOREGROUND_ALL (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
54 #define BACKGROUND_ALL (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE)
56 static void set_console_attr(void)
58 WORD attributes = attr;
60 attributes &= ~FOREGROUND_ALL;
61 attributes &= ~BACKGROUND_ALL;
63 /* This could probably use a bitmask
64 instead of a series of ifs */
65 if (attr & FOREGROUND_RED)
66 attributes |= BACKGROUND_RED;
67 if (attr & FOREGROUND_GREEN)
68 attributes |= BACKGROUND_GREEN;
69 if (attr & FOREGROUND_BLUE)
70 attributes |= BACKGROUND_BLUE;
72 if (attr & BACKGROUND_RED)
73 attributes |= FOREGROUND_RED;
74 if (attr & BACKGROUND_GREEN)
75 attributes |= FOREGROUND_GREEN;
76 if (attr & BACKGROUND_BLUE)
77 attributes |= FOREGROUND_BLUE;
79 SetConsoleTextAttribute(console, attributes);
82 static const char *set_attr(const char *str)
85 size_t len = strspn(str, "0123456789;");
91 long val = strtol(str, (char **)&str, 10);
98 attr |= FOREGROUND_INTENSITY;
101 case 22: /* normal */
102 attr &= ~FOREGROUND_INTENSITY;
107 case 4: /* underline */
108 case 21: /* double underline */
109 /* Wikipedia says this flag does nothing */
110 /* Furthermore, mingw doesn't define this flag
111 attr |= COMMON_LVB_UNDERSCORE; */
113 case 24: /* no underline */
114 /* attr &= ~COMMON_LVB_UNDERSCORE; */
116 case 5: /* slow blink */
117 case 6: /* fast blink */
118 /* We don't have blink, but we do have
119 background intensity */
120 attr |= BACKGROUND_INTENSITY;
122 case 25: /* no blink */
123 attr &= ~BACKGROUND_INTENSITY;
125 case 7: /* negative */
128 case 27: /* positive */
131 case 8: /* conceal */
132 case 28: /* reveal */
136 attr &= ~FOREGROUND_ALL;
139 attr &= ~FOREGROUND_ALL;
140 attr |= FOREGROUND_RED;
143 attr &= ~FOREGROUND_ALL;
144 attr |= FOREGROUND_GREEN;
146 case 33: /* Yellow */
147 attr &= ~FOREGROUND_ALL;
148 attr |= FOREGROUND_RED | FOREGROUND_GREEN;
151 attr &= ~FOREGROUND_ALL;
152 attr |= FOREGROUND_BLUE;
154 case 35: /* Magenta */
155 attr &= ~FOREGROUND_ALL;
156 attr |= FOREGROUND_RED | FOREGROUND_BLUE;
159 attr &= ~FOREGROUND_ALL;
160 attr |= FOREGROUND_GREEN | FOREGROUND_BLUE;
163 attr |= FOREGROUND_RED |
167 case 38: /* Unknown */
170 attr &= ~FOREGROUND_ALL;
171 attr |= (plain_attr & FOREGROUND_ALL);
174 attr &= ~BACKGROUND_ALL;
177 attr &= ~BACKGROUND_ALL;
178 attr |= BACKGROUND_RED;
181 attr &= ~BACKGROUND_ALL;
182 attr |= BACKGROUND_GREEN;
184 case 43: /* Yellow */
185 attr &= ~BACKGROUND_ALL;
186 attr |= BACKGROUND_RED | BACKGROUND_GREEN;
189 attr &= ~BACKGROUND_ALL;
190 attr |= BACKGROUND_BLUE;
192 case 45: /* Magenta */
193 attr &= ~BACKGROUND_ALL;
194 attr |= BACKGROUND_RED | BACKGROUND_BLUE;
197 attr &= ~BACKGROUND_ALL;
198 attr |= BACKGROUND_GREEN | BACKGROUND_BLUE;
201 attr |= BACKGROUND_RED |
205 case 48: /* Unknown */
208 attr &= ~BACKGROUND_ALL;
209 attr |= (plain_attr & BACKGROUND_ALL);
212 /* Unsupported code */
216 } while (*(str-1) == ';');
224 /* Unsupported code */
231 static int ansi_emulate(const char *str, FILE *stream)
234 const char *pos = str;
237 pos = strstr(str, "\033[");
239 size_t len = pos - str;
242 size_t out_len = fwrite(str, 1, len, stream);
265 int winansi_fputs(const char *str, FILE *stream)
269 if (!isatty(fileno(stream)))
270 return fputs(str, stream);
275 return fputs(str, stream);
277 rv = ansi_emulate(str, stream);
285 static int winansi_vfprintf(FILE *stream, const char *format, va_list list)
289 char *buf = small_buf;
292 if (!isatty(fileno(stream)))
301 len = vsnprintf(small_buf, sizeof(small_buf), format, cp);
304 if (len > sizeof(small_buf) - 1) {
305 buf = malloc(len + 1);
309 len = vsnprintf(buf, len + 1, format, list);
312 rv = ansi_emulate(buf, stream);
314 if (buf != small_buf)
319 rv = vfprintf(stream, format, list);
323 int winansi_fprintf(FILE *stream, const char *format, ...)
328 va_start(list, format);
329 rv = winansi_vfprintf(stream, format, list);
335 int winansi_printf(const char *format, ...)
340 va_start(list, format);
341 rv = winansi_vfprintf(stdout, format, list);