From 574644b3eb67945cfad0b71309ab4cd081965cb3 Mon Sep 17 00:00:00 2001 From: twanvl Date: Mon, 4 Aug 2008 21:28:24 +0000 Subject: [PATCH] If possible all errors are sent to stderr git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1055 0fc631ac-6414-0410-93d0-97cfa31319b6 --- src/cli/cli_main.cpp | 9 ++--- src/cli/cli_main.hpp | 1 - src/cli/text_io_handler.cpp | 68 ++++++++++++++++++++++++++----------- src/cli/text_io_handler.hpp | 6 ++++ src/util/error.cpp | 18 +++++++--- src/util/error.hpp | 3 ++ 6 files changed, 75 insertions(+), 30 deletions(-) diff --git a/src/cli/cli_main.cpp b/src/cli/cli_main.cpp index ba0df260..7fe65c53 100644 --- a/src/cli/cli_main.cpp +++ b/src/cli/cli_main.cpp @@ -69,6 +69,7 @@ void CLISetInterface::run() { running = true; while (running) { if (!cli.canGetLine()) break; + handle_pending_errors(); // show prompt if (!quiet) { cli << GRAY << _("> ") << NORMAL; @@ -153,7 +154,7 @@ void CLISetInterface::handleCommand(const String& command) { vector errors; ScriptP script = parse(command,nullptr,false,errors); if (!errors.empty()) { - FOR_EACH(error,errors) showError(error.what()); + FOR_EACH(error,errors) cli.showError(error.what()); return; } // execute command @@ -164,10 +165,6 @@ void CLISetInterface::handleCommand(const String& command) { cli << result->toCode() << ENDL; } } catch (const Error& e) { - showError(e.what()); + cli.showError(e.what()); } } - -void CLISetInterface::showError(const String& error) { - cli << RED << _("ERROR: ") << NORMAL << replace_all(error,_("\n"),_("\n ")) << ENDL; -} diff --git a/src/cli/cli_main.hpp b/src/cli/cli_main.hpp index 36462b7d..7c203ae3 100644 --- a/src/cli/cli_main.hpp +++ b/src/cli/cli_main.hpp @@ -32,7 +32,6 @@ class CLISetInterface : public SetView { void showWelcome(); void showUsage(); void handleCommand(const String& command); - void showError(const String& error); /// our own context, when no set is loaded Context& getContext(); diff --git a/src/cli/text_io_handler.cpp b/src/cli/text_io_handler.cpp index 06c35cee..85117e23 100644 --- a/src/cli/text_io_handler.cpp +++ b/src/cli/text_io_handler.cpp @@ -8,6 +8,7 @@ #include #include +#include // ----------------------------------------------------------------------------- : Text I/O handler @@ -17,22 +18,29 @@ const Char* PARAM = _("\x1B[33m"); const Char* FILE_EXT = _("\x1B[0;1m"); const Char* GRAY = _("\x1B[1;30m"); const Char* RED = _("\x1B[1;31m"); +const Char* YELLOW = _("\x1B[1;33m"); const Char* ENDL = _("\n"); TextIOHandler cli; +#ifdef __WXMSW__ + bool StdHandleOk(DWORD std_handle) { + // GetStdHandle sometimes returns an invalid handle instead of INVALID_HANDLE_VALUE + // check with GetHandleInformation + HANDLE h = GetStdHandle(std_handle); + DWORD flags; + return GetHandleInformation(h,&flags); + } +#endif void TextIOHandler::init() { + bool have_stderr; #ifdef __WXMSW__ have_console = false; escapes = false; // Detect whether to use console output - // GetStdHandle sometimes returns an invalid handle instead of INVALID_HANDLE_VALUE - // check with GetHandleInformation - HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE); - DWORD flags; - bool ok = GetHandleInformation(h,&flags); - if (ok) have_console = true; + have_console = StdHandleOk(STD_OUTPUT_HANDLE); + have_stderr = StdHandleOk(STD_ERROR_HANDLE); // Detect the --color flag, indicating we should allow escapes if (have_console) { for (int i = 1 ; i < wxTheApp->argc ; ++i) { @@ -45,8 +53,14 @@ void TextIOHandler::init() { #else // always use console on *nix (?) have_console = true; - escapes = true; + have_stderr = true; + escapes = true; // TODO: detect output redirection #endif + stream = stdout; + // always write to stderr if possible + if (have_console) { + write_errors_to_cli = true; + } } bool TextIOHandler::haveConsole() const { @@ -56,20 +70,10 @@ bool TextIOHandler::haveConsole() const { // ----------------------------------------------------------------------------- : Output -void TextIOHandler::flush() { - if (have_console) { - fflush(stdout); - } else if (!buffer.empty()) { - // Show message box - wxMessageBox(buffer, _("Magic Set Editor"), wxOK | wxICON_INFORMATION); - buffer.clear(); - } -} - TextIOHandler& TextIOHandler::operator << (const Char* str) { if (escapes || str[0] != 27) { if (have_console) { - IF_UNICODE(wprintf,printf)(str); + IF_UNICODE(fwprintf,fprintf)(stream,str); } else { buffer += str; } @@ -80,7 +84,7 @@ TextIOHandler& TextIOHandler::operator << (const Char* str) { TextIOHandler& TextIOHandler::operator << (const String& str) { if (escapes || str.empty() || str.GetChar(0) != 27) { if (have_console) { - IF_UNICODE(wprintf,printf)(str.c_str()); + IF_UNICODE(fwprintf,fprintf)(stream,str.c_str()); } else { buffer += str; } @@ -88,6 +92,16 @@ TextIOHandler& TextIOHandler::operator << (const String& str) { return *this; } +void TextIOHandler::flush() { + if (have_console) { + fflush(stream); + } else if (!buffer.empty()) { + // Show message box + wxMessageBox(buffer, _("Magic Set Editor"), wxOK | wxICON_INFORMATION); + buffer.clear(); + } +} + // ----------------------------------------------------------------------------- : Input String TextIOHandler::getLine() { @@ -109,3 +123,19 @@ String TextIOHandler::getLine() { bool TextIOHandler::canGetLine() { return !feof(stdin); } + +// ----------------------------------------------------------------------------- : Errors + +void TextIOHandler::showError(const String& message) { + stream = stdout; + *this << RED << _("ERROR: ") << NORMAL << replace_all(message,_("\n"),_("\n ")) << ENDL; + flush(); + stream = stdout; +} + +void TextIOHandler::showWarning(const String& message) { + stream = stdout; + *this << YELLOW << _("WARNING: ") << NORMAL << replace_all(message,_("\n"),_("\n ")) << ENDL; + flush(); + stream = stdout; +} diff --git a/src/cli/text_io_handler.hpp b/src/cli/text_io_handler.hpp index 10a4a912..aa0f5238 100644 --- a/src/cli/text_io_handler.hpp +++ b/src/cli/text_io_handler.hpp @@ -36,9 +36,15 @@ class TextIOHandler { /// Flush output void flush(); + /// Show an error message + void showError(const String& message); + /// Show a warning message + void showWarning(const String& message); + private: bool have_console; bool escapes; + FILE* stream; String buffer; ///< Buffer when not writing to console }; diff --git a/src/util/error.cpp b/src/util/error.cpp index f2b8bf3e..db0e919e 100644 --- a/src/util/error.cpp +++ b/src/util/error.cpp @@ -8,6 +8,7 @@ #include #include +#include DECLARE_TYPEOF_COLLECTION(ScriptParseError); @@ -62,6 +63,7 @@ String pending_errors; String pending_warnings; DECLARE_TYPEOF_COLLECTION(String); wxMutex crit_error_handling; +bool write_errors_to_cli = false; void show_pending_errors(); void show_pending_warnings(); @@ -82,7 +84,7 @@ void handle_error(const String& e, bool allow_duplicate = true, bool now = true) pending_errors += e; } // show messages - if (now && wxThread::IsMain()) { + if ((write_errors_to_cli || now) && wxThread::IsMain()) { show_pending_warnings(); // warnings are older, show them first show_pending_errors(); } @@ -106,7 +108,7 @@ void handle_warning(const String& w, bool now) { pending_warnings += w; } // show messages - if (now && wxThread::IsMain()) { + if ((write_errors_to_cli || now) && wxThread::IsMain()) { show_pending_errors(); show_pending_warnings(); } @@ -122,7 +124,11 @@ void show_pending_errors() { if (crit_error_handling.TryLock() != wxMUTEX_NO_ERROR) return; if (!pending_errors.empty()) { - wxMessageBox(pending_errors, _("Error"), wxOK | wxICON_ERROR); + if (write_errors_to_cli) { + cli.showError(pending_errors); + } else { + wxMessageBox(pending_errors, _("Error"), wxOK | wxICON_ERROR); + } pending_errors.clear(); } crit_error_handling.Unlock(); @@ -132,7 +138,11 @@ void show_pending_warnings() { if (crit_error_handling.TryLock() != wxMUTEX_NO_ERROR) return; if (!pending_warnings.empty()) { - wxMessageBox(pending_warnings, _("Warning"), wxOK | wxICON_EXCLAMATION); + if (write_errors_to_cli) { + cli.showWarning(pending_warnings); + } else { + wxMessageBox(pending_warnings, _("Warning"), wxOK | wxICON_EXCLAMATION); + } pending_warnings.clear(); } crit_error_handling.Unlock(); diff --git a/src/util/error.hpp b/src/util/error.hpp index f76cff76..ff05cb5f 100644 --- a/src/util/error.hpp +++ b/src/util/error.hpp @@ -110,6 +110,9 @@ class ScriptError : public Error { // ----------------------------------------------------------------------------- : Error handling +/// Should errors be written to stdout? +extern bool write_errors_to_cli; + /// Handle an error by showing a message box /** If !allow_duplicate and the error is the same as the previous error, does nothing. * If !now the error is handled by a later call to handle_pending_errors()