ALib C++ Library
Library Version: 2511 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
alox.cpp
1//##################################################################################################
2// ALib C++ Library
3//
4// Copyright 2013-2025 A-Worx GmbH, Germany
5// Published under 'Boost Software License' (a free software license, see LICENSE.txt)
6//##################################################################################################
7#include "alib_precompile.hpp"
8#if !defined(ALIB_C20_MODULES) || ((ALIB_C20_MODULES != 0) && (ALIB_C20_MODULES != 1))
9# error "Symbol ALIB_C20_MODULES has to be given to the compiler as either 0 or 1"
10#endif
11#if ALIB_C20_MODULES
12 module;
13#endif
14//========================================= Global Fragment ========================================
19
20//============================================== Module ============================================
21#if ALIB_C20_MODULES
22 module ALib.ALox;
23 import ALib.Lang;
24 import ALib.Containers.List;
25 import ALib.Monomem;
26 import ALib.Boxing;
27 import ALib.EnumRecords;
28 import ALib.Strings;
29 import ALib.EnumRecords.Bootstrap;
30 import ALib.Variables;
31 import ALib.Camp;
32 import ALib.Camp.Base;
33 import ALib.ALox.Impl;
34#else
35# include "ALib.Lang.H"
36# include "ALib.Containers.List.H"
37# include "ALib.Monomem.H"
38# include "ALib.Boxing.H"
40# include "ALib.Variables.H"
41# include "ALib.Camp.H"
42# include "ALib.Camp.Base.H"
43# include "ALib.ALox.H"
44# include "ALib.ALox.Impl.H"
45#endif
46//========================================== Implementation ========================================
47#if !DOXYGEN
48namespace alib::lox::detail {
49namespace { ListMA<Lox*> loxes(monomem::GLOBAL_ALLOCATOR); }
50integer dbgCountLoxes() { return loxes.size(); }
51void shutdownLoxes() {
52 while ( loxes.IsNotEmpty() )
53 loxes.back()->~Lox();
54 loxes.Reset();
55}
56
57}
58#endif
59
60namespace alib::lox {
61
63
64//##################################################################################################
65// Lox management
66//##################################################################################################
67#if !DOXYGEN
68
69#if ALOX_DBG_LOG
70 Lox* DEBUG_LOX = nullptr; // will be created in ALoxCamp::Bootstrap
71#endif
72
73#endif
74
75
76// The lox singletons for debug and release logging
79
80 // search
81 for( auto* it : detail::loxes )
82 if( it->GetName().Equals<CHK, lang::Case::Ignore>( name ) )
83 return it;
84
85
86 // create?
87 if ( create == lang::CreateIfNotExists::Yes ) {
88 Lox* newLox= new Lox ( name, false );
89 detail::loxes.emplace_back( newLox );
90 return newLox;
91 }
92
93 // not found
94 return nullptr;
95}
96
99
100 // check
101 if ( lox == nullptr ) {
102 ALIB_ERROR( "ALOX", "Nullptr given" )
103 return;
104 }
105
106 // remove
107 if( operation == lang::ContainerOp::Remove ) {
108 for( auto search= detail::loxes.begin() ; search != detail::loxes.end() ; ++search )
109 if ( *search == lox ) {
110 (void) detail::loxes.erase( search );
111 return;
112 }
113 ALIB_WARNING( "ALOX", "Given lox named \"{}\" could not be found for removal.",
114 lox != nullptr ? lox->GetName() : "<null>" )
115 }
116
117 // insert
118 else {
119 for( auto* it : detail::loxes )
120 if( it->GetName().Equals<NC>( lox->GetName() ) ) {
121 ALIB_ERROR( "ALOX", "Given lox named \"{}\" was already registered. "
122 "Registration ignored.", lox->GetName() )
123 return;
124 }
125 detail::loxes.emplace_back( lox );
126}}
127
128
129Lox::Lox(const NString& name, bool doRegister ) {
131
132 if( doRegister )
134}
135
142
143
144//##################################################################################################
145// Static methods of Lox
146//##################################################################################################
148 //--- check configuration setting "CONSOLE_TYPE" ---
150 if(variable.Define())
151 variable= String( A_CHAR("Default") );
152
153 Substring val = variable;
154 val.Trim();
155 if( val.IsEmpty() ||
156 val.Equals<NC, lang::Case::Ignore>( A_CHAR("Default") ) ) goto DEFAULT;
157
158 if( val.Equals<NC, lang::Case::Ignore>( A_CHAR("Plain") ) ) return new ConsoleLogger ( name );
159 if( val.Equals<NC, lang::Case::Ignore>( A_CHAR("Ansi") ) ) return new AnsiConsoleLogger( name );
160
161 if( val.Equals<NC, lang::Case::Ignore>( A_CHAR("Windows") ) )
162 #if defined( _WIN32 )
163 return new WindowsConsoleLogger( name );
164 #else
165 goto DEFAULT;
166 #endif
167 ALIB_WARNING( "ALOX", "Unrecognized value in config variable \"{}\" = \"{}\".",
168 variable, variable.GetString() )
169
170 DEFAULT:
171 if( variable.Define(variables::Priority::Standard) )
172 variable.GetString().Reset(A_CHAR("Default"));
173
174 #if defined( _WIN32 )
175 // if there is no console window we do not do colors
176 if ( !BASECAMP.HasConsoleWindow )
177 return new ConsoleLogger( name );
178 else
179 return new WindowsConsoleLogger( name );
180 #else
181 return new AnsiConsoleLogger( name );
182 #endif
183}
184
185
186#if ALOX_DBG_LOG
187//##################################################################################################
188// Auto detection of DEBUG environment
189//##################################################################################################
191TextLogger* Log::IDELogger = nullptr;
192
194 static bool recursion= false;
195 if( recursion )
196 return;
197 recursion= true;
198
199 // block recursion caused by log operations in this code
200 if ( DebugLogger != nullptr ) {
201 ALIB_WARNING( "ALOX", "Log::AddDebugLogger(): called twice." )
202 recursion= false;
203 return;
204 }
205 DebugLogger= reinterpret_cast<decltype(DebugLogger)>(-1);
206
207 // add a VStudio logger if this is a VStudio debug session
208 #if defined(_MSC_VER) && ALIB_DEBUG
209 if( BASECAMP.IsDebuggerPresent() ) {
210 Variable variable= variables::CampVariable( ALOX, Variables::NO_IDE_LOGGER );
211 bool createIDELogger= variable.IsNotDefined() || (variable.GetBool() == false);
212
213 if(createIDELogger) {
214 IDELogger= new VStudioLogger("IDE_LOGGER");
215
216 // add logger
217 lox->SetVerbosity( IDELogger, Verbosity::Verbose, "/" );
218 lox->SetVerbosity( IDELogger, Verbosity::Warning, Lox::InternalDomains );
219 } }
220 #endif
221
222 // add a default console logger
223 DebugLogger= Lox::CreateConsoleLogger("DEBUG_LOGGER");
224
225 // add logger by setting verbosities
226 lox->SetVerbosity( DebugLogger, Verbosity::Verbose );
227 lox->SetVerbosity( DebugLogger, Verbosity::Warning, Lox::InternalDomains );
228
229 // check various variables, if existed already externally. If not, create them empty or
230 // with debug defaults (only done here, namely for debug logger)
231 {ALIB_LOCK_WITH(ALOX.GetConfig())
232 // Verbosity: If not, set 'ExportAll' flag
233 Variable variable= variables::CampVariable( ALOX );
234 Box replacements[2]= { "LOG", "DEBUG_LOGGER" };
235 variable.Declare( Variables::VERBOSITY, replacements );
236 if( variable.IsNotDefined() ) {
237 (void) variable.Define();
238 variable.Get<CVVerbosities>().ExportAll= true;
239 }
240
241 variable.Declare( Variables::SPTR_LOX , "LOG" ); (void) variable.Define();
242 variable.Declare( Variables::DOMAIN_SUBSTITUTION, "LOG" ); (void) variable.Define();
243 variable.Declare( Variables::PREFIXES , "LOG" ); (void) variable.Define();
244 variable.Declare( Variables::DUMP_STATE_ON_EXIT , "LOG" ); (void) variable.Define();
245 if( dynamic_cast<AnsiConsoleLogger*>(DebugLogger) != nullptr )
246 variable.Declare( Variables::CONSOLE_LIGHT_COLORS ); (void) variable.Define();
247 }
248
249 // set ALib's assertion plugin with one that uses ALox
250 SetALibAssertionPlugin( lox );
251
252 recursion= false;
253}
254
256 // remove ALox specific assertion plugin of ALib
257 SetALibAssertionPlugin( nullptr );
258
259 // remove debug logger(s)
260 ALIB_ASSERT_WARNING( DebugLogger != nullptr, "ALOX",
261 "Log::RemoveDebugLogger(): no debug logger to remove." )
262
263 if ( DebugLogger != nullptr ) {
264 lox->RemoveLogger( DebugLogger );
265
266 delete DebugLogger;
267 DebugLogger= nullptr;
268 }
269
270 #if defined(_WIN32) && ALIB_DEBUG
271 if ( IDELogger != nullptr ) {
272 lox->RemoveLogger( IDELogger );
273
274 delete IDELogger;
275 IDELogger= nullptr;
276 }
277 #endif
278}
279#endif // ALOX_DBG_LOG
280
281
282//##################################################################################################
283// ALoxAssertionPlugin
284//##################################################################################################
285#if ALIB_DEBUG
286
287//==================================================================================================
288/// This function will be set to global pointer \alib{assert::PLUGIN} when calling
289/// method \alib{lox;Log::AddDebugLogger}.<br>
290/// If no debug-logging is used, or method \b AddDebugLogger is not used, then
291/// this function can also be used with a different \b Lox and explicitly activated using
292/// the static method \alib{lox;Log::SetALibAssertionPlugin}.
293/// Uses internal domain <b>"/ALIB"</b> for logging, respectively to what the global variable
294/// \ref ALOX_ASSERTION_PLUGIN_DOMAIN_PREFIX is set.
295/// @param ci Information about the scope of invocation.
296/// @param type The type of the message. As a convention, \c 0 is an assertion, \c 1 is a
297/// warning, \c 2 is an info message, \c 3 or above are a verbose messages.
298/// @param domain The domain of the assertion, warning, or message.
299/// Will be appended to the \alox domain.
300/// @param msg The assembled message to print.
301//==================================================================================================
303 int type,
304 std::string_view domain,
305 std::string_view msg );
306
307std::string_view const ALOX_ASSERTION_PLUGIN_DOMAIN_PREFIX = "/ALIB";
308
309#if !DOXYGEN
310namespace { Lox* assertionLox= nullptr; }
311#endif
312
314
315 // remove plugin
316 if ( pLox == nullptr ) {
317 if ( assertionLox == nullptr )
318 return;
319
320 assertionLox->Acquire( ALIB_CALLER );
321 assertionLox->GetLogableContainer().Add( "ALoxAssertionPlugin removed "
322 "from Lox {!Q}", assertionLox->GetName() );
323 assertionLox->Entry( ALOX_ASSERTION_PLUGIN_DOMAIN_PREFIX, Verbosity::Verbose );
324 assertionLox->Release ();
325 assertionLox = nullptr;
326 assert::PLUGIN= nullptr;
327 return;
328 }
329
330 // add plugin
331 assertionLox = pLox;
333 assertionLox->Acquire( ALIB_CALLER );
334 assertionLox->GetLogableContainer().Add( "ALoxAssertionPlugin set to Lox {!Q}.", pLox->GetName() );
335 assertionLox->Entry( ALOX_ASSERTION_PLUGIN_DOMAIN_PREFIX, Verbosity::Verbose );
336
337 // we set the verbosity only now. This should
338 // - allow to have the above verbose message seen once
339 // - in case the values become externalized, this setting is written to such external
340 // configuration file and thus is not displayed a second time.
341 assertionLox->SetVerbosity( DebugLogger, Verbosity::Warning, ALOX_ASSERTION_PLUGIN_DOMAIN_PREFIX );
342 assertionLox->Release ();
343}
344
346 int type,
347 std::string_view domain,
348 std::string_view msg ) {
349 assertionLox->Acquire( ci );
350
351 auto& logables= assertionLox->GetLogableContainer();
352 logables.Add( msg );
353
354 auto verbosity= type == 0 ? Verbosity::Error :
355 type == 1 ? Verbosity::Warning :
356 type == 2 ? Verbosity::Info :
357 Verbosity::Verbose ;
358
359 NString256 dom(ALOX_ASSERTION_PLUGIN_DOMAIN_PREFIX); dom << '/' << domain;
360
361 assertionLox->Entry( dom, verbosity );
362 assertionLox->Release ();
363}
364
365
366#endif //ALIB_DEBUG
367
368# include "ALib.Lang.CIMethods.H"
369}// namespace [alib::lox]
static ALIB_DLL textlogger::TextLogger * DebugLogger
The debug logger created by AddDebugLogger.
Definition log.inl:40
static ALIB_DLL void RemoveDebugLogger(Lox *lox)
Definition alox.cpp:255
static ALIB_DLL void AddDebugLogger(Lox *lox)
Definition alox.cpp:193
static ALIB_DLL void SetALibAssertionPlugin(Lox *lox)
Definition alox.cpp:313
static ALIB_DLL textlogger::TextLogger * IDELogger
An (additional) IDE specific logger, that might be created by AddDebugLogger.
Definition log.inl:43
This class acts as a container for Loggers and provides a convenient interface to logging.
Definition lox.inl:14
ALIB_DLL ~Lox()
Destructs a lox.
Definition alox.cpp:136
ALIB_DLL Lox(const NString &name, bool doRegister=true)
Definition alox.cpp:129
detail::LoxImpl * impl
The implementation.
Definition lox.inl:22
static ALIB_DLL textlogger::TextLogger * CreateConsoleLogger(const NString &name=nullptr)
Definition alox.cpp:147
static constexpr NString InternalDomains
Definition lox.inl:46
const NString & GetName()
Definition lox.inl:119
static ALIB_DLL void Register(Lox *lox, lang::ContainerOp operation)
Definition alox.cpp:97
static ALIB_DLL Lox * Get(const NString &name, lang::CreateIfNotExists create=lang::CreateIfNotExists::No)
Definition alox.cpp:77
constexpr bool IsEmpty() const
Definition string.inl:365
bool Equals(const TString< TChar > &rhs) const
Definition string.inl:531
TSubstring & Trim(const TCString< TChar > &whiteSpaces=CStringConstantsTraits< TChar >::DefaultWhitespaces())
ALIB_DLL bool Define(Priority requestedPriority=Priority::Standard)
Definition variable.cpp:261
#define ALIB_CALLER
Definition alib.inl:1018
#define A_CHAR(STR)
#define ALIB_WARNING(domain,...)
Definition alib.inl:1063
#define ALIB_ASSERT_WARNING(cond, domain,...)
Definition alib.inl:1067
#define ALIB_ERROR(domain,...)
Definition alib.inl:1062
#define ALIB_LOCK_RECURSIVE_WITH(lock)
Definition alib.inl:1340
#define ALIB_LOCK_WITH(lock)
Definition alib.inl:1339
void(* PLUGIN)(const CallerInfo &ci, int type, std::string_view domain, std::string_view msg)
Definition assert.cpp:172
ContainerOp
Denotes standard container operations.
@ Remove
Denotes removals.
@ Insert
Denotes insertions.
CreateIfNotExists
Denotes whether something should be created if it does not exist.
@ Yes
Create if something does not exist.
void shutdownLoxes()
Internal lox management.
integer dbgCountLoxes()
void ALoxAssertionPlugin(const lang::CallerInfo &ci, int type, std::string_view domain, std::string_view msg)
Definition alox.cpp:345
std::string_view const ALOX_ASSERTION_PLUGIN_DOMAIN_PREFIX
Definition alox.cpp:307
ALIB_DLL Lox * DEBUG_LOX
@ CONSOLE_LIGHT_COLORS
Denotes configuration variable ALOX/CONSOLE_LIGHT_COLORS used by colorful specializations of class Te...
Definition aloxcamp.inl:67
@ CONSOLE_TYPE
Denotes configuration variable ALOX/CONSOLE_TYPE used by Lox::CreateConsoleLogger.
Definition aloxcamp.inl:25
@ VERBOSITY
Denotes configuration variable ALOX/LOGGERNAME/VERBOSITY_WITH_LOXNAME.
Definition aloxcamp.inl:28
@ DOMAIN_SUBSTITUTION
Denotes configuration variable ALOX/LOXNAME/DOMAIN_SUBSTITUTION used by class Lox.
Definition aloxcamp.inl:37
@ DUMP_STATE_ON_EXIT
Denotes configuration variable ALOX/LOXNAME/DUMP_STATE_ON_EXIT used by class Lox.
Definition aloxcamp.inl:43
@ SPTR_LOX
Denotes configuration variable ALOX/LOXNAME/SOURCE_PATH_TRIM_RULES used by class Lox.
Definition aloxcamp.inl:34
@ PREFIXES
Denotes configuration variable ALOX/LOXNAME/PREFIXES used by class Lox.
Definition aloxcamp.inl:40
ALIB_DLL TMonoAllocator< lang::HeapAllocator > GLOBAL_ALLOCATOR
ALIB_DLL RecursiveLock GLOBAL_ALLOCATOR_LOCK
variables::Variable CampVariable(camp::Camp &camp)
Definition camp.inl:344
variables::Variable Variable
Type alias in namespace alib.
camp::Basecamp BASECAMP
The singleton instance of ALib Camp class Basecamp.
Definition basecamp.cpp:81
lox::loggers::AnsiConsoleLogger AnsiConsoleLogger
Type alias in namespace alib.
containers::List< T, MonoAllocator, TRecycling > ListMA
Type alias in namespace alib.
Definition list.inl:693
lox::loggers::ConsoleLogger ConsoleLogger
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
strings::TString< nchar > NString
Type alias in namespace alib.
Definition string.inl:2198
lox::ALoxCamp ALOX
The singleton instance of ALib Camp class ALoxCamp.
Definition aloxcamp.cpp:53
lox::loggers::WindowsConsoleLogger WindowsConsoleLogger
Type alias in namespace alib.
boxing::Box Box
Type alias in namespace alib.
Definition box.inl:1149
lox::Lox Lox
Type alias in namespace alib.
Definition lox.inl:1268
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2189
NLocalString< 256 > NString256
Type alias name for TLocalString<nchar,256>.
strings::TSubstring< character > Substring
Type alias in namespace alib.
lox::textlogger::TextLogger TextLogger
Type alias in namespace alib.
See sibling type NC.
Definition chk_nc.inl:33
static ALIB_DLL void Destruct(LoxImpl *lox)
static ALIB_DLL LoxImpl * Construct(const NString &name)