2 * Copyright 2008 Peter Harris <git@peter.is-a-geek.org>
5 #include "../git-compat-util.h"
8 Functions to be wrapped:
16 ANSI codes used by git: m, K
18 This file is git-specific. Therefore, this file does not attempt
19 to implement any codes that are not used by git.
22 static HANDLE console;
23 static WORD plain_attr;
27 static void init(void)
29 CONSOLE_SCREEN_BUFFER_INFO sbi;
31 static int initialized = 0;
35 console = GetStdHandle(STD_OUTPUT_HANDLE);
36 if (console == INVALID_HANDLE_VALUE)
42 GetConsoleScreenBufferInfo(console, &sbi);
43 attr = plain_attr = sbi.wAttributes;
50 #define FOREGROUND_ALL (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
51 #define BACKGROUND_ALL (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE)
53 static void set_console_attr(void)
55 WORD attributes = attr;
57 attributes &= ~FOREGROUND_ALL;
58 attributes &= ~BACKGROUND_ALL;
60 /* This could probably use a bitmask
61 instead of a series of ifs */
62 if (attr & FOREGROUND_RED)
63 attributes |= BACKGROUND_RED;
64 if (attr & FOREGROUND_GREEN)
65 attributes |= BACKGROUND_GREEN;
66 if (attr & FOREGROUND_BLUE)
67 attributes |= BACKGROUND_BLUE;
69 if (attr & BACKGROUND_RED)
70 attributes |= FOREGROUND_RED;
71 if (attr & BACKGROUND_GREEN)
72 attributes |= FOREGROUND_GREEN;
73 if (attr & BACKGROUND_BLUE)
74 attributes |= FOREGROUND_BLUE;
76 SetConsoleTextAttribute(console, attributes);
79 static void erase_in_line(void)
81 CONSOLE_SCREEN_BUFFER_INFO sbi;
82 DWORD dummy; /* Needed for Windows 7 (or Vista) regression */
87 GetConsoleScreenBufferInfo(console, &sbi);
88 FillConsoleOutputCharacterA(console, ' ',
89 sbi.dwSize.X - sbi.dwCursorPosition.X, sbi.dwCursorPosition,
94 static const char *set_attr(const char *str)
97 size_t len = strspn(str, "0123456789;");
103 long val = strtol(str, (char **)&str, 10);
110 attr |= FOREGROUND_INTENSITY;
113 case 22: /* normal */
114 attr &= ~FOREGROUND_INTENSITY;
119 case 4: /* underline */
120 case 21: /* double underline */
121 /* Wikipedia says this flag does nothing */
122 /* Furthermore, mingw doesn't define this flag
123 attr |= COMMON_LVB_UNDERSCORE; */
125 case 24: /* no underline */
126 /* attr &= ~COMMON_LVB_UNDERSCORE; */
128 case 5: /* slow blink */
129 case 6: /* fast blink */
130 /* We don't have blink, but we do have
131 background intensity */
132 attr |= BACKGROUND_INTENSITY;
134 case 25: /* no blink */
135 attr &= ~BACKGROUND_INTENSITY;
137 case 7: /* negative */
140 case 27: /* positive */
143 case 8: /* conceal */
144 case 28: /* reveal */
148 attr &= ~FOREGROUND_ALL;
151 attr &= ~FOREGROUND_ALL;
152 attr |= FOREGROUND_RED;
155 attr &= ~FOREGROUND_ALL;
156 attr |= FOREGROUND_GREEN;
158 case 33: /* Yellow */
159 attr &= ~FOREGROUND_ALL;
160 attr |= FOREGROUND_RED | FOREGROUND_GREEN;
163 attr &= ~FOREGROUND_ALL;
164 attr |= FOREGROUND_BLUE;
166 case 35: /* Magenta */
167 attr &= ~FOREGROUND_ALL;
168 attr |= FOREGROUND_RED | FOREGROUND_BLUE;
171 attr &= ~FOREGROUND_ALL;
172 attr |= FOREGROUND_GREEN | FOREGROUND_BLUE;
175 attr |= FOREGROUND_RED |
179 case 38: /* Unknown */
182 attr &= ~FOREGROUND_ALL;
183 attr |= (plain_attr & FOREGROUND_ALL);
186 attr &= ~BACKGROUND_ALL;
189 attr &= ~BACKGROUND_ALL;
190 attr |= BACKGROUND_RED;
193 attr &= ~BACKGROUND_ALL;
194 attr |= BACKGROUND_GREEN;
196 case 43: /* Yellow */
197 attr &= ~BACKGROUND_ALL;
198 attr |= BACKGROUND_RED | BACKGROUND_GREEN;
201 attr &= ~BACKGROUND_ALL;
202 attr |= BACKGROUND_BLUE;
204 case 45: /* Magenta */
205 attr &= ~BACKGROUND_ALL;
206 attr |= BACKGROUND_RED | BACKGROUND_BLUE;
209 attr &= ~BACKGROUND_ALL;
210 attr |= BACKGROUND_GREEN | BACKGROUND_BLUE;
213 attr |= BACKGROUND_RED |
217 case 48: /* Unknown */
220 attr &= ~BACKGROUND_ALL;
221 attr |= (plain_attr & BACKGROUND_ALL);
224 /* Unsupported code */
228 } while (*(str-1) == ';');
236 /* Unsupported code */
243 static int ansi_emulate(const char *str, FILE *stream)
246 const char *pos = str;
249 pos = strstr(str, "\033[");
251 size_t len = pos - str;
254 size_t out_len = fwrite(str, 1, len, stream);
277 int winansi_fputs(const char *str, FILE *stream)
281 if (!isatty(fileno(stream)))
282 return fputs(str, stream);
287 return fputs(str, stream);
289 rv = ansi_emulate(str, stream);
297 static int winansi_vfprintf(FILE *stream, const char *format, va_list list)
301 char *buf = small_buf;
304 if (!isatty(fileno(stream)))
313 len = vsnprintf(small_buf, sizeof(small_buf), format, cp);
316 if (len > sizeof(small_buf) - 1) {
317 buf = malloc(len + 1);
321 len = vsnprintf(buf, len + 1, format, list);
324 rv = ansi_emulate(buf, stream);
326 if (buf != small_buf)
331 rv = vfprintf(stream, format, list);
335 int winansi_fprintf(FILE *stream, const char *format, ...)
340 va_start(list, format);
341 rv = winansi_vfprintf(stream, format, list);
347 int winansi_printf(const char *format, ...)
352 va_start(list, format);
353 rv = winansi_vfprintf(stdout, format, list);