24
#include "PreCompiled.h"
34
#include <frameobject.h>
36
#include "ConsoleObserver.h"
37
#include "Interpreter.h"
46
ConsoleObserverFile::ConsoleObserverFile(const char* sFileName)
47
: cFileStream(Base::FileInfo(sFileName))
49
if (!cFileStream.is_open()) {
50
Console().Warning("Cannot open log file '%s'.\n", sFileName);
53
unsigned char bom[3] = {0xef, 0xbb, 0xbf};
54
cFileStream.write(reinterpret_cast<const char*>(bom), 3 * sizeof(char));
57
ConsoleObserverFile::~ConsoleObserverFile()
62
void ConsoleObserverFile::SendLog(const std::string& notifiername,
63
const std::string& msg,
65
IntendedRecipient recipient,
71
if (recipient == IntendedRecipient::User || content == ContentType::Translated) {
77
case LogStyle::Warning:
80
case LogStyle::Message:
89
case LogStyle::Critical:
90
prefix = "Critical: ";
96
cFileStream << prefix << msg;
100
ConsoleObserverStd::ConsoleObserverStd()
102
#if defined(FC_OS_WIN32)
104
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
105
useColorStderr(isatty(STDERR_FILENO))
107
useColorStderr(false)
113
ConsoleObserverStd::~ConsoleObserverStd() = default;
115
void ConsoleObserverStd::SendLog(const std::string& notifiername,
116
const std::string& msg,
118
IntendedRecipient recipient,
124
if (recipient == IntendedRecipient::User || content == ContentType::Translated) {
129
case LogStyle::Warning:
130
this->Warning(msg.c_str());
132
case LogStyle::Message:
133
this->Message(msg.c_str());
135
case LogStyle::Error:
136
this->Error(msg.c_str());
139
this->Log(msg.c_str());
141
case LogStyle::Critical:
142
this->Critical(msg.c_str());
149
void ConsoleObserverStd::Message(const char* sMsg)
154
void ConsoleObserverStd::Warning(const char* sWarn)
156
if (useColorStderr) {
157
#if defined(FC_OS_WIN32)
158
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),
159
FOREGROUND_GREEN | FOREGROUND_BLUE);
160
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
161
fprintf(stderr, "\033[1;33m");
165
fprintf(stderr, "%s", sWarn);
167
if (useColorStderr) {
168
#if defined(FC_OS_WIN32)
169
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),
170
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
171
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
172
fprintf(stderr, "\033[0m");
177
void ConsoleObserverStd::Error(const char* sErr)
179
if (useColorStderr) {
180
#if defined(FC_OS_WIN32)
181
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),
182
FOREGROUND_RED | FOREGROUND_INTENSITY);
183
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
184
fprintf(stderr, "\033[1;31m");
188
fprintf(stderr, "%s", sErr);
190
if (useColorStderr) {
191
#if defined(FC_OS_WIN32)
192
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),
193
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
194
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
195
fprintf(stderr, "\033[0m");
200
void ConsoleObserverStd::Log(const char* sLog)
202
if (useColorStderr) {
203
#if defined(FC_OS_WIN32)
204
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),
205
FOREGROUND_RED | FOREGROUND_GREEN);
206
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
207
fprintf(stderr, "\033[1;36m");
211
fprintf(stderr, "%s", sLog);
213
if (useColorStderr) {
214
#if defined(FC_OS_WIN32)
215
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),
216
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
217
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
218
fprintf(stderr, "\033[0m");
223
void ConsoleObserverStd::Critical(const char* sCritical)
225
if (useColorStderr) {
226
#if defined(FC_OS_WIN32)
227
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),
228
FOREGROUND_GREEN | FOREGROUND_BLUE);
229
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
230
fprintf(stderr, "\033[1;33m");
234
fprintf(stderr, "%s", sCritical);
236
if (useColorStderr) {
237
#if defined(FC_OS_WIN32)
238
::SetConsoleTextAttribute(::GetStdHandle(STD_ERROR_HANDLE),
239
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
240
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
241
fprintf(stderr, "\033[0m");
246
RedirectStdOutput::RedirectStdOutput()
251
int RedirectStdOutput::overflow(int ch)
254
buffer.push_back(static_cast<char>(ch));
259
int RedirectStdOutput::sync()
262
if (!buffer.empty() && buffer.back() == '\n') {
263
Base::Console().Log("%s", buffer.c_str());
269
RedirectStdLog::RedirectStdLog()
274
int RedirectStdLog::overflow(int ch)
277
buffer.push_back(static_cast<char>(ch));
282
int RedirectStdLog::sync()
285
if (!buffer.empty() && buffer.back() == '\n') {
286
Base::Console().Log("%s", buffer.c_str());
292
RedirectStdError::RedirectStdError()
297
int RedirectStdError::overflow(int ch)
300
buffer.push_back(static_cast<char>(ch));
305
int RedirectStdError::sync()
307
if (!buffer.empty() && buffer.back() == '\n') {
308
Base::Console().Error("%s", buffer.c_str());
316
std::stringstream& LogLevel::prefix(std::stringstream& str, const char* src, int line)
318
static FC_TIME_POINT s_tstart;
319
static bool s_timing = false;
323
_FC_TIME_INIT(s_tstart);
325
auto tnow = std::chrono::FC_TIME_CLOCK::now();
326
auto dc = std::chrono::duration_cast<FC_DURATION>(tnow - s_tstart);
327
str << dc.count() << ' ';
330
str << '<' << tag << "> ";
332
if (print_src == 2) {
333
Base::PyGILStateLocker lock;
334
PyFrameObject* frame = PyEval_GetFrame();
336
line = PyFrame_GetLineNumber(frame);
337
#if PY_VERSION_HEX < 0x030b0000
338
src = PyUnicode_AsUTF8(frame->f_code->co_filename);
340
PyCodeObject* code = PyFrame_GetCode(frame);
341
src = PyUnicode_AsUTF8(code->co_filename);
346
if (print_src && src && src[0]) {
348
const char* _f = std::strrchr(src, '\\');
350
const char* _f = std::strrchr(src, '/');
352
str << (_f ? _f + 1 : src) << "(" << line << "): ";