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