Refactored the terminal initialization code. Also, we will now properly shut down the terminal at the end.
This commit is contained in:
parent
bc3701305d
commit
1c175c651b
@ -37,7 +37,7 @@ namespace MUtils
|
|||||||
typedef int (main_function_t)(int &argc, char **argv);
|
typedef int (main_function_t)(int &argc, char **argv);
|
||||||
|
|
||||||
//Startup Application
|
//Startup Application
|
||||||
MUTILS_API int startup(int &argc, char **argv, main_function_t *const entry_point, const bool &debugConsole);
|
MUTILS_API int startup(int &argc, char **argv, main_function_t *const entry_point, const char* const appName, const bool &debugConsole);
|
||||||
|
|
||||||
//Initialize Qt
|
//Initialize Qt
|
||||||
MUTILS_API QApplication *create_qt(int &argc, char **argv, const QString &appName);
|
MUTILS_API QApplication *create_qt(int &argc, char **argv, const QString &appName);
|
||||||
|
@ -34,7 +34,7 @@ namespace MUtils
|
|||||||
namespace Terminal
|
namespace Terminal
|
||||||
{
|
{
|
||||||
//Setup terminal
|
//Setup terminal
|
||||||
MUTILS_API void setup(int &argc, char **argv, const bool forceEnabled);
|
MUTILS_API void setup(int &argc, char **argv, const char* const appName, const bool forceEnabled);
|
||||||
|
|
||||||
//Terminal output
|
//Terminal output
|
||||||
MUTILS_API void write(const int &type, const char *const message);
|
MUTILS_API void write(const int &type, const char *const message);
|
||||||
|
@ -64,19 +64,19 @@ static bool qt_event_filter(void *message, long *result)
|
|||||||
// STARTUP FUNCTION
|
// STARTUP FUNCTION
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static int startup_main(int &argc, char **argv, MUtils::Startup::main_function_t *const entry_point, const bool &debugConsole)
|
static int startup_main(int &argc, char **argv, MUtils::Startup::main_function_t *const entry_point, const char* const appName, const bool &debugConsole)
|
||||||
{
|
{
|
||||||
qInstallMsgHandler(qt_message_handler);
|
qInstallMsgHandler(qt_message_handler);
|
||||||
MUtils::Terminal::setup(argc, argv, MUTILS_DEBUG || debugConsole);
|
MUtils::Terminal::setup(argc, argv, appName, MUTILS_DEBUG || debugConsole);
|
||||||
return entry_point(argc, argv);
|
return entry_point(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int startup_helper(int &argc, char **argv, MUtils::Startup::main_function_t *const entry_point, const bool &debugConsole)
|
static int startup_helper(int &argc, char **argv, MUtils::Startup::main_function_t *const entry_point, const char* const appName, const bool &debugConsole)
|
||||||
{
|
{
|
||||||
int iResult = -1;
|
int iResult = -1;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
iResult = startup_main(argc, argv, entry_point, debugConsole);
|
iResult = startup_main(argc, argv, entry_point, appName, debugConsole);
|
||||||
}
|
}
|
||||||
catch(const std::exception &error)
|
catch(const std::exception &error)
|
||||||
{
|
{
|
||||||
@ -91,21 +91,21 @@ static int startup_helper(int &argc, char **argv, MUtils::Startup::main_function
|
|||||||
return iResult;
|
return iResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MUtils::Startup::startup(int &argc, char **argv, main_function_t *const entry_point, const bool &debugConsole)
|
int MUtils::Startup::startup(int &argc, char **argv, main_function_t *const entry_point, const char* const appName, const bool &debugConsole)
|
||||||
{
|
{
|
||||||
int iResult = -1;
|
int iResult = -1;
|
||||||
#if (MUTILS_DEBUG)
|
#if (MUTILS_DEBUG)
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
_CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF || _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
|
_CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF || _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG));
|
||||||
#endif //_MSCVER
|
#endif //_MSCVER
|
||||||
iResult = startup_main(argc, argv, entry_point, debugConsole);
|
iResult = startup_main(argc, argv, entry_point, appName, debugConsole);
|
||||||
#else //MUTILS_DEBUG
|
#else //MUTILS_DEBUG
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
__try
|
__try
|
||||||
{
|
{
|
||||||
MUtils::ErrorHandler::initialize();
|
MUtils::ErrorHandler::initialize();
|
||||||
MUtils::OS::check_debugger();
|
MUtils::OS::check_debugger();
|
||||||
iResult = startup_helper(argc, argv, entry_point, debugConsole);
|
iResult = startup_helper(argc, argv, entry_point, appName, debugConsole);
|
||||||
}
|
}
|
||||||
__except(1)
|
__except(1)
|
||||||
{
|
{
|
||||||
@ -115,7 +115,7 @@ int MUtils::Startup::startup(int &argc, char **argv, main_function_t *const entr
|
|||||||
#else //_MSCVER
|
#else //_MSCVER
|
||||||
MUtils::ErrorHandler::initialize();
|
MUtils::ErrorHandler::initialize();
|
||||||
MUtils::OS::check_debugger();
|
MUtils::OS::check_debugger();
|
||||||
iResult = startup_helper(argc, argv, entry_point, debugConsole);
|
iResult = startup_helper(argc, argv, entry_point, appName, debugConsole);
|
||||||
#endif //_MSCVER
|
#endif //_MSCVER
|
||||||
#endif //MUTILS_DEBUG
|
#endif //MUTILS_DEBUG
|
||||||
return iResult;
|
return iResult;
|
||||||
|
@ -45,9 +45,6 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
//Lock
|
|
||||||
static MUtils::Internal::CriticalSection g_terminal_lock;
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define stricmp(X,Y) _stricmp((X),(Y))
|
#define stricmp(X,Y) _stricmp((X),(Y))
|
||||||
#endif
|
#endif
|
||||||
@ -102,16 +99,79 @@ static const char *clean_str(char *str)
|
|||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// HELPER MACROS
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define REPLACE_STANDARD_STREAM(TYPE, HANDLE) do \
|
||||||
|
{ \
|
||||||
|
const int fd_##TYPE = _open_osfhandle((intptr_t)GetStdHandle(HANDLE), flags); \
|
||||||
|
FILE *const file_##TYPE = (fd_##TYPE >= 0) ? _fdopen(fd_##TYPE, "wb") : NULL; \
|
||||||
|
if(file_##TYPE) \
|
||||||
|
{ \
|
||||||
|
g_terminal_backup_file_##TYPE = *(std##TYPE); \
|
||||||
|
*(std##TYPE) = *(file_##TYPE); \
|
||||||
|
g_terminal_filebuf_##TYPE.reset(new std::filebuf(file_##TYPE)); \
|
||||||
|
g_terminal_backup_fbuf_##TYPE = std::c##TYPE.rdbuf(); \
|
||||||
|
std::c##TYPE.rdbuf(g_terminal_filebuf_##TYPE.data()); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
while(0)
|
||||||
|
|
||||||
|
#define RESTORE_STANDARD_STREAM(TYPE) do \
|
||||||
|
{ \
|
||||||
|
if(!g_terminal_filebuf_##TYPE.isNull()) \
|
||||||
|
{ \
|
||||||
|
*(std##TYPE) = g_terminal_backup_file_##TYPE; \
|
||||||
|
std::c##TYPE.rdbuf(g_terminal_backup_fbuf_##TYPE); \
|
||||||
|
g_terminal_filebuf_##TYPE.reset(NULL); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
while(0)
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// TERMINAL VARIABLES
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//Critical section
|
||||||
|
static MUtils::Internal::CriticalSection g_terminal_lock;
|
||||||
|
|
||||||
|
//Terminal replacement streams
|
||||||
|
static bool g_terminal_attached = false;
|
||||||
|
static QScopedPointer<std::filebuf> g_terminal_filebuf_out;
|
||||||
|
static QScopedPointer<std::filebuf> g_terminal_filebuf_err;
|
||||||
|
|
||||||
|
//Backup of original streams
|
||||||
|
static FILE g_terminal_backup_file_out;
|
||||||
|
static FILE g_terminal_backup_file_err;
|
||||||
|
static std::streambuf* g_terminal_backup_fbuf_out;
|
||||||
|
static std::streambuf* g_terminal_backup_fbuf_err;
|
||||||
|
|
||||||
|
//The log file
|
||||||
|
static QScopedPointer<QFile> g_terminal_log_file;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// TERMINAL EXIT
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
static void terminal_restore(void)
|
||||||
|
{
|
||||||
|
MUtils::Internal::CSLocker lock(g_terminal_lock);
|
||||||
|
|
||||||
|
if(g_terminal_attached)
|
||||||
|
{
|
||||||
|
RESTORE_STANDARD_STREAM(out);
|
||||||
|
RESTORE_STANDARD_STREAM(err);
|
||||||
|
FreeConsole();
|
||||||
|
g_terminal_attached = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// TERMINAL SETUP
|
// TERMINAL SETUP
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static bool g_terminal_attached = false;
|
void MUtils::Terminal::setup(int &argc, char **argv, const char* const appName, const bool forceEnabled)
|
||||||
static QScopedPointer<std::filebuf> g_filebufStdOut;
|
|
||||||
static QScopedPointer<std::filebuf> g_filebufStdErr;
|
|
||||||
static QScopedPointer<QFile> g_log_file;
|
|
||||||
|
|
||||||
void MUtils::Terminal::setup(int &argc, char **argv, const bool forceEnabled)
|
|
||||||
{
|
{
|
||||||
MUtils::Internal::CSLocker lock(g_terminal_lock);
|
MUtils::Internal::CSLocker lock(g_terminal_lock);
|
||||||
bool enableConsole = (MUTILS_DEBUG) || forceEnabled;
|
bool enableConsole = (MUTILS_DEBUG) || forceEnabled;
|
||||||
@ -123,11 +183,11 @@ void MUtils::Terminal::setup(int &argc, char **argv, const bool forceEnabled)
|
|||||||
{
|
{
|
||||||
if(logfile && (logfile_len > 0))
|
if(logfile && (logfile_len > 0))
|
||||||
{
|
{
|
||||||
g_log_file.reset(new QFile(MUTILS_QSTR(logfile)));
|
g_terminal_log_file.reset(new QFile(MUTILS_QSTR(logfile)));
|
||||||
if(g_log_file->open(QIODevice::WriteOnly))
|
if(g_terminal_log_file->open(QIODevice::WriteOnly))
|
||||||
{
|
{
|
||||||
static const char MARKER[3] = { char(0xEF), char(0xBB), char(0xBF) };
|
static const char MARKER[3] = { char(0xEF), char(0xBB), char(0xBF) };
|
||||||
g_log_file->write(MARKER, 3);
|
g_terminal_log_file->write(MARKER, 3);
|
||||||
}
|
}
|
||||||
free(logfile);
|
free(logfile);
|
||||||
}
|
}
|
||||||
@ -155,9 +215,14 @@ void MUtils::Terminal::setup(int &argc, char **argv, const bool forceEnabled)
|
|||||||
{
|
{
|
||||||
if(AllocConsole() != FALSE)
|
if(AllocConsole() != FALSE)
|
||||||
{
|
{
|
||||||
SetConsoleCtrlHandler(NULL, TRUE);
|
|
||||||
SetConsoleTitle(L"LameXP - Audio Encoder Front-End | Debug Console");
|
|
||||||
SetConsoleOutputCP(CP_UTF8);
|
SetConsoleOutputCP(CP_UTF8);
|
||||||
|
SetConsoleCtrlHandler(NULL, TRUE);
|
||||||
|
if(appName && appName[0])
|
||||||
|
{
|
||||||
|
char title[128];
|
||||||
|
_snprintf_s(title, 128, _TRUNCATE, "%s | Debug Console", appName);
|
||||||
|
SetConsoleTitleA(title);
|
||||||
|
}
|
||||||
g_terminal_attached = true;
|
g_terminal_attached = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,23 +233,9 @@ void MUtils::Terminal::setup(int &argc, char **argv, const bool forceEnabled)
|
|||||||
//See: http://support.microsoft.com/default.aspx?scid=kb;en-us;105305
|
//See: http://support.microsoft.com/default.aspx?scid=kb;en-us;105305
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
const int flags = _O_WRONLY | _O_U8TEXT;
|
const int flags = _O_WRONLY | _O_U8TEXT;
|
||||||
const int hCrtStdOut = _open_osfhandle((intptr_t) GetStdHandle(STD_OUTPUT_HANDLE), flags);
|
REPLACE_STANDARD_STREAM(out, STD_OUTPUT_HANDLE);
|
||||||
const int hCrtStdErr = _open_osfhandle((intptr_t) GetStdHandle(STD_ERROR_HANDLE ), flags);
|
REPLACE_STANDARD_STREAM(err, STD_ERROR_HANDLE );
|
||||||
FILE *const hfStdOut = (hCrtStdOut >= 0) ? _fdopen(hCrtStdOut, "wb") : NULL;
|
atexit(terminal_restore);
|
||||||
FILE *const hfStdErr = (hCrtStdErr >= 0) ? _fdopen(hCrtStdErr, "wb") : NULL;
|
|
||||||
if(hfStdOut)
|
|
||||||
{
|
|
||||||
*stdout = *hfStdOut;
|
|
||||||
g_filebufStdOut.reset(new std::filebuf(hfStdOut));
|
|
||||||
std::cout.rdbuf(g_filebufStdOut.data());
|
|
||||||
}
|
|
||||||
if(hfStdErr)
|
|
||||||
{
|
|
||||||
*stderr = *hfStdErr;
|
|
||||||
g_filebufStdErr.reset(new std::filebuf(hfStdErr));
|
|
||||||
std::cerr.rdbuf(g_filebufStdErr.data());
|
|
||||||
std::cerr.rdbuf(new std::filebuf(hfStdErr));
|
|
||||||
}
|
|
||||||
|
|
||||||
const HWND hwndConsole = GetConsoleWindow();
|
const HWND hwndConsole = GetConsoleWindow();
|
||||||
if((hwndConsole != NULL) && (hwndConsole != INVALID_HANDLE_VALUE))
|
if((hwndConsole != NULL) && (hwndConsole != INVALID_HANDLE_VALUE))
|
||||||
@ -325,9 +376,9 @@ void MUtils::Terminal::write(const int &type, const char *const message)
|
|||||||
write_debugger_helper(type, message);
|
write_debugger_helper(type, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!g_log_file.isNull())
|
if(!g_terminal_log_file.isNull())
|
||||||
{
|
{
|
||||||
write_logfile_helper(g_log_file.data(), type, message);
|
write_logfile_helper(g_terminal_log_file.data(), type, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user