Base: move ILogger sub-classes to their own source files in order to reduce including stream classes in client code
This commit is contained in:
277
src/Base/ConsoleObserver.cpp
Normal file
277
src/Base/ConsoleObserver.cpp
Normal file
@@ -0,0 +1,277 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de> *
|
||||
* *
|
||||
* 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 <cstring>
|
||||
# include <Python.h>
|
||||
# include <frameobject.h>
|
||||
#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<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(static_cast<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(static_cast<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(static_cast<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<FC_DURATION>(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)<<"("<<line<<"): ";
|
||||
}
|
||||
return str;
|
||||
}
|
||||
Reference in New Issue
Block a user