FreeCAD

Форк
0
/
ConsoleObserver.cpp 
355 строк · 10.6 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de>              *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This program is free software; you can redistribute it and/or modify  *
7
 *   it under the terms of the GNU Library General Public License (LGPL)   *
8
 *   as published by the Free Software Foundation; either version 2 of     *
9
 *   the License, or (at your option) any later version.                   *
10
 *   for detail see the LICENCE text file.                                 *
11
 *                                                                         *
12
 *   FreeCAD is distributed in the hope that it will be useful,            *
13
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
14
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
15
 *   GNU Library General Public License for more details.                  *
16
 *                                                                         *
17
 *   You should have received a copy of the GNU Library General Public     *
18
 *   License along with FreeCAD; if not, write to the Free Software        *
19
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
20
 *   USA                                                                   *
21
 *                                                                         *
22
 ***************************************************************************/
23

24
#include "PreCompiled.h"
25

26
#ifndef _PreComp_
27
#ifdef FC_OS_WIN32
28
#include <windows.h>
29
#endif
30
#include <cstring>
31
#include <Python.h>
32
#endif
33

34
#include <frameobject.h>
35

36
#include "ConsoleObserver.h"
37
#include "Interpreter.h"
38

39

40
using namespace Base;
41

42

43
//=========================================================================
44
// some special observers
45

46
ConsoleObserverFile::ConsoleObserverFile(const char* sFileName)
47
    : cFileStream(Base::FileInfo(sFileName))  // can be in UTF8
48
{
49
    if (!cFileStream.is_open()) {
50
        Console().Warning("Cannot open log file '%s'.\n", sFileName);
51
    }
52
    // mark the file as a UTF-8 encoded file
53
    unsigned char bom[3] = {0xef, 0xbb, 0xbf};
54
    cFileStream.write(reinterpret_cast<const char*>(bom), 3 * sizeof(char));
55
}
56

57
ConsoleObserverFile::~ConsoleObserverFile()
58
{
59
    cFileStream.close();
60
}
61

62
void ConsoleObserverFile::SendLog(const std::string& notifiername,
63
                                  const std::string& msg,
64
                                  LogStyle level,
65
                                  IntendedRecipient recipient,
66
                                  ContentType content)
67
{
68
    (void)notifiername;
69

70
    // Do not log translated messages, or messages intended only to the user to log file
71
    if (recipient == IntendedRecipient::User || content == ContentType::Translated) {
72
        return;
73
    }
74

75
    std::string prefix;
76
    switch (level) {
77
        case LogStyle::Warning:
78
            prefix = "Wrn: ";
79
            break;
80
        case LogStyle::Message:
81
            prefix = "Msg: ";
82
            break;
83
        case LogStyle::Error:
84
            prefix = "Err: ";
85
            break;
86
        case LogStyle::Log:
87
            prefix = "Log: ";
88
            break;
89
        case LogStyle::Critical:
90
            prefix = "Critical: ";
91
            break;
92
        default:
93
            break;
94
    }
95

96
    cFileStream << prefix << msg;
97
    cFileStream.flush();
98
}
99

100
ConsoleObserverStd::ConsoleObserverStd()
101
    :
102
#if defined(FC_OS_WIN32)
103
    useColorStderr(true)
104
#elif defined(FC_OS_LINUX) || defined(FC_OS_MACOSX) || defined(FC_OS_BSD)
105
    useColorStderr(isatty(STDERR_FILENO))
106
#else
107
    useColorStderr(false)
108
#endif
109
{
110
    bLog = false;
111
}
112

113
ConsoleObserverStd::~ConsoleObserverStd() = default;
114

115
void ConsoleObserverStd::SendLog(const std::string& notifiername,
116
                                 const std::string& msg,
117
                                 LogStyle level,
118
                                 IntendedRecipient recipient,
119
                                 ContentType content)
120
{
121
    (void)notifiername;
122

123
    // Do not log translated messages, or messages intended only to the user to std log
124
    if (recipient == IntendedRecipient::User || content == ContentType::Translated) {
125
        return;
126
    }
127

128
    switch (level) {
129
        case LogStyle::Warning:
130
            this->Warning(msg.c_str());
131
            break;
132
        case LogStyle::Message:
133
            this->Message(msg.c_str());
134
            break;
135
        case LogStyle::Error:
136
            this->Error(msg.c_str());
137
            break;
138
        case LogStyle::Log:
139
            this->Log(msg.c_str());
140
            break;
141
        case LogStyle::Critical:
142
            this->Critical(msg.c_str());
143
            break;
144
        default:
145
            break;
146
    }
147
}
148

149
void ConsoleObserverStd::Message(const char* sMsg)
150
{
151
    printf("%s", sMsg);
152
}
153

154
void ConsoleObserverStd::Warning(const char* sWarn)
155
{
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");
162
#endif
163
    }
164

165
    fprintf(stderr, "%s", sWarn);
166

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");
173
#endif
174
    }
175
}
176

177
void ConsoleObserverStd::Error(const char* sErr)
178
{
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");
185
#endif
186
    }
187

188
    fprintf(stderr, "%s", sErr);
189

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");
196
#endif
197
    }
198
}
199

200
void ConsoleObserverStd::Log(const char* sLog)
201
{
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");
208
#endif
209
    }
210

211
    fprintf(stderr, "%s", sLog);
212

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");
219
#endif
220
    }
221
}
222

223
void ConsoleObserverStd::Critical(const char* sCritical)
224
{
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");
231
#endif
232
    }
233

234
    fprintf(stderr, "%s", sCritical);
235

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");
242
#endif
243
    }
244
}
245

246
RedirectStdOutput::RedirectStdOutput()
247
{
248
    buffer.reserve(80);
249
}
250

251
int RedirectStdOutput::overflow(int ch)
252
{
253
    if (ch != EOF) {
254
        buffer.push_back(static_cast<char>(ch));
255
    }
256
    return ch;
257
}
258

259
int RedirectStdOutput::sync()
260
{
261
    // Print as log as this might be verbose
262
    if (!buffer.empty() && buffer.back() == '\n') {
263
        Base::Console().Log("%s", buffer.c_str());
264
        buffer.clear();
265
    }
266
    return 0;
267
}
268

269
RedirectStdLog::RedirectStdLog()
270
{
271
    buffer.reserve(80);
272
}
273

274
int RedirectStdLog::overflow(int ch)
275
{
276
    if (ch != EOF) {
277
        buffer.push_back(static_cast<char>(ch));
278
    }
279
    return ch;
280
}
281

282
int RedirectStdLog::sync()
283
{
284
    // Print as log as this might be verbose
285
    if (!buffer.empty() && buffer.back() == '\n') {
286
        Base::Console().Log("%s", buffer.c_str());
287
        buffer.clear();
288
    }
289
    return 0;
290
}
291

292
RedirectStdError::RedirectStdError()
293
{
294
    buffer.reserve(80);
295
}
296

297
int RedirectStdError::overflow(int ch)
298
{
299
    if (ch != EOF) {
300
        buffer.push_back(static_cast<char>(ch));
301
    }
302
    return ch;
303
}
304

305
int RedirectStdError::sync()
306
{
307
    if (!buffer.empty() && buffer.back() == '\n') {
308
        Base::Console().Error("%s", buffer.c_str());
309
        buffer.clear();
310
    }
311
    return 0;
312
}
313

314
//---------------------------------------------------------
315

316
std::stringstream& LogLevel::prefix(std::stringstream& str, const char* src, int line)
317
{
318
    static FC_TIME_POINT s_tstart;
319
    static bool s_timing = false;
320
    if (print_time) {
321
        if (!s_timing) {
322
            s_timing = true;
323
            _FC_TIME_INIT(s_tstart);
324
        }
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() << ' ';
328
    }
329
    if (print_tag) {
330
        str << '<' << tag << "> ";
331
    }
332
    if (print_src == 2) {
333
        Base::PyGILStateLocker lock;
334
        PyFrameObject* frame = PyEval_GetFrame();
335
        if (frame) {
336
            line = PyFrame_GetLineNumber(frame);
337
#if PY_VERSION_HEX < 0x030b0000
338
            src = PyUnicode_AsUTF8(frame->f_code->co_filename);
339
#else
340
            PyCodeObject* code = PyFrame_GetCode(frame);
341
            src = PyUnicode_AsUTF8(code->co_filename);
342
            Py_DECREF(code);
343
#endif
344
        }
345
    }
346
    if (print_src && src && src[0]) {
347
#ifdef FC_OS_WIN32
348
        const char* _f = std::strrchr(src, '\\');
349
#else
350
        const char* _f = std::strrchr(src, '/');
351
#endif
352
        str << (_f ? _f + 1 : src) << "(" << line << "): ";
353
    }
354
    return str;
355
}
356

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.