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.
23 static HANDLE console;
24 static WORD plain_attr;
28 static void init(void)
30 CONSOLE_SCREEN_BUFFER_INFO sbi;
32 static int initialized = 0;
36 console = GetStdHandle(STD_OUTPUT_HANDLE);
37 if (console == INVALID_HANDLE_VALUE)
43 GetConsoleScreenBufferInfo(console, &sbi);
44 attr = plain_attr = sbi.wAttributes;
51 #define FOREGROUND_ALL (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
52 #define BACKGROUND_ALL (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE)
54 static void set_console_attr(void)
56 WORD attributes = attr;
58 attributes &= ~FOREGROUND_ALL;
59 attributes &= ~BACKGROUND_ALL;
61 /* This could probably use a bitmask
62 instead of a series of ifs */
63 if (attr & FOREGROUND_RED)
64 attributes |= BACKGROUND_RED;
65 if (attr & FOREGROUND_GREEN)
66 attributes |= BACKGROUND_GREEN;
67 if (attr & FOREGROUND_BLUE)
68 attributes |= BACKGROUND_BLUE;
70 if (attr & BACKGROUND_RED)
71 attributes |= FOREGROUND_RED;
72 if (attr & BACKGROUND_GREEN)
73 attributes |= FOREGROUND_GREEN;
74 if (attr & BACKGROUND_BLUE)
75 attributes |= FOREGROUND_BLUE;
77 SetConsoleTextAttribute(console, attributes);
80 static void erase_in_line(void)
82 CONSOLE_SCREEN_BUFFER_INFO sbi;
83 DWORD dummy; /* Needed for Windows 7 (or Vista) regression */
88 GetConsoleScreenBufferInfo(console, &sbi);
89 FillConsoleOutputCharacterA(console, ' ',
90 sbi.dwSize.X - sbi.dwCursorPosition.X, sbi.dwCursorPosition,
95 static const char *set_attr(const char *str)
98 size_t len = strspn(str, "0123456789;");
104 long val = strtol(str, (char **)&str, 10);
111 attr |= FOREGROUND_INTENSITY;
114 case 22: /* normal */
115 attr &= ~FOREGROUND_INTENSITY;
120 case 4: /* underline */
121 case 21: /* double underline */
122 /* Wikipedia says this flag does nothing */
123 /* Furthermore, mingw doesn't define this flag
124 attr |= COMMON_LVB_UNDERSCORE; */
126 case 24: /* no underline */
127 /* attr &= ~COMMON_LVB_UNDERSCORE; */
129 case 5: /* slow blink */
130 case 6: /* fast blink */
131 /* We don't have blink, but we do have
132 background intensity */
133 attr |= BACKGROUND_INTENSITY;
135 case 25: /* no blink */
136 attr &= ~BACKGROUND_INTENSITY;
138 case 7: /* negative */
141 case 27: /* positive */
144 case 8: /* conceal */
145 case 28: /* reveal */
149 attr &= ~FOREGROUND_ALL;
152 attr &= ~FOREGROUND_ALL;
153 attr |= FOREGROUND_RED;
156 attr &= ~FOREGROUND_ALL;
157 attr |= FOREGROUND_GREEN;
159 case 33: /* Yellow */
160 attr &= ~FOREGROUND_ALL;
161 attr |= FOREGROUND_RED | FOREGROUND_GREEN;
164 attr &= ~FOREGROUND_ALL;
165 attr |= FOREGROUND_BLUE;
167 case 35: /* Magenta */
168 attr &= ~FOREGROUND_ALL;
169 attr |= FOREGROUND_RED | FOREGROUND_BLUE;
172 attr &= ~FOREGROUND_ALL;
173 attr |= FOREGROUND_GREEN | FOREGROUND_BLUE;
176 attr |= FOREGROUND_RED |
180 case 38: /* Unknown */
183 attr &= ~FOREGROUND_ALL;
184 attr |= (plain_attr & FOREGROUND_ALL);
187 attr &= ~BACKGROUND_ALL;
190 attr &= ~BACKGROUND_ALL;
191 attr |= BACKGROUND_RED;
194 attr &= ~BACKGROUND_ALL;
195 attr |= BACKGROUND_GREEN;
197 case 43: /* Yellow */
198 attr &= ~BACKGROUND_ALL;
199 attr |= BACKGROUND_RED | BACKGROUND_GREEN;
202 attr &= ~BACKGROUND_ALL;
203 attr |= BACKGROUND_BLUE;
205 case 45: /* Magenta */
206 attr &= ~BACKGROUND_ALL;
207 attr |= BACKGROUND_RED | BACKGROUND_BLUE;
210 attr &= ~BACKGROUND_ALL;
211 attr |= BACKGROUND_GREEN | BACKGROUND_BLUE;
214 attr |= BACKGROUND_RED |
218 case 48: /* Unknown */
221 attr &= ~BACKGROUND_ALL;
222 attr |= (plain_attr & BACKGROUND_ALL);
225 /* Unsupported code */
229 } while (*(str-1) == ';');
237 /* Unsupported code */
244 static int ansi_emulate(const char *str, FILE *stream)
247 const char *pos = str;
250 pos = strstr(str, "\033[");
252 size_t len = pos - str;
255 size_t out_len = fwrite(str, 1, len, stream);
278 int winansi_fputs(const char *str, FILE *stream)
282 if (!isatty(fileno(stream)))
283 return fputs(str, stream);
288 return fputs(str, stream);
290 rv = ansi_emulate(str, stream);
298 static int winansi_vfprintf(FILE *stream, const char *format, va_list list)
302 char *buf = small_buf;
305 if (!isatty(fileno(stream)))
314 len = vsnprintf(small_buf, sizeof(small_buf), format, cp);
317 if (len > sizeof(small_buf) - 1) {
318 buf = malloc(len + 1);
322 len = vsnprintf(buf, len + 1, format, list);
325 rv = ansi_emulate(buf, stream);
327 if (buf != small_buf)
332 rv = vfprintf(stream, format, list);
336 int winansi_fprintf(FILE *stream, const char *format, ...)
341 va_start(list, format);
342 rv = winansi_vfprintf(stream, format, list);
348 int winansi_printf(const char *format, ...)
353 va_start(list, format);
354 rv = winansi_vfprintf(stdout, format, list);