From 91e4e468dd5b6738a613b2fb563613de532a344c Mon Sep 17 00:00:00 2001 From: wmayer Date: Sun, 6 Mar 2022 10:13:47 +0100 Subject: [PATCH] Base: move ILogger sub-classes to their own source files in order to reduce including stream classes in client code --- src/App/Application.cpp | 2 +- src/App/Document.cpp | 1 + src/App/DocumentPyImp.cpp | 1 + src/App/PropertyFile.cpp | 1 + src/App/PropertyStandard.cpp | 1 + src/Base/Builder3D.cpp | 1 + src/Base/CMakeLists.txt | 2 + src/Base/Console.cpp | 308 ++----------------- src/Base/Console.h | 79 ----- src/Base/ConsoleObserver.cpp | 277 +++++++++++++++++ src/Base/ConsoleObserver.h | 115 +++++++ src/Base/Interpreter.cpp | 1 + src/Base/Reader.cpp | 1 + src/Gui/Application.cpp | 1 + src/Gui/AutoSaver.cpp | 1 + src/Gui/CommandDoc.cpp | 1 + src/Gui/DocumentPyImp.cpp | 1 + src/Gui/DownloadManager.cpp | 3 +- src/Gui/GuiConsole.cpp | 3 +- src/Main/MainGui.cpp | 2 +- src/Main/MainPy.cpp | 1 + src/Mod/Drawing/App/FeaturePage.cpp | 3 +- src/Mod/Fem/App/PropertyPostDataObject.cpp | 3 +- src/Mod/Inspection/App/InspectionFeature.cpp | 1 + src/Mod/Mesh/App/Mesh.cpp | 1 + src/Mod/Mesh/App/MeshPyImp.cpp | 1 + src/Mod/Mesh/Gui/RemeshGmsh.cpp | 1 + src/Mod/Mesh/Gui/ViewProvider.cpp | 1 + src/Mod/MeshPart/Gui/Tessellation.cpp | 1 + src/Mod/Part/App/TopoShapePyImp.cpp | 1 + src/Mod/Raytracing/App/PovTools.cpp | 1 + src/Mod/Spreadsheet/Gui/SheetTableView.cpp | 1 + src/Mod/TechDraw/App/LineGroup.cpp | 1 + src/Mod/TechDraw/App/PreCompiled.h | 1 + 34 files changed, 460 insertions(+), 360 deletions(-) create mode 100644 src/Base/ConsoleObserver.cpp create mode 100644 src/Base/ConsoleObserver.h diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 71517fc674..40a621bd09 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -58,7 +58,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 09a3e58497..8e6cf23313 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -91,6 +91,7 @@ recompute path. Also, it enables more complicated dependencies beyond trees. #include #include #include +#include #include "Document.h" #include "Application.h" diff --git a/src/App/DocumentPyImp.cpp b/src/App/DocumentPyImp.cpp index 4f7bc1a6f9..3b4c3e96de 100644 --- a/src/App/DocumentPyImp.cpp +++ b/src/App/DocumentPyImp.cpp @@ -25,6 +25,7 @@ #include #include +#include #include "Document.h" #include "DocumentObject.h" diff --git a/src/App/PropertyFile.cpp b/src/App/PropertyFile.cpp index 8dc8cfe3e7..5c14e43bae 100644 --- a/src/App/PropertyFile.cpp +++ b/src/App/PropertyFile.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/src/App/PropertyStandard.cpp b/src/App/PropertyStandard.cpp index cf84b57421..0fc1cf9821 100644 --- a/src/App/PropertyStandard.cpp +++ b/src/App/PropertyStandard.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "PropertyStandard.h" diff --git a/src/Base/Builder3D.cpp b/src/Base/Builder3D.cpp index a090485985..073413244c 100644 --- a/src/Base/Builder3D.cpp +++ b/src/Base/Builder3D.cpp @@ -26,6 +26,7 @@ #ifndef _PreComp_ # include # include +# include #endif #include "Builder3D.h" diff --git a/src/Base/CMakeLists.txt b/src/Base/CMakeLists.txt index bbe8c09b9f..f5a711055d 100644 --- a/src/Base/CMakeLists.txt +++ b/src/Base/CMakeLists.txt @@ -222,6 +222,7 @@ SET(FreeCADBase_CPP_SRCS BoundBoxPyImp.cpp Builder3D.cpp Console.cpp + ConsoleObserver.cpp CoordinateSystem.cpp CoordinateSystemPyImp.cpp Debugger.cpp @@ -285,6 +286,7 @@ SET(FreeCADBase_HPP_SRCS BoundBox.h Builder3D.h Console.h + ConsoleObserver.h Converter.h CoordinateSystem.h Debugger.h diff --git a/src/Base/Console.cpp b/src/Base/Console.cpp index e03a4acc36..e68f1cb353 100644 --- a/src/Base/Console.cpp +++ b/src/Base/Console.cpp @@ -35,7 +35,6 @@ #include "Console.h" #include "Exception.h" #include "PyObjectBase.h" -#include "frameobject.h" #include @@ -70,7 +69,7 @@ public: } static void destruct() { delete instance; - instance = 0; + instance = nullptr; } void customEvent(QEvent* ev) { @@ -104,7 +103,7 @@ private: static ConsoleOutput* instance; }; -ConsoleOutput* ConsoleOutput::instance = 0; +ConsoleOutput* ConsoleOutput::instance = nullptr; } @@ -112,7 +111,7 @@ ConsoleOutput* ConsoleOutput::instance = 0; // Construction destruction -ConsoleSingleton::ConsoleSingleton(void) +ConsoleSingleton::ConsoleSingleton() : _bVerbose(true) , _bCanRefresh(true) , connectionMode(Direct) @@ -404,14 +403,14 @@ ILogger *ConsoleSingleton::Get(const char *Name) const if (OName && strcmp(OName,Name) == 0) return *Iter; } - return 0; + return nullptr; } int *ConsoleSingleton::GetLogLevel(const char *tag, bool create) { if (!tag) tag = ""; if (_logLevels.find(tag) != _logLevels.end()) return &_logLevels[tag]; - if (!create) return 0; + if (!create) return nullptr; int &ret = _logLevels[tag]; ret = -1; return &ret; @@ -429,17 +428,17 @@ void ConsoleSingleton::EnableRefresh(bool enable) { //************************************************************************** // Singleton stuff -ConsoleSingleton * ConsoleSingleton::_pcSingleton = 0; +ConsoleSingleton * ConsoleSingleton::_pcSingleton = nullptr; -void ConsoleSingleton::Destruct(void) +void ConsoleSingleton::Destruct() { // not initialized or double destructed! assert(_pcSingleton); delete _pcSingleton; - _pcSingleton=0; + _pcSingleton=nullptr; } -ConsoleSingleton & ConsoleSingleton::Instance(void) +ConsoleSingleton & ConsoleSingleton::Instance() { // not initialized? if (!_pcSingleton) @@ -454,19 +453,19 @@ ConsoleSingleton & ConsoleSingleton::Instance(void) // ConsoleSingleton Methods // Methods structure PyMethodDef ConsoleSingleton::Methods[] = { - {"PrintMessage", (PyCFunction) ConsoleSingleton::sPyMessage, METH_VARARGS, + {"PrintMessage", ConsoleSingleton::sPyMessage, METH_VARARGS, "PrintMessage(string) -- Print a message to the output"}, - {"PrintLog", (PyCFunction) ConsoleSingleton::sPyLog, METH_VARARGS, + {"PrintLog", ConsoleSingleton::sPyLog, METH_VARARGS, "PrintLog(string) -- Print a log message to the output"}, - {"PrintError" , (PyCFunction) ConsoleSingleton::sPyError, METH_VARARGS, + {"PrintError" , ConsoleSingleton::sPyError, METH_VARARGS, "PrintError(string) -- Print an error message to the output"}, - {"PrintWarning", (PyCFunction) ConsoleSingleton::sPyWarning, METH_VARARGS, + {"PrintWarning", ConsoleSingleton::sPyWarning, METH_VARARGS, "PrintWarning -- Print a warning to the output"}, - {"SetStatus", (PyCFunction) ConsoleSingleton::sPySetStatus, METH_VARARGS, + {"SetStatus", ConsoleSingleton::sPySetStatus, METH_VARARGS, "Set the status for either Log, Msg, Wrn or Error for an observer"}, - {"GetStatus", (PyCFunction) ConsoleSingleton::sPyGetStatus, METH_VARARGS, + {"GetStatus", ConsoleSingleton::sPyGetStatus, METH_VARARGS, "Get the status for either Log, Msg, Wrn or Error for an observer"}, - {NULL, NULL, 0, NULL} /* Sentinel */ + {nullptr, nullptr, 0, nullptr} /* Sentinel */ }; @@ -474,10 +473,10 @@ PyObject *ConsoleSingleton::sPyMessage(PyObject * /*self*/, PyObject *args) { PyObject *output; if (!PyArg_ParseTuple(args, "O", &output)) - return NULL; + return nullptr; - const char* string=0; - PyObject* unicode=0; + const char* string=nullptr; + PyObject* unicode=nullptr; if (PyUnicode_Check(output)) { string = PyUnicode_AsUTF8(output); } @@ -502,10 +501,10 @@ PyObject *ConsoleSingleton::sPyWarning(PyObject * /*self*/, PyObject *args) { PyObject *output; if (!PyArg_ParseTuple(args, "O", &output)) - return NULL; + return nullptr; - const char* string=0; - PyObject* unicode=0; + const char* string=nullptr; + PyObject* unicode=nullptr; if (PyUnicode_Check(output)) { string = PyUnicode_AsUTF8(output); } @@ -530,10 +529,10 @@ PyObject *ConsoleSingleton::sPyError(PyObject * /*self*/, PyObject *args) { PyObject *output; if (!PyArg_ParseTuple(args, "O", &output)) - return NULL; + return nullptr; - const char* string=0; - PyObject* unicode=0; + const char* string=nullptr; + PyObject* unicode=nullptr; if (PyUnicode_Check(output)) { string = PyUnicode_AsUTF8(output); } @@ -558,10 +557,10 @@ PyObject *ConsoleSingleton::sPyLog(PyObject * /*self*/, PyObject *args) { PyObject *output; if (!PyArg_ParseTuple(args, "O", &output)) - return NULL; + return nullptr; - const char* string=0; - PyObject* unicode=0; + const char* string=nullptr; + PyObject* unicode=nullptr; if (PyUnicode_Check(output)) { string = PyUnicode_AsUTF8(output); } @@ -587,7 +586,7 @@ PyObject *ConsoleSingleton::sPyGetStatus(PyObject * /*self*/, PyObject *args) char *pstr1; char *pstr2; if (!PyArg_ParseTuple(args, "ss", &pstr1, &pstr2)) // convert args: Python->C - return NULL; // NULL triggers exception + return nullptr; // NULL triggers exception PY_TRY{ bool b=false; @@ -616,8 +615,8 @@ PyObject *ConsoleSingleton::sPySetStatus(PyObject * /*self*/, PyObject *args) char *pstr1; char *pstr2; int Bool; - if (!PyArg_ParseTuple(args, "ssi", &pstr1, &pstr2,&Bool)) // convert args: Python->C - return NULL; // NULL triggers exception + if (!PyArg_ParseTuple(args, "ssi", &pstr1, &pstr2,&Bool)) + return nullptr; PY_TRY{ ILogger *pObs = Instance().Get(pstr1); @@ -637,253 +636,12 @@ PyObject *ConsoleSingleton::sPySetStatus(PyObject * /*self*/, PyObject *args) Py_INCREF(Py_None); return Py_None; } - else { + else { Py_Error(Base::BaseExceptionFreeCADError,"Unknown Console Type"); - } + } } PY_CATCH; } -//========================================================================= -// some special observers - Base::ILogger::~ILogger() {} - -ConsoleObserverFile::ConsoleObserverFile(const char *sFileName) - : cFileStream(Base::FileInfo(sFileName)) // can be in UTF8 -{ - if (!cFileStream.is_open()) - Console().Warning("Cannot open log file '%s'.\n", sFileName); - // mark the file as a UTF-8 encoded file - unsigned char bom[3] = {0xef, 0xbb, 0xbf}; - cFileStream.write((const char*)bom,3*sizeof(char)); -} - -ConsoleObserverFile::~ConsoleObserverFile() -{ - cFileStream.close(); -} - -void ConsoleObserverFile::SendLog(const std::string& msg, LogStyle level) -{ - std::string prefix; - switch(level){ - case LogStyle::Warning: - prefix = "Wrn: "; - break; - case LogStyle::Message: - prefix = "Msg: "; - break; - case LogStyle::Error: - prefix = "Err: "; - break; - case LogStyle::Log: - prefix = "Log: "; - break; - } - - cFileStream << prefix << msg; - cFileStream.flush(); -} - -ConsoleObserverStd::ConsoleObserverStd() : -# if defined(FC_OS_WIN32) - useColorStderr(true) -# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD) - useColorStderr( isatty(STDERR_FILENO) ) -# else - useColorStderr(false) -# endif -{ - bLog = false; -} - -ConsoleObserverStd::~ConsoleObserverStd() -{ -} - -void ConsoleObserverStd::SendLog(const std::string& msg, LogStyle level) -{ - switch(level){ - case LogStyle::Warning: - this->Warning(msg.c_str()); - break; - case LogStyle::Message: - this->Message(msg.c_str()); - break; - case LogStyle::Error: - this->Error(msg.c_str()); - break; - case LogStyle::Log: - this->Log(msg.c_str()); - break; - } -} - -void ConsoleObserverStd::Message(const char *sMsg) -{ - printf("%s",sMsg); -} - -void ConsoleObserverStd::Warning(const char *sWarn) -{ - if (useColorStderr) { -# if defined(FC_OS_WIN32) - ::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), FOREGROUND_GREEN| FOREGROUND_BLUE); -# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD) - fprintf(stderr, "\033[1;33m"); -# endif - } - - fprintf(stderr, "%s", sWarn); - - if (useColorStderr) { -# if defined(FC_OS_WIN32) - ::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE ); -# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD) - fprintf(stderr, "\033[0m"); -# endif - } -} - -void ConsoleObserverStd::Error (const char *sErr) -{ - if (useColorStderr) { -# if defined(FC_OS_WIN32) - ::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), FOREGROUND_RED|FOREGROUND_INTENSITY ); -# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD) - fprintf(stderr, "\033[1;31m"); -# endif - } - - fprintf(stderr, "%s", sErr); - - if (useColorStderr) { -# if defined(FC_OS_WIN32) - ::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE ); -# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD) - fprintf(stderr, "\033[0m"); -# endif - } -} - -void ConsoleObserverStd::Log (const char *sErr) -{ - if (useColorStderr) { -# if defined(FC_OS_WIN32) - ::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), FOREGROUND_RED |FOREGROUND_GREEN); -# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD) - fprintf(stderr, "\033[1;36m"); -# endif - } - - fprintf(stderr, "%s", sErr); - - if (useColorStderr) { -# if defined(FC_OS_WIN32) - ::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE ); -# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD) - fprintf(stderr, "\033[0m"); -# endif - } -} - -RedirectStdOutput::RedirectStdOutput() -{ - buffer.reserve(80); -} - -int RedirectStdOutput::overflow(int c) -{ - if (c != EOF) - buffer.push_back((char)c); - return c; -} - -int RedirectStdOutput::sync() -{ - // Print as log as this might be verbose - if (!buffer.empty() && buffer.back() == '\n') { - Base::Console().Log("%s", buffer.c_str()); - buffer.clear(); - } - return 0; -} - -RedirectStdLog::RedirectStdLog() -{ - buffer.reserve(80); -} - -int RedirectStdLog::overflow(int c) -{ - if (c != EOF) - buffer.push_back((char)c); - return c; -} - -int RedirectStdLog::sync() -{ - // Print as log as this might be verbose - if (!buffer.empty() && buffer.back() == '\n') { - Base::Console().Log("%s", buffer.c_str()); - buffer.clear(); - } - return 0; -} - -RedirectStdError::RedirectStdError() -{ - buffer.reserve(80); -} - -int RedirectStdError::overflow(int c) -{ - if (c != EOF) - buffer.push_back((char)c); - return c; -} - -int RedirectStdError::sync() -{ - if (!buffer.empty() && buffer.back() == '\n') { - Base::Console().Error("%s", buffer.c_str()); - buffer.clear(); - } - return 0; -} - -//--------------------------------------------------------- - -std::stringstream &LogLevel::prefix(std::stringstream &str, const char *src, int line) -{ - static FC_TIME_POINT s_tstart; - static bool s_timing = false; - if (print_time) { - if (!s_timing) { - s_timing = true; - _FC_TIME_INIT(s_tstart); - } - auto tnow = std::chrono::FC_TIME_CLOCK::now(); - auto d = std::chrono::duration_cast(tnow-s_tstart); - str << d.count() << ' '; - } - if (print_tag) str << '<' << tag << "> "; - if (print_src==2) { - PyFrameObject* frame = PyEval_GetFrame(); - if (frame) { - line = PyFrame_GetLineNumber(frame); - src = PyUnicode_AsUTF8(frame->f_code->co_filename); - } - } - if (print_src && src && src[0]) { -#ifdef FC_OS_WIN32 - const char *_f = std::strrchr(src, '\\'); -#else - const char *_f = std::strrchr(src, '/'); -#endif - str << (_f?_f+1:src)<<"("< #include #include #include @@ -670,84 +669,6 @@ namespace Base { }; - //========================================================================= - // some special observers - - /** The LoggingConsoleObserver class - * This class is used by the main modules to write Console messages and logs to a file - */ - class BaseExport ConsoleObserverFile : public ILogger -{ -public: - ConsoleObserverFile(const char *sFileName); - ~ConsoleObserverFile() override; - - void SendLog(const std::string& message, LogStyle level) override; - const char* Name(void) override {return "File";} - -protected: - Base::ofstream cFileStream; -}; - -/** The CmdConsoleObserver class - * This class is used by the main modules to write Console messages and logs the system con. - */ -class BaseExport ConsoleObserverStd: public ILogger -{ -public: - ConsoleObserverStd(); - ~ConsoleObserverStd() override; - void SendLog(const std::string& message, LogStyle level) override; - const char* Name(void) override {return "Console";} -protected: - bool useColorStderr; -private: - void Warning(const char *sWarn); - void Message(const char *sMsg); - void Error (const char *sErr); - void Log (const char *sErr); -}; - -class BaseExport RedirectStdOutput : public std::streambuf -{ -public: - RedirectStdOutput(); - -protected: - int overflow(int c = EOF); - int sync(); - -private: - std::string buffer; -}; - -class BaseExport RedirectStdError : public std::streambuf -{ -public: - RedirectStdError(); - -protected: - int overflow(int c = EOF); - int sync(); - -private: - std::string buffer; -}; - -class BaseExport RedirectStdLog : public std::streambuf -{ -public: - RedirectStdLog(); - -protected: - int overflow(int c = EOF); - int sync(); - -private: - std::string buffer; -}; - - } // namespace Base #if defined(__clang__) diff --git a/src/Base/ConsoleObserver.cpp b/src/Base/ConsoleObserver.cpp new file mode 100644 index 0000000000..ddf2becea8 --- /dev/null +++ b/src/Base/ConsoleObserver.cpp @@ -0,0 +1,277 @@ +/*************************************************************************** + * Copyright (c) 2002 Jürgen Riegel * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License (LGPL) * + * as published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * for detail see the LICENCE text file. * + * * + * FreeCAD is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with FreeCAD; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * + * USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +# include +# include +#endif + +#include "ConsoleObserver.h" + + +using namespace Base; + + +//========================================================================= +// some special observers + +ConsoleObserverFile::ConsoleObserverFile(const char *sFileName) + : cFileStream(Base::FileInfo(sFileName)) // can be in UTF8 +{ + if (!cFileStream.is_open()) + Console().Warning("Cannot open log file '%s'.\n", sFileName); + // mark the file as a UTF-8 encoded file + unsigned char bom[3] = {0xef, 0xbb, 0xbf}; + cFileStream.write(reinterpret_cast(bom), 3*sizeof(char)); +} + +ConsoleObserverFile::~ConsoleObserverFile() +{ + cFileStream.close(); +} + +void ConsoleObserverFile::SendLog(const std::string& msg, LogStyle level) +{ + std::string prefix; + switch(level){ + case LogStyle::Warning: + prefix = "Wrn: "; + break; + case LogStyle::Message: + prefix = "Msg: "; + break; + case LogStyle::Error: + prefix = "Err: "; + break; + case LogStyle::Log: + prefix = "Log: "; + break; + } + + cFileStream << prefix << msg; + cFileStream.flush(); +} + +ConsoleObserverStd::ConsoleObserverStd() : +# if defined(FC_OS_WIN32) + useColorStderr(true) +# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD) + useColorStderr( isatty(STDERR_FILENO) ) +# else + useColorStderr(false) +# endif +{ + bLog = false; +} + +ConsoleObserverStd::~ConsoleObserverStd() +{ +} + +void ConsoleObserverStd::SendLog(const std::string& msg, LogStyle level) +{ + switch(level){ + case LogStyle::Warning: + this->Warning(msg.c_str()); + break; + case LogStyle::Message: + this->Message(msg.c_str()); + break; + case LogStyle::Error: + this->Error(msg.c_str()); + break; + case LogStyle::Log: + this->Log(msg.c_str()); + break; + } +} + +void ConsoleObserverStd::Message(const char *sMsg) +{ + printf("%s",sMsg); +} + +void ConsoleObserverStd::Warning(const char *sWarn) +{ + if (useColorStderr) { +# if defined(FC_OS_WIN32) + ::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), FOREGROUND_GREEN| FOREGROUND_BLUE); +# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD) + fprintf(stderr, "\033[1;33m"); +# endif + } + + fprintf(stderr, "%s", sWarn); + + if (useColorStderr) { +# if defined(FC_OS_WIN32) + ::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE ); +# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD) + fprintf(stderr, "\033[0m"); +# endif + } +} + +void ConsoleObserverStd::Error (const char *sErr) +{ + if (useColorStderr) { +# if defined(FC_OS_WIN32) + ::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), FOREGROUND_RED|FOREGROUND_INTENSITY ); +# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD) + fprintf(stderr, "\033[1;31m"); +# endif + } + + fprintf(stderr, "%s", sErr); + + if (useColorStderr) { +# if defined(FC_OS_WIN32) + ::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE ); +# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD) + fprintf(stderr, "\033[0m"); +# endif + } +} + +void ConsoleObserverStd::Log (const char *sErr) +{ + if (useColorStderr) { +# if defined(FC_OS_WIN32) + ::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE), FOREGROUND_RED |FOREGROUND_GREEN); +# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD) + fprintf(stderr, "\033[1;36m"); +# endif + } + + fprintf(stderr, "%s", sErr); + + if (useColorStderr) { +# if defined(FC_OS_WIN32) + ::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE ); +# elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD) + fprintf(stderr, "\033[0m"); +# endif + } +} + +RedirectStdOutput::RedirectStdOutput() +{ + buffer.reserve(80); +} + +int RedirectStdOutput::overflow(int c) +{ + if (c != EOF) + buffer.push_back(static_cast(c)); + return c; +} + +int RedirectStdOutput::sync() +{ + // Print as log as this might be verbose + if (!buffer.empty() && buffer.back() == '\n') { + Base::Console().Log("%s", buffer.c_str()); + buffer.clear(); + } + return 0; +} + +RedirectStdLog::RedirectStdLog() +{ + buffer.reserve(80); +} + +int RedirectStdLog::overflow(int c) +{ + if (c != EOF) + buffer.push_back(static_cast(c)); + return c; +} + +int RedirectStdLog::sync() +{ + // Print as log as this might be verbose + if (!buffer.empty() && buffer.back() == '\n') { + Base::Console().Log("%s", buffer.c_str()); + buffer.clear(); + } + return 0; +} + +RedirectStdError::RedirectStdError() +{ + buffer.reserve(80); +} + +int RedirectStdError::overflow(int c) +{ + if (c != EOF) + buffer.push_back(static_cast(c)); + return c; +} + +int RedirectStdError::sync() +{ + if (!buffer.empty() && buffer.back() == '\n') { + Base::Console().Error("%s", buffer.c_str()); + buffer.clear(); + } + return 0; +} + +//--------------------------------------------------------- + +std::stringstream &LogLevel::prefix(std::stringstream &str, const char *src, int line) +{ + static FC_TIME_POINT s_tstart; + static bool s_timing = false; + if (print_time) { + if (!s_timing) { + s_timing = true; + _FC_TIME_INIT(s_tstart); + } + auto tnow = std::chrono::FC_TIME_CLOCK::now(); + auto d = std::chrono::duration_cast(tnow-s_tstart); + str << d.count() << ' '; + } + if (print_tag) str << '<' << tag << "> "; + if (print_src==2) { + PyFrameObject* frame = PyEval_GetFrame(); + if (frame) { + line = PyFrame_GetLineNumber(frame); + src = PyUnicode_AsUTF8(frame->f_code->co_filename); + } + } + if (print_src && src && src[0]) { +#ifdef FC_OS_WIN32 + const char *_f = std::strrchr(src, '\\'); +#else + const char *_f = std::strrchr(src, '/'); +#endif + str << (_f?_f+1:src)<<"("< * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License (LGPL) * + * as published by the Free Software Foundation; either version 2 of * + * the License, or (at your option) any later version. * + * for detail see the LICENCE text file. * + * * + * FreeCAD is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with FreeCAD; if not, write to the Free Software * + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * + * USA * + * * + ***************************************************************************/ + + + + +#ifndef BASE_CONSOLEOBSERVER_H +#define BASE_CONSOLEOBSERVER_H + +#include +#include + +namespace Base { + +//========================================================================= +// some special observers + +/** The LoggingConsoleObserver class + * This class is used by the main modules to write Console messages and logs to a file + */ +class BaseExport ConsoleObserverFile : public ILogger +{ +public: + ConsoleObserverFile(const char *sFileName); + ~ConsoleObserverFile() override; + + void SendLog(const std::string& message, LogStyle level) override; + const char* Name(void) override {return "File";} + +protected: + Base::ofstream cFileStream; +}; + +/** The CmdConsoleObserver class + * This class is used by the main modules to write Console messages and logs the system con. + */ +class BaseExport ConsoleObserverStd: public ILogger +{ +public: + ConsoleObserverStd(); + ~ConsoleObserverStd() override; + void SendLog(const std::string& message, LogStyle level) override; + const char* Name(void) override {return "Console";} +protected: + bool useColorStderr; +private: + void Warning(const char *sWarn); + void Message(const char *sMsg); + void Error (const char *sErr); + void Log (const char *sErr); +}; + +class BaseExport RedirectStdOutput : public std::streambuf +{ +public: + RedirectStdOutput(); + +protected: + int overflow(int c = EOF); + int sync(); + +private: + std::string buffer; +}; + +class BaseExport RedirectStdError : public std::streambuf +{ +public: + RedirectStdError(); + +protected: + int overflow(int c = EOF); + int sync(); + +private: + std::string buffer; +}; + +class BaseExport RedirectStdLog : public std::streambuf +{ +public: + RedirectStdLog(); + +protected: + int overflow(int c = EOF); + int sync(); + +private: + std::string buffer; +}; + + +} // namespace Base + +#endif // BASE_CONSOLEOBSERVER_H diff --git a/src/Base/Interpreter.cpp b/src/Base/Interpreter.cpp index 3a75866ee5..aabe9fc667 100644 --- a/src/Base/Interpreter.cpp +++ b/src/Base/Interpreter.cpp @@ -35,6 +35,7 @@ #include "FileInfo.h" #include "PyObjectBase.h" #include "PyTools.h" +#include "Stream.h" char format2[1024]; //Warning! Can't go over 512 characters!!! diff --git a/src/Base/Reader.cpp b/src/Base/Reader.cpp index 033563722d..cf963b6ce7 100644 --- a/src/Base/Reader.cpp +++ b/src/Base/Reader.cpp @@ -35,6 +35,7 @@ #include "InputSource.h" #include "Persistence.h" #include "Sequencer.h" +#include "Stream.h" #include "XMLTools.h" #ifdef _MSC_VER diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index 2b4676f600..13546fa50d 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include diff --git a/src/Gui/AutoSaver.cpp b/src/Gui/AutoSaver.cpp index 7bc408a681..56f5b0518e 100644 --- a/src/Gui/AutoSaver.cpp +++ b/src/Gui/AutoSaver.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include diff --git a/src/Gui/CommandDoc.cpp b/src/Gui/CommandDoc.cpp index 19956b0a3e..b0091b911a 100644 --- a/src/Gui/CommandDoc.cpp +++ b/src/Gui/CommandDoc.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include "Action.h" diff --git a/src/Gui/DocumentPyImp.cpp b/src/Gui/DocumentPyImp.cpp index d6c6d80616..379e9c81b0 100644 --- a/src/Gui/DocumentPyImp.cpp +++ b/src/Gui/DocumentPyImp.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include "Application.h" #include "MergeDocuments.h" diff --git a/src/Gui/DownloadManager.cpp b/src/Gui/DownloadManager.cpp index f31b4e53d5..06658d1318 100644 --- a/src/Gui/DownloadManager.cpp +++ b/src/Gui/DownloadManager.cpp @@ -21,7 +21,8 @@ ***************************************************************************/ #include "PreCompiled.h" -#include +#include +#include #include #include diff --git a/src/Gui/GuiConsole.cpp b/src/Gui/GuiConsole.cpp index 5a98a8739c..0e101873aa 100644 --- a/src/Gui/GuiConsole.cpp +++ b/src/Gui/GuiConsole.cpp @@ -28,7 +28,8 @@ # include "io.h" # include # endif -# include "fcntl.h" +# include +# include #endif #include "GuiConsole.h" diff --git a/src/Main/MainGui.cpp b/src/Main/MainGui.cpp index 0adb53818c..854f73e794 100644 --- a/src/Main/MainGui.cpp +++ b/src/Main/MainGui.cpp @@ -46,7 +46,7 @@ // FreeCAD header #include -#include +#include #include #include #include diff --git a/src/Main/MainPy.cpp b/src/Main/MainPy.cpp index 941451789b..112c6b8523 100644 --- a/src/Main/MainPy.cpp +++ b/src/Main/MainPy.cpp @@ -46,6 +46,7 @@ // FreeCAD Base header +#include #include #include #include diff --git a/src/Mod/Drawing/App/FeaturePage.cpp b/src/Mod/Drawing/App/FeaturePage.cpp index 70ad678eac..9cf642341c 100644 --- a/src/Mod/Drawing/App/FeaturePage.cpp +++ b/src/Mod/Drawing/App/FeaturePage.cpp @@ -24,6 +24,8 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include +# include # include #endif @@ -33,7 +35,6 @@ #include #include #include -#include #include #include "FeaturePage.h" diff --git a/src/Mod/Fem/App/PropertyPostDataObject.cpp b/src/Mod/Fem/App/PropertyPostDataObject.cpp index cccf9febd9..7d5f009af0 100644 --- a/src/Mod/Fem/App/PropertyPostDataObject.cpp +++ b/src/Mod/Fem/App/PropertyPostDataObject.cpp @@ -43,8 +43,9 @@ #include #include -#include #include +#include +#include #include #include #include diff --git a/src/Mod/Inspection/App/InspectionFeature.cpp b/src/Mod/Inspection/App/InspectionFeature.cpp index 3a3dde9c28..0cad76d5dc 100644 --- a/src/Mod/Inspection/App/InspectionFeature.cpp +++ b/src/Mod/Inspection/App/InspectionFeature.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Mod/Mesh/App/Mesh.cpp b/src/Mod/Mesh/App/Mesh.cpp index 463d6f19ba..4aeafa3f1d 100644 --- a/src/Mod/Mesh/App/Mesh.cpp +++ b/src/Mod/Mesh/App/Mesh.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include diff --git a/src/Mod/Mesh/App/MeshPyImp.cpp b/src/Mod/Mesh/App/MeshPyImp.cpp index 94e92619f9..90c5d789f9 100644 --- a/src/Mod/Mesh/App/MeshPyImp.cpp +++ b/src/Mod/Mesh/App/MeshPyImp.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "Mesh.h" diff --git a/src/Mod/Mesh/Gui/RemeshGmsh.cpp b/src/Mod/Mesh/Gui/RemeshGmsh.cpp index 63ee727f4c..f1eded902c 100644 --- a/src/Mod/Mesh/Gui/RemeshGmsh.cpp +++ b/src/Mod/Mesh/Gui/RemeshGmsh.cpp @@ -34,6 +34,7 @@ #include "ui_RemeshGmsh.h" #include #include +#include #include #include #include diff --git a/src/Mod/Mesh/Gui/ViewProvider.cpp b/src/Mod/Mesh/Gui/ViewProvider.cpp index 63b6bfa7a5..cc90768278 100644 --- a/src/Mod/Mesh/Gui/ViewProvider.cpp +++ b/src/Mod/Mesh/Gui/ViewProvider.cpp @@ -63,6 +63,7 @@ #include #include #include +#include #include #include diff --git a/src/Mod/MeshPart/Gui/Tessellation.cpp b/src/Mod/MeshPart/Gui/Tessellation.cpp index 1955ab88c8..f84d528412 100644 --- a/src/Mod/MeshPart/Gui/Tessellation.cpp +++ b/src/Mod/MeshPart/Gui/Tessellation.cpp @@ -31,6 +31,7 @@ #include "ui_Tessellation.h" #include #include +#include #include #include #include diff --git a/src/Mod/Part/App/TopoShapePyImp.cpp b/src/Mod/Part/App/TopoShapePyImp.cpp index 001a7e5848..46d45dd189 100644 --- a/src/Mod/Part/App/TopoShapePyImp.cpp +++ b/src/Mod/Part/App/TopoShapePyImp.cpp @@ -74,6 +74,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Mod/Raytracing/App/PovTools.cpp b/src/Mod/Raytracing/App/PovTools.cpp index 049308c8b9..97b1722456 100644 --- a/src/Mod/Raytracing/App/PovTools.cpp +++ b/src/Mod/Raytracing/App/PovTools.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include diff --git a/src/Mod/Spreadsheet/Gui/SheetTableView.cpp b/src/Mod/Spreadsheet/Gui/SheetTableView.cpp index f0089132df..7909973096 100644 --- a/src/Mod/Spreadsheet/Gui/SheetTableView.cpp +++ b/src/Mod/Spreadsheet/Gui/SheetTableView.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Mod/TechDraw/App/LineGroup.cpp b/src/Mod/TechDraw/App/LineGroup.cpp index 3b2dc9bc85..54a37f2278 100644 --- a/src/Mod/TechDraw/App/LineGroup.cpp +++ b/src/Mod/TechDraw/App/LineGroup.cpp @@ -23,6 +23,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ +#include #include #include #include diff --git a/src/Mod/TechDraw/App/PreCompiled.h b/src/Mod/TechDraw/App/PreCompiled.h index d9659fa58d..873194ebd0 100644 --- a/src/Mod/TechDraw/App/PreCompiled.h +++ b/src/Mod/TechDraw/App/PreCompiled.h @@ -48,6 +48,7 @@ #ifdef _PreComp_ // standard +#include #include #include #include