KiCad PCB EDA Suite
Loading...
Searching...
No Matches
reporter.cpp
Go to the documentation of this file.
1
4/*
5 * This program source code file is part of KiCad, a free EDA CAD application.
6 *
7 * Copyright (C) 2013 Wayne Stambaugh <[email protected]>
8 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 */
23
24#include <mutex>
25#include <macros.h>
26#include <reporter.h>
27#include <font/fontconfig.h>
28#include <string_utils.h>
29#include <widgets/kistatusbar.h>
30#include <widgets/wx_infobar.h>
31#include <wx/crt.h>
32#include <wx/log.h>
33#include <wx/textctrl.h>
34#include <wx/statusbr.h>
35#include <wx/tokenzr.h>
36#include <wx/weakref.h>
37
38
44static const wxChar traceReporter[] = wxT( "KICAD_REPORTER" );
45
46static std::mutex g_logReporterMutex;
47
48
50{
51public:
52 STATUSBAR_WARNING_REPORTER_IMPL( KISTATUSBAR* aStatusBar, const wxString& aSource ) :
53 m_statusBar( aStatusBar ),
54 m_source( aSource )
55 {
56 }
57
59 {
60 KISTATUSBAR* statusBar = m_statusBar.get();
61
62 if( statusBar && !statusBar->IsBeingDeleted() )
63 return statusBar;
64
65 return nullptr;
66 }
67
68 wxWeakRef<KISTATUSBAR> m_statusBar;
69 wxString m_source;
70};
71
72
73REPORTER& REPORTER::Report( const char* aText, SEVERITY aSeverity )
74{
75 Report( From_UTF8( aText ) );
76 return *this;
77}
78
79
80REPORTER& WX_TEXT_CTRL_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
81{
82 REPORTER::Report( aText, aSeverity );
83
84 wxCHECK_MSG( m_textCtrl != nullptr, *this,
85 wxT( "No wxTextCtrl object defined in WX_TEXT_CTRL_REPORTER." ) );
86
87 m_textCtrl->AppendText( aText + wxS( "\n" ) );
88 return *this;
89}
90
91
92REPORTER& WX_STRING_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
93{
94 REPORTER::Report( aText, aSeverity );
95
96 m_string << aText << wxS( "\n" );
97 return *this;
98}
99
100
101REPORTER& SYNC_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
102{
103 std::lock_guard lock( m_mutex );
104
105 m_reporter.Report( aText, aSeverity );
106 return *this;
107}
108
109
110REPORTER& SYNC_REPORTER::ReportTail( const wxString& aText, SEVERITY aSeverity )
111{
112 std::lock_guard lock( m_mutex );
113
114 m_reporter.ReportTail( aText, aSeverity );
115 return *this;
116}
117
118
119REPORTER& SYNC_REPORTER::ReportHead( const wxString& aText, SEVERITY aSeverity )
120{
121 std::lock_guard lock( m_mutex );
122
123 m_reporter.ReportHead( aText, aSeverity );
124 return *this;
125}
126
127
129{
130 std::lock_guard lock( m_mutex );
131
132 m_reporter.Clear();
133}
134
135
137{
138 std::lock_guard lock( m_mutex );
139
140 return m_reporter.HasMessage();
141}
142
143
144bool SYNC_REPORTER::HasMessageOfSeverity( int aSeverityMask ) const
145{
146 std::lock_guard lock( m_mutex );
147
148 return m_reporter.HasMessageOfSeverity( aSeverityMask );
149}
150
151
153{
154 std::lock_guard lock( m_mutex );
155
156 return m_reporter.GetUnits();
157}
158
159
160const wxString& WX_STRING_REPORTER::GetMessages() const
161{
162 return m_string;
163}
164
165
167{
169 m_string.clear();
170}
171
172
173REPORTER& NULL_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
174{
175 return REPORTER::Report( aText, aSeverity );
176}
177
178
180{
181 static REPORTER* s_nullReporter = nullptr;
182
183 if( !s_nullReporter )
184 s_nullReporter = new NULL_REPORTER();
185
186 return *s_nullReporter;
187}
188
189
190REPORTER& CLI_REPORTER::Report( const wxString& aMsg, SEVERITY aSeverity )
191{
192 REPORTER::Report( aMsg, aSeverity );
193
194 // Skip debug messages unless verbose mode is enabled
195 if( aSeverity == RPT_SEVERITY_DEBUG && !m_verbose )
196 return *this;
197
198 FILE* target = stdout;
199
200 if( aSeverity == RPT_SEVERITY_ERROR )
201 target = stderr;
202
203 if( aMsg.EndsWith( wxS( "\n" ) ) )
204 wxFprintf( target, aMsg );
205 else
206 wxFprintf( target, aMsg + wxS( "\n" ) );
207
208 // Needed after wxPrintf (or printf) to be sure the message is immediately printed
209 // (i.e. not stored in some i/o buffer)
210 fflush( target );
211
212 return *this;
213}
214
215
217{
218 static CLI_REPORTER s_cliReporter;
219
220 return s_cliReporter;
221}
222
223
224REPORTER& STDOUT_REPORTER::Report( const wxString& aMsg, SEVERITY aSeverity )
225{
226 REPORTER::Report( aMsg, aSeverity );
227
228 switch( aSeverity )
229 {
230 case RPT_SEVERITY_UNDEFINED: std::cout << "SEVERITY_UNDEFINED: "; break;
231 case RPT_SEVERITY_INFO: std::cout << "SEVERITY_INFO: "; break;
232 case RPT_SEVERITY_WARNING: std::cout << "SEVERITY_WARNING: "; break;
233 case RPT_SEVERITY_ERROR: std::cout << "SEVERITY_ERROR: "; break;
234 case RPT_SEVERITY_ACTION: std::cout << "SEVERITY_ACTION: "; break;
235 case RPT_SEVERITY_DEBUG: std::cout << "SEVERITY_DEBUG: "; break;
237 case RPT_SEVERITY_IGNORE: break;
238 }
239
240 std::cout << aMsg << std::endl;
241
242 return *this;
243}
244
245
247{
248 static REPORTER* s_stdoutReporter = nullptr;
249
250 if( !s_stdoutReporter )
251 s_stdoutReporter = new STDOUT_REPORTER();
252
253 return *s_stdoutReporter;
254}
255
256
257REPORTER& WXLOG_REPORTER::Report( const wxString& aMsg, SEVERITY aSeverity )
258{
259 REPORTER::Report( aMsg, aSeverity );
260
261 // aMsg is finished content; pass it as a "%s" argument so a stray '%' in
262 // reported data is not read as a format specifier (bogus varargs -> assert).
263 switch( aSeverity )
264 {
265 case RPT_SEVERITY_ERROR: wxLogError( wxS( "%s" ), aMsg ); break;
266 case RPT_SEVERITY_WARNING: wxLogWarning( wxS( "%s" ), aMsg ); break;
267 case RPT_SEVERITY_UNDEFINED: wxLogMessage( wxS( "%s" ), aMsg ); break;
268 case RPT_SEVERITY_INFO: wxLogInfo( wxS( "%s" ), aMsg ); break;
269 case RPT_SEVERITY_ACTION: wxLogInfo( wxS( "%s" ), aMsg ); break;
270 case RPT_SEVERITY_DEBUG: wxLogTrace( traceReporter, wxS( "%s" ), aMsg ); break;
271 case RPT_SEVERITY_EXCLUSION: break;
272 case RPT_SEVERITY_IGNORE: break;
273 }
274
275 return *this;
276}
277
278
280{
281 static REPORTER* s_wxLogReporter = nullptr;
282 std::lock_guard lock( g_logReporterMutex );
283
284 if( !s_wxLogReporter )
285 s_wxLogReporter = new WXLOG_REPORTER();
286
287 return *s_wxLogReporter;
288}
289
290
291REPORTER& LOAD_INFO_REPORTER::Report( const wxString& aMsg, SEVERITY aSeverity )
292{
293 REPORTER::Report( aMsg, aSeverity );
294
295 REPORTER* target = m_redirectTarget;
296
297 if( !target )
298 target = &WXLOG_REPORTER::GetInstance();
299
300 target->Report( aMsg, aSeverity );
301
302 return *this;
303}
304
305
307{
308 static LOAD_INFO_REPORTER s_loadInfoReporter;
309 std::lock_guard lock( g_logReporterMutex );
310
311 return s_loadInfoReporter;
312}
313
314
316{
317 std::lock_guard lock( g_logReporterMutex );
318 m_redirectTarget = aReporter;
319}
320
321
323{
324 std::lock_guard lock( g_logReporterMutex );
325 return m_redirectTarget;
326}
327
328
330 m_reporter( LOAD_INFO_REPORTER::GetInstance() ),
331 m_previousReporter( m_reporter.GetRedirectTarget() )
332{
333 m_reporter.SetRedirectTarget( aReporter );
334}
335
336
341
342
348
349
354
355
356REPORTER& REDIRECT_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
357{
358 REPORTER::Report( aText, aSeverity );
359
360 if( m_redirectTarget )
361 m_redirectTarget->Report( aText, aSeverity );
362
363 return *this;
364}
365
366
367REPORTER& STATUSBAR_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
368{
369 REPORTER::Report( aText, aSeverity );
370
371 // KiCad status bars give most fields a fixed width, so ellipsize to fit rather than let a
372 // long message (e.g. an archive entry path) be clipped mid-character.
373 if( KISTATUSBAR* kiStatusBar = dynamic_cast<KISTATUSBAR*>( m_statusBar ) )
374 kiStatusBar->SetEllipsedTextField( aText, m_position );
375 else if( m_statusBar )
376 m_statusBar->SetStatusText( aText, m_position );
377
378 return *this;
379}
380
381
383 const wxString& aSource ) :
384 m_impl( std::make_shared<STATUSBAR_WARNING_REPORTER_IMPL>( aStatusBar, aSource ) )
385{
386}
387
388
390
391
392REPORTER& STATUSBAR_WARNING_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
393{
394 REPORTER::Report( aText, aSeverity );
395
396 KISTATUSBAR* statusBar = m_impl ? m_impl->GetStatusBar() : nullptr;
397
398 if( !statusBar || aText.IsEmpty() )
399 return *this;
400
401 std::vector<LOAD_MESSAGE> messages;
402 wxStringTokenizer tokenizer( aText, wxS( "\n" ), wxTOKEN_STRTOK );
403 SEVERITY severity = aSeverity == RPT_SEVERITY_UNDEFINED ? RPT_SEVERITY_WARNING : aSeverity;
404
405 while( tokenizer.HasMoreTokens() )
406 {
407 LOAD_MESSAGE message;
408 message.message = tokenizer.GetNextToken();
409 message.severity = severity;
410 messages.emplace_back( std::move( message ) );
411 }
412
413 if( messages.empty() )
414 {
415 LOAD_MESSAGE message;
416 message.message = aText;
417 message.severity = severity;
418 messages.emplace_back( std::move( message ) );
419 }
420
421 statusBar->AddWarningMessages( m_impl->m_source, messages );
422 return *this;
423}
REPORTER & Report(const wxString &aMsg, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:190
static CLI_REPORTER & GetInstance()
Definition reporter.cpp:216
bool m_verbose
Definition reporter.h:291
FONTCONFIG_REPORTER_SCOPE(REPORTER *aReporter)
Definition reporter.cpp:343
REPORTER * m_previousReporter
Definition reporter.h:374
void AddWarningMessages(const wxString &aSource, const wxString &aMessages)
Add warning/error messages (not thread-safe, use the std::vector<LOAD_MESSAGE> variant from other thr...
LOAD_INFO_REPORTER_SCOPE(REPORTER *aReporter)
Definition reporter.cpp:329
LOAD_INFO_REPORTER & m_reporter
Definition reporter.h:356
REPORTER * m_previousReporter
Definition reporter.h:357
REPORTER * GetRedirectTarget() const
Definition reporter.cpp:322
REPORTER * m_redirectTarget
Definition reporter.h:345
static LOAD_INFO_REPORTER & GetInstance()
Definition reporter.cpp:306
void SetRedirectTarget(REPORTER *aReporter)
Definition reporter.cpp:315
REPORTER & Report(const wxString &aMsg, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:291
static REPORTER & GetInstance()
Definition reporter.cpp:179
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:173
REPORTER * m_redirectTarget
Definition reporter.h:385
REPORTER & Report(const wxString &aMsg, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:356
A pure virtual class used to derive REPORTER objects from.
Definition reporter.h:72
virtual void Clear()
Definition reporter.h:152
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Definition reporter.h:101
REPORTER()
Definition reporter.h:74
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:367
wxStatusBar * m_statusBar
Definition reporter.h:404
wxWeakRef< KISTATUSBAR > m_statusBar
Definition reporter.cpp:68
KISTATUSBAR * GetStatusBar() const
Definition reporter.cpp:58
STATUSBAR_WARNING_REPORTER_IMPL(KISTATUSBAR *aStatusBar, const wxString &aSource)
Definition reporter.cpp:52
STATUSBAR_WARNING_REPORTER(KISTATUSBAR *aStatusBar, const wxString &aSource)
Definition reporter.cpp:382
~STATUSBAR_WARNING_REPORTER() override
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:392
std::shared_ptr< STATUSBAR_WARNING_REPORTER_IMPL > m_impl
Definition reporter.h:418
REPORTER & Report(const wxString &aMsg, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:224
static REPORTER & GetInstance()
Definition reporter.cpp:246
bool HasMessage() const override
Returns true if any messages were reported.
Definition reporter.cpp:136
REPORTER & ReportHead(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Places the report at the beginning of the list for objects that support ordering.
Definition reporter.cpp:119
EDA_UNITS GetUnits() const override
Definition reporter.cpp:152
bool HasMessageOfSeverity(int aSeverityMask) const override
Returns true if the reporter has one or more messages matching the specified severity mask.
Definition reporter.cpp:144
REPORTER & ReportTail(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Places the report at the end of the list, for objects that support report ordering.
Definition reporter.cpp:110
void Clear() override
Definition reporter.cpp:128
std::mutex m_mutex
Definition reporter.h:193
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:101
REPORTER & m_reporter
Definition reporter.h:192
REPORTER & Report(const wxString &aMsg, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:257
static REPORTER & GetInstance()
Definition reporter.cpp:279
wxString m_string
Definition reporter.h:240
void Clear() override
Definition reporter.cpp:166
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:92
const wxString & GetMessages() const
Definition reporter.cpp:160
wxTextCtrl * m_textCtrl
Definition reporter.h:217
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:80
static void SetReporter(REPORTER *aReporter)
Set the reporter to use for reporting font substitution warnings.
EDA_UNITS
Definition eda_units.h:44
static const wxChar traceReporter[]
Flag to enable reporter debugging output.
Definition reporter.cpp:44
This file contains miscellaneous commonly used macros and functions.
STL namespace.
SEVERITY
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_UNDEFINED
@ RPT_SEVERITY_EXCLUSION
@ RPT_SEVERITY_IGNORE
@ RPT_SEVERITY_DEBUG
@ RPT_SEVERITY_INFO
@ RPT_SEVERITY_ACTION
static std::mutex g_logReporterMutex
Definition reporter.cpp:46
wxString From_UTF8(const char *cstring)
KISTATUSBAR is a wxStatusBar suitable for Kicad manager.
Definition kistatusbar.h:50
wxString message
Definition kistatusbar.h:51
SEVERITY severity
Definition kistatusbar.h:52