Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
tpruvot
GitHub Repository: tpruvot/cpuminer-multi
Path: blob/linux/compat/winansi.c
1201 views
1
/**
2
* Old Git implementation of windows terminal colors (2009)
3
* before use of a threaded wrapper.
4
*/
5
6
#undef NOGDI
7
#include <windows.h>
8
#include <wingdi.h>
9
#include <winreg.h>
10
#include <malloc.h>
11
#include <stdio.h>
12
#include <io.h>
13
14
#include "compat/winansi.h"
15
/*
16
* Copyright 2008 Peter Harris <[email protected]>
17
*/
18
19
/*
20
Functions to be wrapped:
21
*/
22
#undef printf
23
#undef fprintf
24
#undef fputs
25
#undef vfprintf
26
/* TODO: write */
27
28
/*
29
ANSI codes used by git: m, K
30
31
This file is git-specific. Therefore, this file does not attempt
32
to implement any codes that are not used by git.
33
*/
34
35
static HANDLE console;
36
static WORD plain_attr;
37
static WORD attr;
38
static int negative;
39
40
static void init(void)
41
{
42
CONSOLE_SCREEN_BUFFER_INFO sbi;
43
44
static int initialized = 0;
45
if (initialized)
46
return;
47
48
console = GetStdHandle(STD_OUTPUT_HANDLE);
49
if (console == INVALID_HANDLE_VALUE)
50
console = NULL;
51
52
if (!console)
53
return;
54
55
GetConsoleScreenBufferInfo(console, &sbi);
56
attr = plain_attr = sbi.wAttributes;
57
negative = 0;
58
59
initialized = 1;
60
}
61
62
static int write_console(const char *str, int len)
63
{
64
/* convert utf-8 to utf-16, write directly to console */
65
int wlen = MultiByteToWideChar(CP_UTF8, 0, str, len, NULL, 0);
66
wchar_t *wbuf = (wchar_t *)alloca(wlen * sizeof(wchar_t));
67
MultiByteToWideChar(CP_UTF8, 0, str, len, wbuf, wlen);
68
69
WriteConsoleW(console, wbuf, wlen, NULL, NULL);
70
71
/* return original (utf-8 encoded) length */
72
return len;
73
}
74
75
#define FOREGROUND_ALL (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE)
76
#define BACKGROUND_ALL (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE)
77
78
static void set_console_attr(void)
79
{
80
WORD attributes = attr;
81
if (negative) {
82
attributes &= ~FOREGROUND_ALL;
83
attributes &= ~BACKGROUND_ALL;
84
85
/* This could probably use a bitmask
86
instead of a series of ifs */
87
if (attr & FOREGROUND_RED)
88
attributes |= BACKGROUND_RED;
89
if (attr & FOREGROUND_GREEN)
90
attributes |= BACKGROUND_GREEN;
91
if (attr & FOREGROUND_BLUE)
92
attributes |= BACKGROUND_BLUE;
93
94
if (attr & BACKGROUND_RED)
95
attributes |= FOREGROUND_RED;
96
if (attr & BACKGROUND_GREEN)
97
attributes |= FOREGROUND_GREEN;
98
if (attr & BACKGROUND_BLUE)
99
attributes |= FOREGROUND_BLUE;
100
}
101
SetConsoleTextAttribute(console, attributes);
102
}
103
104
static void erase_in_line(void)
105
{
106
CONSOLE_SCREEN_BUFFER_INFO sbi;
107
DWORD dummy; /* Needed for Windows 7 (or Vista) regression */
108
109
if (!console)
110
return;
111
112
GetConsoleScreenBufferInfo(console, &sbi);
113
FillConsoleOutputCharacterA(console, ' ',
114
sbi.dwSize.X - sbi.dwCursorPosition.X, sbi.dwCursorPosition,
115
&dummy);
116
}
117
118
119
static const char *set_attr(const char *str)
120
{
121
const char *func;
122
size_t len = strspn(str, "0123456789;");
123
func = str + len;
124
125
switch (*func) {
126
case 'm':
127
do {
128
long val = strtol(str, (char **)&str, 10);
129
switch (val) {
130
case 0: /* reset */
131
attr = plain_attr;
132
negative = 0;
133
break;
134
case 1: /* bold */
135
attr |= FOREGROUND_INTENSITY;
136
break;
137
case 2: /* faint */
138
case 22: /* normal */
139
attr &= ~FOREGROUND_INTENSITY;
140
break;
141
case 3: /* italic */
142
/* Unsupported */
143
break;
144
case 4: /* underline */
145
case 21: /* double underline */
146
/* Wikipedia says this flag does nothing */
147
/* Furthermore, mingw doesn't define this flag
148
attr |= COMMON_LVB_UNDERSCORE; */
149
break;
150
case 24: /* no underline */
151
/* attr &= ~COMMON_LVB_UNDERSCORE; */
152
break;
153
case 5: /* slow blink */
154
case 6: /* fast blink */
155
/* We don't have blink, but we do have
156
background intensity */
157
attr |= BACKGROUND_INTENSITY;
158
break;
159
case 25: /* no blink */
160
attr &= ~BACKGROUND_INTENSITY;
161
break;
162
case 7: /* negative */
163
negative = 1;
164
break;
165
case 27: /* positive */
166
negative = 0;
167
break;
168
case 8: /* conceal */
169
case 28: /* reveal */
170
/* Unsupported */
171
break;
172
case 30: /* Black */
173
attr &= ~FOREGROUND_ALL;
174
break;
175
case 31: /* Red */
176
attr &= ~FOREGROUND_ALL;
177
attr |= FOREGROUND_RED;
178
break;
179
case 32: /* Green */
180
attr &= ~FOREGROUND_ALL;
181
attr |= FOREGROUND_GREEN;
182
break;
183
case 33: /* Yellow */
184
attr &= ~FOREGROUND_ALL;
185
attr |= FOREGROUND_RED | FOREGROUND_GREEN;
186
break;
187
case 34: /* Blue */
188
attr &= ~FOREGROUND_ALL;
189
attr |= FOREGROUND_BLUE;
190
break;
191
case 35: /* Magenta */
192
attr &= ~FOREGROUND_ALL;
193
attr |= FOREGROUND_RED | FOREGROUND_BLUE;
194
break;
195
case 36: /* Cyan */
196
attr &= ~FOREGROUND_ALL;
197
attr |= FOREGROUND_GREEN | FOREGROUND_BLUE;
198
break;
199
case 37: /* White */
200
attr |= FOREGROUND_RED |
201
FOREGROUND_GREEN |
202
FOREGROUND_BLUE;
203
break;
204
case 38: /* Unknown */
205
break;
206
case 39: /* reset */
207
attr &= ~FOREGROUND_ALL;
208
attr |= (plain_attr & FOREGROUND_ALL);
209
break;
210
case 40: /* Black */
211
attr &= ~BACKGROUND_ALL;
212
break;
213
case 41: /* Red */
214
attr &= ~BACKGROUND_ALL;
215
attr |= BACKGROUND_RED;
216
break;
217
case 42: /* Green */
218
attr &= ~BACKGROUND_ALL;
219
attr |= BACKGROUND_GREEN;
220
break;
221
case 43: /* Yellow */
222
attr &= ~BACKGROUND_ALL;
223
attr |= BACKGROUND_RED | BACKGROUND_GREEN;
224
break;
225
case 44: /* Blue */
226
attr &= ~BACKGROUND_ALL;
227
attr |= BACKGROUND_BLUE;
228
break;
229
case 45: /* Magenta */
230
attr &= ~BACKGROUND_ALL;
231
attr |= BACKGROUND_RED | BACKGROUND_BLUE;
232
break;
233
case 46: /* Cyan */
234
attr &= ~BACKGROUND_ALL;
235
attr |= BACKGROUND_GREEN | BACKGROUND_BLUE;
236
break;
237
case 47: /* White */
238
attr |= BACKGROUND_RED |
239
BACKGROUND_GREEN |
240
BACKGROUND_BLUE;
241
break;
242
case 48: /* Unknown */
243
break;
244
case 49: /* reset */
245
attr &= ~BACKGROUND_ALL;
246
attr |= (plain_attr & BACKGROUND_ALL);
247
break;
248
default:
249
/* Unsupported code */
250
break;
251
}
252
str++;
253
} while (*(str - 1) == ';');
254
255
set_console_attr();
256
break;
257
case 'K':
258
erase_in_line();
259
break;
260
default:
261
/* Unsupported code */
262
break;
263
}
264
265
return func + 1;
266
}
267
268
static int ansi_emulate(const char *str, FILE *stream)
269
{
270
int rv = 0;
271
const char *pos = str;
272
273
fflush(stream);
274
275
while (*pos) {
276
pos = strstr(str, "\033[");
277
if (pos) {
278
int len = (int) (pos - str);
279
280
if (len) {
281
int out_len = write_console(str, len);
282
rv += out_len;
283
if (out_len < len)
284
return rv;
285
}
286
287
str = pos + 2;
288
rv += 2;
289
290
pos = set_attr(str);
291
rv += (int) (pos - str);
292
str = pos;
293
}
294
else {
295
int len = (int) strlen(str);
296
rv += write_console(str, len);
297
return rv;
298
}
299
}
300
return rv;
301
}
302
303
int winansi_fputs(const char *str, FILE *stream)
304
{
305
int rv;
306
307
if (!isatty(fileno(stream)))
308
return fputs(str, stream);
309
310
init();
311
312
if (!console)
313
return fputs(str, stream);
314
315
rv = ansi_emulate(str, stream);
316
317
if (rv >= 0)
318
return 0;
319
else
320
return EOF;
321
}
322
323
int winansi_vfprintf(FILE *stream, const char *format, va_list list)
324
{
325
int len, rv;
326
char small_buf[256] = { 0 };
327
char *buf = small_buf;
328
va_list cp;
329
330
if (!isatty(fileno(stream)))
331
goto abort;
332
333
init();
334
335
if (!console)
336
goto abort;
337
338
va_copy(cp, list);
339
len = vsnprintf(small_buf, sizeof(small_buf), format, cp);
340
#ifdef WIN32
341
/* bug on long strings without that */
342
if (len == -1)
343
len = _vscprintf(format, cp);
344
#endif
345
va_end(cp);
346
347
if (len > sizeof(small_buf) - 1) {
348
buf = malloc(len + 1);
349
if (!buf)
350
goto abort;
351
352
len = vsnprintf(buf, len + 1, format, list);
353
#ifdef WIN32
354
if (len == -1)
355
len = _vscprintf(format, list);
356
#endif
357
}
358
359
rv = ansi_emulate(buf, stream);
360
361
if (buf != small_buf)
362
free(buf);
363
return rv;
364
365
abort:
366
rv = vfprintf(stream, format, list);
367
return rv;
368
}
369
370
int winansi_fprintf(FILE *stream, const char *format, ...)
371
{
372
va_list list;
373
int rv;
374
375
va_start(list, format);
376
rv = winansi_vfprintf(stream, format, list);
377
va_end(list);
378
379
return rv;
380
}
381
382
int winansi_printf(const char *format, ...)
383
{
384
va_list list;
385
int rv;
386
387
va_start(list, format);
388
rv = winansi_vfprintf(stdout, format, list);
389
va_end(list);
390
391
return rv;
392
}
393