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