blob: f7285f348a8e4ec5f0c0afacb008a247bf92a8b4 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
#include "core/log.h"
// there is no standard way to ask whether a stream is a terminal
#ifdef HSDBG_WINDOWS
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#include <io.h>
#else
#include <unistd.h>
#endif
namespace Hsdbg::Log::Detail
{
namespace
{
constexpr int STDOUT_DESCRIPTOR = 1;
constexpr int STDERR_DESCRIPTOR = 2;
#ifdef HSDBG_WINDOWS
// a windows console prints escapes literally until it is asked to
// interpret them, so a console that refuses gets the plain format
auto probe(bool to_stderr) -> bool
{
if (_isatty(to_stderr ? STDERR_DESCRIPTOR : STDOUT_DESCRIPTOR) == 0)
return false;
const HANDLE console = GetStdHandle(to_stderr ? STD_ERROR_HANDLE : STD_OUTPUT_HANDLE);
if (console == nullptr || console == INVALID_HANDLE_VALUE)
return false;
DWORD mode = 0;
if (GetConsoleMode(console, &mode) == 0)
return false;
if ((mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) != 0)
return true;
return SetConsoleMode(console, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING) != 0;
}
#else
auto probe(bool to_stderr) -> bool
{
return isatty(to_stderr ? STDERR_DESCRIPTOR : STDOUT_DESCRIPTOR) != 0;
}
#endif
}
auto is_terminal(bool to_stderr) -> bool
{
static const bool out = probe(false);
static const bool err = probe(true);
return to_stderr ? err : out;
}
}
|