Yet another method to initialize the terminal. Tested to work with VS2013 *and* VS2015.
This commit is contained in:
parent
fee09d0982
commit
a05dcbfe80
@ -43,6 +43,8 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define stricmp(X,Y) _stricmp((X),(Y))
|
#define stricmp(X,Y) _stricmp((X),(Y))
|
||||||
@ -60,13 +62,14 @@ static MUtils::Internal::CriticalSection g_terminal_lock;
|
|||||||
//Is terminal attached?
|
//Is terminal attached?
|
||||||
static volatile bool g_terminal_attached = false;
|
static volatile bool g_terminal_attached = false;
|
||||||
|
|
||||||
//Terminal output handle
|
|
||||||
static HANDLE g_hConOut = NULL;
|
|
||||||
|
|
||||||
//Terminal output buffer
|
//Terminal output buffer
|
||||||
static const size_t BUFF_SIZE = 8192;
|
static const size_t BUFF_SIZE = 8192;
|
||||||
static char g_conOutBuff[BUFF_SIZE] = { '\0' };
|
static char g_conOutBuff[BUFF_SIZE] = { '\0' };
|
||||||
|
|
||||||
|
//Buffer objects
|
||||||
|
static QScopedPointer<std::filebuf> g_fileBuf_stdout;
|
||||||
|
static QScopedPointer<std::filebuf> g_fileBuf_stderr;
|
||||||
|
|
||||||
//The log file
|
//The log file
|
||||||
static QScopedPointer<QFile> g_terminal_log_file;
|
static QScopedPointer<QFile> g_terminal_log_file;
|
||||||
|
|
||||||
@ -107,7 +110,7 @@ static inline bool null_or_whitespace(const char *const str)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t clean_str(char *const str)
|
static inline size_t clean_string(char *const str)
|
||||||
{
|
{
|
||||||
bool space_flag = true;
|
bool space_flag = true;
|
||||||
size_t src = 0, out = 0;
|
size_t src = 0, out = 0;
|
||||||
@ -147,17 +150,27 @@ static inline size_t clean_str(char *const str)
|
|||||||
// TERMINAL SETUP
|
// TERMINAL SETUP
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static inline std::filebuf *terminal_connect(FILE *const fs, std::ostream &os)
|
||||||
|
{
|
||||||
|
std::filebuf *result = NULL;
|
||||||
|
FILE *temp;
|
||||||
|
if (freopen_s(&temp, "CONOUT$", "wb", fs) == 0)
|
||||||
|
{
|
||||||
|
os.rdbuf(result = new std::filebuf(temp));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static void terminal_shutdown(void)
|
static void terminal_shutdown(void)
|
||||||
{
|
{
|
||||||
MUtils::Internal::CSLocker lock(g_terminal_lock);
|
|
||||||
|
|
||||||
if (g_terminal_attached)
|
if (g_terminal_attached)
|
||||||
{
|
{
|
||||||
if (VALID_HANLDE(g_hConOut))
|
g_fileBuf_stdout.reset();
|
||||||
{
|
g_fileBuf_stderr.reset();
|
||||||
CloseHandle(g_hConOut);
|
FILE *temp[2];
|
||||||
g_hConOut = NULL;
|
if(stdout) freopen_s(&temp[0], "NUL", "wb", stdout);
|
||||||
}
|
if(stderr) freopen_s(&temp[1], "NUL", "wb", stderr);
|
||||||
|
FreeConsole();
|
||||||
g_terminal_attached = false;
|
g_terminal_attached = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -220,7 +233,9 @@ void MUtils::Terminal::setup(int &argc, char **argv, const char* const appName,
|
|||||||
|
|
||||||
if(g_terminal_attached)
|
if(g_terminal_attached)
|
||||||
{
|
{
|
||||||
g_hConOut = CreateFileA("CONOUT$", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL);
|
g_fileBuf_stdout.reset(terminal_connect(stdout, std::cout));
|
||||||
|
g_fileBuf_stderr.reset(terminal_connect(stderr, std::cerr));
|
||||||
|
|
||||||
atexit(terminal_shutdown);
|
atexit(terminal_shutdown);
|
||||||
|
|
||||||
const HWND hwndConsole = GetConsoleWindow();
|
const HWND hwndConsole = GetConsoleWindow();
|
||||||
@ -248,11 +263,15 @@ static const WORD COLOR_YELLOW = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_
|
|||||||
static const WORD COLOR_WHITE = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
|
static const WORD COLOR_WHITE = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
|
||||||
static const WORD COLOR_DEFAULT= FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
|
static const WORD COLOR_DEFAULT= FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED;
|
||||||
|
|
||||||
static void set_terminal_color(const WORD &attributes)
|
static void set_terminal_color(FILE *const fp, const WORD &attributes)
|
||||||
{
|
{
|
||||||
if(VALID_HANLDE(g_hConOut))
|
if(_isatty(_fileno(fp)))
|
||||||
{
|
{
|
||||||
SetConsoleTextAttribute(g_hConOut, attributes);
|
const HANDLE hConsole = (HANDLE)(_get_osfhandle(_fileno(fp)));
|
||||||
|
if (VALID_HANLDE(hConsole))
|
||||||
|
{
|
||||||
|
SetConsoleTextAttribute(hConsole, attributes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,35 +282,15 @@ static void set_terminal_color(const WORD &attributes)
|
|||||||
static const char *const FORMAT = "[%c][%s] %s\r\n";
|
static const char *const FORMAT = "[%c][%s] %s\r\n";
|
||||||
static const char *const GURU_MEDITATION = "\n\nGURU MEDITATION !!!\n\n";
|
static const char *const GURU_MEDITATION = "\n\nGURU MEDITATION !!!\n\n";
|
||||||
|
|
||||||
static inline int terminal_fprintf(const char *const text, ...)
|
|
||||||
{
|
|
||||||
if (VALID_HANLDE(g_hConOut))
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, text);
|
|
||||||
const int len = _vsnprintf_s(g_conOutBuff, BUFF_SIZE, _TRUNCATE, text, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
if (len > 0)
|
|
||||||
{
|
|
||||||
DWORD written;
|
|
||||||
WriteFile(g_hConOut, g_conOutBuff, DWORD(len), &written, NULL);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void write_to_logfile(QFile *const file, const int &type, const char *const message)
|
static void write_to_logfile(QFile *const file, const int &type, const char *const message)
|
||||||
{
|
{
|
||||||
|
int len = -1;
|
||||||
|
|
||||||
if (null_or_whitespace(message))
|
if (null_or_whitespace(message))
|
||||||
{
|
{
|
||||||
return; /*don't write empty message to log file*/
|
return; /*don't write empty message to log file*/
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = -1;
|
|
||||||
|
|
||||||
static char timestamp[32];
|
static char timestamp[32];
|
||||||
make_timestamp(timestamp, 32);
|
make_timestamp(timestamp, 32);
|
||||||
|
|
||||||
@ -311,7 +310,7 @@ static void write_to_logfile(QFile *const file, const int &type, const char *con
|
|||||||
|
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
if (clean_str(g_conOutBuff) > 0)
|
if (clean_string(g_conOutBuff) > 0)
|
||||||
{
|
{
|
||||||
file->write(g_conOutBuff);
|
file->write(g_conOutBuff);
|
||||||
file->flush();
|
file->flush();
|
||||||
@ -321,13 +320,13 @@ static void write_to_logfile(QFile *const file, const int &type, const char *con
|
|||||||
|
|
||||||
static void write_to_debugger(const int &type, const char *const message)
|
static void write_to_debugger(const int &type, const char *const message)
|
||||||
{
|
{
|
||||||
|
int len = -1;
|
||||||
|
|
||||||
if (null_or_whitespace(message))
|
if (null_or_whitespace(message))
|
||||||
{
|
{
|
||||||
return; /*don't send empty message to debugger*/
|
return; /*don't send empty message to debugger*/
|
||||||
}
|
}
|
||||||
|
|
||||||
int len = -1;
|
|
||||||
|
|
||||||
static char timestamp[32];
|
static char timestamp[32];
|
||||||
make_timestamp(timestamp, 32);
|
make_timestamp(timestamp, 32);
|
||||||
|
|
||||||
@ -347,7 +346,7 @@ static void write_to_debugger(const int &type, const char *const message)
|
|||||||
|
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
if (clean_str(g_conOutBuff) > 0)
|
if (clean_string(g_conOutBuff) > 0)
|
||||||
{
|
{
|
||||||
OutputDebugStringA(g_conOutBuff);
|
OutputDebugStringA(g_conOutBuff);
|
||||||
}
|
}
|
||||||
@ -360,19 +359,21 @@ static void write_to_terminal(const int &type, const char *const message)
|
|||||||
{
|
{
|
||||||
case QtCriticalMsg:
|
case QtCriticalMsg:
|
||||||
case QtFatalMsg:
|
case QtFatalMsg:
|
||||||
set_terminal_color(COLOR_RED);
|
set_terminal_color(stderr, COLOR_RED);
|
||||||
terminal_fprintf(GURU_MEDITATION);
|
fprintf(stderr, GURU_MEDITATION);
|
||||||
terminal_fprintf("%s\n", message);
|
fprintf(stderr, "%s\n", message);
|
||||||
break;
|
break;
|
||||||
case QtWarningMsg:
|
case QtWarningMsg:
|
||||||
set_terminal_color(COLOR_YELLOW);
|
set_terminal_color(stderr, COLOR_YELLOW);
|
||||||
terminal_fprintf("%s\n", message);
|
fprintf(stderr, "%s\n", message);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
set_terminal_color(COLOR_WHITE);
|
set_terminal_color(stderr, COLOR_WHITE);
|
||||||
terminal_fprintf("%s\n", message);
|
fprintf(stderr, "%s\n", message);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fflush(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MUtils::Terminal::write(const int &type, const char *const message)
|
void MUtils::Terminal::write(const int &type, const char *const message)
|
||||||
|
Loading…
Reference in New Issue
Block a user