diff --git a/include/MUtils/Startup.h b/include/MUtils/Startup.h index ad7699c..e420982 100644 --- a/include/MUtils/Startup.h +++ b/include/MUtils/Startup.h @@ -37,7 +37,7 @@ namespace MUtils typedef int (main_function_t)(int &argc, char **argv); //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 MUTILS_API QApplication *create_qt(int &argc, char **argv, const QString &appName); diff --git a/include/MUtils/Terminal.h b/include/MUtils/Terminal.h index e5039be..014296c 100644 --- a/include/MUtils/Terminal.h +++ b/include/MUtils/Terminal.h @@ -34,7 +34,7 @@ namespace MUtils namespace 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 MUTILS_API void write(const int &type, const char *const message); diff --git a/src/Startup.cpp b/src/Startup.cpp index 50e7015..aaa82cd 100644 --- a/src/Startup.cpp +++ b/src/Startup.cpp @@ -64,19 +64,19 @@ static bool qt_event_filter(void *message, long *result) // 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); - MUtils::Terminal::setup(argc, argv, MUTILS_DEBUG || debugConsole); + MUtils::Terminal::setup(argc, argv, appName, MUTILS_DEBUG || debugConsole); 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; try { - iResult = startup_main(argc, argv, entry_point, debugConsole); + iResult = startup_main(argc, argv, entry_point, appName, debugConsole); } catch(const std::exception &error) { @@ -91,21 +91,21 @@ static int startup_helper(int &argc, char **argv, MUtils::Startup::main_function 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; #if (MUTILS_DEBUG) #ifdef _MSC_VER _CrtSetDbgFlag(_CRTDBG_CHECK_ALWAYS_DF || _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG)); #endif //_MSCVER - iResult = startup_main(argc, argv, entry_point, debugConsole); + iResult = startup_main(argc, argv, entry_point, appName, debugConsole); #else //MUTILS_DEBUG #ifdef _MSC_VER __try { MUtils::ErrorHandler::initialize(); MUtils::OS::check_debugger(); - iResult = startup_helper(argc, argv, entry_point, debugConsole); + iResult = startup_helper(argc, argv, entry_point, appName, debugConsole); } __except(1) { @@ -115,7 +115,7 @@ int MUtils::Startup::startup(int &argc, char **argv, main_function_t *const entr #else //_MSCVER MUtils::ErrorHandler::initialize(); MUtils::OS::check_debugger(); - iResult = startup_helper(argc, argv, entry_point, debugConsole); + iResult = startup_helper(argc, argv, entry_point, appName, debugConsole); #endif //_MSCVER #endif //MUTILS_DEBUG return iResult; diff --git a/src/Terminal_Win32.cpp b/src/Terminal_Win32.cpp index 9f1b404..0dcc7f2 100644 --- a/src/Terminal_Win32.cpp +++ b/src/Terminal_Win32.cpp @@ -45,9 +45,6 @@ #include #include -//Lock -static MUtils::Internal::CriticalSection g_terminal_lock; - #ifdef _MSC_VER #define stricmp(X,Y) _stricmp((X),(Y)) #endif @@ -102,16 +99,79 @@ static const char *clean_str(char *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 g_terminal_filebuf_out; +static QScopedPointer 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 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 /////////////////////////////////////////////////////////////////////////////// -static bool g_terminal_attached = false; -static QScopedPointer g_filebufStdOut; -static QScopedPointer g_filebufStdErr; -static QScopedPointer g_log_file; - -void MUtils::Terminal::setup(int &argc, char **argv, const bool forceEnabled) +void MUtils::Terminal::setup(int &argc, char **argv, const char* const appName, const bool forceEnabled) { MUtils::Internal::CSLocker lock(g_terminal_lock); 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)) { - g_log_file.reset(new QFile(MUTILS_QSTR(logfile))); - if(g_log_file->open(QIODevice::WriteOnly)) + g_terminal_log_file.reset(new QFile(MUTILS_QSTR(logfile))); + if(g_terminal_log_file->open(QIODevice::WriteOnly)) { 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); } @@ -155,9 +215,14 @@ void MUtils::Terminal::setup(int &argc, char **argv, const bool forceEnabled) { if(AllocConsole() != FALSE) { - SetConsoleCtrlHandler(NULL, TRUE); - SetConsoleTitle(L"LameXP - Audio Encoder Front-End | Debug Console"); 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; } } @@ -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 //------------------------------------------------------------------- const int flags = _O_WRONLY | _O_U8TEXT; - const int hCrtStdOut = _open_osfhandle((intptr_t) GetStdHandle(STD_OUTPUT_HANDLE), flags); - const int hCrtStdErr = _open_osfhandle((intptr_t) GetStdHandle(STD_ERROR_HANDLE ), flags); - FILE *const hfStdOut = (hCrtStdOut >= 0) ? _fdopen(hCrtStdOut, "wb") : NULL; - 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)); - } + REPLACE_STANDARD_STREAM(out, STD_OUTPUT_HANDLE); + REPLACE_STANDARD_STREAM(err, STD_ERROR_HANDLE ); + atexit(terminal_restore); const HWND hwndConsole = GetConsoleWindow(); 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); } - 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); } }