ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
report.cpp
1// #################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2024 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6// #################################################################################################
8
9#if !defined(ALIB_DOX)
10# if !defined(HPP_ALIB_CAMP_MESSAGE_REPORT)
12# endif
13
14# if ALIB_THREADS && !defined (HPP_ALIB_THREADS_SMARTLOCK)
16# endif
17
18# if !defined(HPP_ALIB_LANG_FORMAT_FORMATTER_PYTHONSTYLE)
20# endif
21
22# if !defined(HPP_ALIB_LANG_FORMAT_FORMATTER)
24# endif
25
26# if !defined (_GLIBCXX_IOSTREAM) && !defined (_IOSTREAM_ )
27# include <iostream>
28# endif
29
30# if defined( _WIN32 ) && !defined(HPP_ALIB_LANG_BASECAMP)
32# endif
33
34# if !defined (HPP_ALIB_LANG_CAMP_INLINES)
36# endif
37#endif // !defined(ALIB_DOX)
38
39
41
42
43namespace alib::lang {
44
45// #################################################################################################
46// static objects
47// #################################################################################################
48Report* Report::defaultReport = nullptr;
49
50// #################################################################################################
51// class Report
52// #################################################################################################
58
63
64
65void Report::PushHaltFlags( bool haltOnErrors, bool haltOnWarnings )
66{
68 haltAfterReport.push( (haltOnErrors ? 1 : 0)
69 + (haltOnWarnings ? 2 : 0));
70}
72{
74 bool stackEmptyError;
75 )
76
77 {
79 haltAfterReport.pop();
80
81 ALIB_DBG( stackEmptyError= haltAfterReport.size() == 0; )
82 }
83
85 if ( stackEmptyError )
86 {
87 PushHaltFlags( true, true );
88 ALIB_ERROR( "REPORT", "Stack empty, too many pop operations" );
89 }
90 )
91}
92
93void Report::PushWriter( ReportWriter* newReportWriter )
94{
96 if ( writers.size() > 0 )
97 writers.top()->NotifyActivation( lang::Phase::End );
98 writers.push( newReportWriter );
99 newReportWriter->NotifyActivation( lang::Phase::Begin );
100}
101
102void Report::PopWriter( ReportWriter* checkWriter )
103{
105 if ( writers.size() == 0 ) { ALIB_ERROR( "REPORT", "No Writer to remove" ) return; }
106 if ( writers.top() != checkWriter ) { ALIB_ERROR( "REPORT", "Report Writer is not actual" ) return; }
107 writers.top()->NotifyActivation( lang::Phase::End );
108 writers.pop();
109 if ( writers.size() > 0 )
110 writers.top()->NotifyActivation( lang::Phase::Begin );
111}
112
114{
116 return writers.top();
117}
118
119void Report::DoReport( Message& message )
120{
123 return;
124 recursionBlocker= true;
125
126 try
127 {
128 if ( writers.size() > 0 )
129 writers.top()->Report( message );
130 }
131 catch( Exception& e )
132 {
133 e.Add( message.File, message.Line, message.Function, ReportExceptions::ErrorWritingReport );
134 throw;
135 }
136
137 #if ALIB_DEBUG
138 int haltFlags= haltAfterReport.top();
139 bool halt= (message.Type == Report::Types::Error && ( (haltFlags & 1) != 0) )
140 || (message.Type == Report::Types::Warning && ( (haltFlags & 2) != 0) );
141
142 #if defined( _WIN32 )
143 if( halt )
144 {
145 #if ALIB_CAMP
147 DebugBreak();
148 else
149 #endif
150 assert( false );
151 }
152 #else
153 assert( !halt );
154 #endif
155
156 #endif
157 recursionBlocker= false;
158}
159
160
162{
163 #if ALIB_THREADS
164 if ( phase == lang::Phase::Begin )
166 else
168 #else
169 (void) phase;
170 #endif
171}
172
173
175{
177
178 String1K buffer( "ALib " );
179 if ( msg.Type.Integral() == 0 ) buffer._( "Error: " );
180 else if ( msg.Type.Integral() == 1 ) buffer._( "Warning: " );
181 else buffer._( "Report (type=" )._( msg.Type )._("): ");
182
183 auto* out = msg.Type.Integral() == 0 || msg.Type.Integral() == 1 ? &std::cerr : &std::cout;
184 auto* other= msg.Type.Integral() == 0 || msg.Type.Integral() == 1 ? &std::cout : &std::cerr;
185
186 // With ALox replacing this report writer (the usual thing), the first string might
187 // become auto-detected as an ALox domain name. To keep this consistent wie do a similar
188 // effort here (code is copied from ALoxReportWriter::Report())
189 NString32 replacement;
190 if( msg.Size() > 1
191 && msg[0].IsArrayOf<nchar>()
192 && msg[0].UnboxLength() < 29 )
193 {
194 bool illegalCharacterFound= false;
195 NString firstArg= msg[0].Unbox<NString>();
196 for( integer idx= 0 ; idx< firstArg.Length() ; ++idx )
197 {
198 char c= firstArg[idx];
199 if (! ( isdigit( c )
200 || ( c >= 'A' && c <= 'Z' )
201 || c == '-'
202 || c == '_'
203 || c == '/'
204 || c == '.'
205 ) )
206 {
207 illegalCharacterFound= true;
208 break;
209 }
210 }
211
212 if(!illegalCharacterFound)
213 {
214 replacement << firstArg << ": ";
215 msg[0]= replacement;
216 }
217 }
218
220 if( formatter != nullptr)
221 {
222 formatter->Acquire( ALIB_CALLER_PRUNED );
223 try
224 {
225 formatter->FormatArgs( buffer, msg );
226 }
227 catch ( Exception & e )
228 {
229 buffer << BASECAMP.GetResource( "RepFmtExc" );
230 e.Format( buffer );
231 out = &std::cerr;
232 other = &std::cout;
233 }
234 formatter->Release();
235 }
236 else
237 {
238 for( auto& box : msg )
239 buffer << box << " ";
240 buffer << NewLine() << "(Note: Default Formatter was not available while writing Report)";
241 }
242 buffer << NewLine() << "At : " << msg.File << ':' << msg.Line << ' ' << msg.Function << "()";
243
244 out ->flush();
245 other->flush();
246 *out << std::endl;
247
248 ALIB_STRINGS_TO_NARROW(buffer, nBuffer, 1024)
249 out->write( nBuffer.Buffer(), nBuffer.Length() );
250 *out << std::endl;
251 out ->flush();
252 other->flush();
253
254 #if defined( _WIN32 ) && ALIB_CAMP
256 {
257 #if !ALIB_CHARACTERS_WIDE
258 OutputDebugStringA( buffer );
259 OutputDebugStringA( "\r\n" );
260 #else
261 OutputDebugStringW( buffer );
262 OutputDebugStringW( L"\r\n" );
263 #endif
264 }
265 #endif
266
268}
269
270
271} // namespace [alib::lang]
integer Size() const
Definition boxes.inl:258
const String & GetResource(const NString &name)
Exception & Add(const NCString &file, int line, const NCString &func, TEnum type, TArgs &&... args)
ALIB_API AString & Format(AString &target) const
virtual ALIB_API void NotifyActivation(lang::Phase phase) override
Definition report.cpp:161
virtual ALIB_API void Report(Message &msg) override
Definition report.cpp:174
virtual void Report(Message &msg)=0
virtual void NotifyActivation(lang::Phase phase)=0
ALIB_API void PushWriter(ReportWriter *newWriter)
Definition report.cpp:93
ALIB_API void DoReport(Message &message)
Definition report.cpp:119
threads::ThreadLock lock
Definition report.hpp:127
std::stack< ReportWriter * > writers
Definition report.hpp:116
ALIB_API ~Report()
Definition report.cpp:59
ALIB_API void PopWriter(ReportWriter *checkWriter)
Definition report.cpp:102
ALIB_API Report()
Definition report.cpp:53
ALIB_API void PushHaltFlags(bool haltOnErrors, bool haltOnWarnings)
Definition report.cpp:65
static ALIB_API Report * defaultReport
Definition report.hpp:110
ALIB_API ReportWriter * PeekWriter()
Definition report.cpp:113
ALIB_API void PopHaltFlags()
Definition report.cpp:71
std::stack< int > haltAfterReport
Definition report.hpp:136
ALIB_API bool IsDebuggerPresent()
static SPFormatter GetDefault()
static TDerivedClass & GetSingleton()
Definition singleton.hpp:61
constexpr integer Length() const
Definition string.hpp:357
ALIB_API int RemoveAcquirer(ThreadLock *acquirer)
Definition smartlock.cpp:92
ALIB_API int AddAcquirer(ThreadLock *newAcquirer)
Definition smartlock.cpp:29
static ALIB_API SmartLock StdOutputStreams
#define ALIB_BOXING_VTABLE_DEFINE(TMapped, Identifier)
Definition vtable.inl:490
#define ALIB_IF_THREADS(...)
Definition alib.hpp:303
#define ALIB_STRINGS_TO_NARROW( src, dest, bufSize)
#define ALIB_ERROR(...)
Definition alib.hpp:980
#define ALIB_DBG(...)
Definition alib.hpp:457
#define ALIB_CALLER_PRUNED
Definition alib.hpp:845
#define ALIB_LOCK_WITH(lock)
platform_specific integer
Definition integers.hpp:50
@ Begin
The start of a transaction.
@ End
The end of a transaction.
constexpr CString NewLine()
Definition cstring.hpp:528
lang::basecamp::BaseCamp BASECAMP
Definition basecamp.cpp:136
std::shared_ptr< lang::format::Formatter > SPFormatter
characters::nchar nchar
Type alias in namespace alib.
integer Integral() const
Definition enum.hpp:123