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
101const wxString& WX_STRING_REPORTER::GetMessages() const
102{
103 return m_string;
104}
105
106
108{
110 m_string.clear();
111}
112
113
114REPORTER& NULL_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
115{
116 return REPORTER::Report( aText, aSeverity );
117}
118
119
121{
122 static REPORTER* s_nullReporter = nullptr;
123
124 if( !s_nullReporter )
125 s_nullReporter = new NULL_REPORTER();
126
127 return *s_nullReporter;
128}
129
130
131REPORTER& CLI_REPORTER::Report( const wxString& aMsg, SEVERITY aSeverity )
132{
133 REPORTER::Report( aMsg, aSeverity );
134
135 // Skip debug messages unless verbose mode is enabled
136 if( aSeverity == RPT_SEVERITY_DEBUG && !m_verbose )
137 return *this;
138
139 FILE* target = stdout;
140
141 if( aSeverity == RPT_SEVERITY_ERROR )
142 target = stderr;
143
144 if( aMsg.EndsWith( wxS( "\n" ) ) )
145 wxFprintf( target, aMsg );
146 else
147 wxFprintf( target, aMsg + wxS( "\n" ) );
148
149 // Needed after wxPrintf (or printf) to be sure the message is immediately printed
150 // (i.e. not stored in some i/o buffer)
151 fflush( target );
152
153 return *this;
154}
155
156
158{
159 static CLI_REPORTER s_cliReporter;
160
161 return s_cliReporter;
162}
163
164
165REPORTER& STDOUT_REPORTER::Report( const wxString& aMsg, SEVERITY aSeverity )
166{
167 REPORTER::Report( aMsg, aSeverity );
168
169 switch( aSeverity )
170 {
171 case RPT_SEVERITY_UNDEFINED: std::cout << "SEVERITY_UNDEFINED: "; break;
172 case RPT_SEVERITY_INFO: std::cout << "SEVERITY_INFO: "; break;
173 case RPT_SEVERITY_WARNING: std::cout << "SEVERITY_WARNING: "; break;
174 case RPT_SEVERITY_ERROR: std::cout << "SEVERITY_ERROR: "; break;
175 case RPT_SEVERITY_ACTION: std::cout << "SEVERITY_ACTION: "; break;
176 case RPT_SEVERITY_DEBUG: std::cout << "SEVERITY_DEBUG: "; break;
178 case RPT_SEVERITY_IGNORE: break;
179 }
180
181 std::cout << aMsg << std::endl;
182
183 return *this;
184}
185
186
188{
189 static REPORTER* s_stdoutReporter = nullptr;
190
191 if( !s_stdoutReporter )
192 s_stdoutReporter = new STDOUT_REPORTER();
193
194 return *s_stdoutReporter;
195}
196
197
198REPORTER& WXLOG_REPORTER::Report( const wxString& aMsg, SEVERITY aSeverity )
199{
200 REPORTER::Report( aMsg, aSeverity );
201
202 // aMsg is finished content; pass it as a "%s" argument so a stray '%' in
203 // reported data is not read as a format specifier (bogus varargs -> assert).
204 switch( aSeverity )
205 {
206 case RPT_SEVERITY_ERROR: wxLogError( wxS( "%s" ), aMsg ); break;
207 case RPT_SEVERITY_WARNING: wxLogWarning( wxS( "%s" ), aMsg ); break;
208 case RPT_SEVERITY_UNDEFINED: wxLogMessage( wxS( "%s" ), aMsg ); break;
209 case RPT_SEVERITY_INFO: wxLogInfo( wxS( "%s" ), aMsg ); break;
210 case RPT_SEVERITY_ACTION: wxLogInfo( wxS( "%s" ), aMsg ); break;
211 case RPT_SEVERITY_DEBUG: wxLogTrace( traceReporter, wxS( "%s" ), aMsg ); break;
212 case RPT_SEVERITY_EXCLUSION: break;
213 case RPT_SEVERITY_IGNORE: break;
214 }
215
216 return *this;
217}
218
219
221{
222 static REPORTER* s_wxLogReporter = nullptr;
223 std::lock_guard lock( g_logReporterMutex );
224
225 if( !s_wxLogReporter )
226 s_wxLogReporter = new WXLOG_REPORTER();
227
228 return *s_wxLogReporter;
229}
230
231
232REPORTER& LOAD_INFO_REPORTER::Report( const wxString& aMsg, SEVERITY aSeverity )
233{
234 REPORTER::Report( aMsg, aSeverity );
235
236 REPORTER* target = m_redirectTarget;
237
238 if( !target )
239 target = &WXLOG_REPORTER::GetInstance();
240
241 target->Report( aMsg, aSeverity );
242
243 return *this;
244}
245
246
248{
249 static LOAD_INFO_REPORTER s_loadInfoReporter;
250 std::lock_guard lock( g_logReporterMutex );
251
252 return s_loadInfoReporter;
253}
254
255
257{
258 std::lock_guard lock( g_logReporterMutex );
259 m_redirectTarget = aReporter;
260}
261
262
264{
265 std::lock_guard lock( g_logReporterMutex );
266 return m_redirectTarget;
267}
268
269
271 m_reporter( LOAD_INFO_REPORTER::GetInstance() ),
272 m_previousReporter( m_reporter.GetRedirectTarget() )
273{
274 m_reporter.SetRedirectTarget( aReporter );
275}
276
277
282
283
289
290
295
296
297REPORTER& REDIRECT_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
298{
299 REPORTER::Report( aText, aSeverity );
300
301 if( m_redirectTarget )
302 m_redirectTarget->Report( aText, aSeverity );
303
304 return *this;
305}
306
307
308REPORTER& STATUSBAR_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
309{
310 REPORTER::Report( aText, aSeverity );
311
312 // KiCad status bars give most fields a fixed width, so ellipsize to fit rather than let a
313 // long message (e.g. an archive entry path) be clipped mid-character.
314 if( KISTATUSBAR* kiStatusBar = dynamic_cast<KISTATUSBAR*>( m_statusBar ) )
315 kiStatusBar->SetEllipsedTextField( aText, m_position );
316 else if( m_statusBar )
317 m_statusBar->SetStatusText( aText, m_position );
318
319 return *this;
320}
321
322
324 const wxString& aSource ) :
325 m_impl( std::make_shared<STATUSBAR_WARNING_REPORTER_IMPL>( aStatusBar, aSource ) )
326{
327}
328
329
331
332
333REPORTER& STATUSBAR_WARNING_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
334{
335 REPORTER::Report( aText, aSeverity );
336
337 KISTATUSBAR* statusBar = m_impl ? m_impl->GetStatusBar() : nullptr;
338
339 if( !statusBar || aText.IsEmpty() )
340 return *this;
341
342 std::vector<LOAD_MESSAGE> messages;
343 wxStringTokenizer tokenizer( aText, wxS( "\n" ), wxTOKEN_STRTOK );
344 SEVERITY severity = aSeverity == RPT_SEVERITY_UNDEFINED ? RPT_SEVERITY_WARNING : aSeverity;
345
346 while( tokenizer.HasMoreTokens() )
347 {
348 LOAD_MESSAGE message;
349 message.message = tokenizer.GetNextToken();
350 message.severity = severity;
351 messages.emplace_back( std::move( message ) );
352 }
353
354 if( messages.empty() )
355 {
356 LOAD_MESSAGE message;
357 message.message = aText;
358 message.severity = severity;
359 messages.emplace_back( std::move( message ) );
360 }
361
362 statusBar->AddWarningMessages( m_impl->m_source, messages );
363 return *this;
364}
REPORTER & Report(const wxString &aMsg, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:131
static CLI_REPORTER & GetInstance()
Definition reporter.cpp:157
bool m_verbose
Definition reporter.h:255
FONTCONFIG_REPORTER_SCOPE(REPORTER *aReporter)
Definition reporter.cpp:284
REPORTER * m_previousReporter
Definition reporter.h:338
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:270
LOAD_INFO_REPORTER & m_reporter
Definition reporter.h:320
REPORTER * m_previousReporter
Definition reporter.h:321
REPORTER * GetRedirectTarget() const
Definition reporter.cpp:263
REPORTER * m_redirectTarget
Definition reporter.h:309
static LOAD_INFO_REPORTER & GetInstance()
Definition reporter.cpp:247
void SetRedirectTarget(REPORTER *aReporter)
Definition reporter.cpp:256
REPORTER & Report(const wxString &aMsg, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:232
static REPORTER & GetInstance()
Definition reporter.cpp:120
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:114
REPORTER * m_redirectTarget
Definition reporter.h:349
REPORTER & Report(const wxString &aMsg, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:297
A pure virtual class used to derive REPORTER objects from.
Definition reporter.h:71
virtual void Clear()
Definition reporter.h:151
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Definition reporter.h:100
REPORTER()
Definition reporter.h:73
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:308
wxStatusBar * m_statusBar
Definition reporter.h:368
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:323
~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:333
std::shared_ptr< STATUSBAR_WARNING_REPORTER_IMPL > m_impl
Definition reporter.h:382
REPORTER & Report(const wxString &aMsg, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:165
static REPORTER & GetInstance()
Definition reporter.cpp:187
REPORTER & Report(const wxString &aMsg, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
Definition reporter.cpp:198
static REPORTER & GetInstance()
Definition reporter.cpp:220
wxString m_string
Definition reporter.h:204
void Clear() override
Definition reporter.cpp:107
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:101
wxTextCtrl * m_textCtrl
Definition reporter.h:181
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.
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