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
);