ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
aloxmodule.cpp
1// #################################################################################################
2// alib::lox::detail - ALox Logging 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_ALOX)
11# include "alib/alox/alox.hpp"
12# endif
13# if !defined (HPP_ALIB_CONFIG_INI_FILE)
15# endif
16# if !defined (HPP_ALOX_DETAIL_LOGGER)
18# endif
19# if !defined (HPP_ALIB_ALOXMODULE)
21# endif
22
23# if !defined (HPP_ALIB_LANG_BASECAMP)
25# endif
26# if !defined(HPP_ALIB_ENUMS_SERIALIZATION)
28# endif
29# if !defined (HPP_ALIB_LANG_RESOURCES_RESOURCES)
31# endif
32# if !defined (HPP_ALIB_ENUMS_RECORDBOOTSTRAP)
34# endif
35# if !defined (HPP_ALIB_STRINGS_FORMAT)
37# endif
38# if !defined(HPP_ALIB_CAMP_MESSAGE_REPORT)
40# endif
41
46 ALIB_COMMA alib::config::Priorities>, vt_lox_pair_verby_prio )
47
48#endif // !defined(ALIB_DOX)
49
50namespace alib {
51
53
54/** ************************************************************************************************
55 * This is the \b C++ version of <b>%ALox Logging Library</b>, which has been integrated
56 * as one of many modules into the <b>ALib C++ Class Library</b>.<br>
57 *
58 * Please check out the \ref alib_mod_alox "documentation of ALib Module ALox" for more
59 * information.
60 **************************************************************************************************/
61namespace lox {
62
63#if ALIB_DEBUG && !defined(ALIB_DOX)
64 namespace { integer dbgCheckQtyConfigPlugins; }
65#endif
66
67
69: Camp( "ALOX" )
70{
71 ALIB_ASSERT_ERROR( this == &ALOX, "ALOX",
72 "Instances of class ALox must not be created. Use singleton alib::ALOX" )
73}
74
75// #################################################################################################
76// Compilation Flags
77// #################################################################################################
78
79// check compiler symbols, give warning once (therefore not in HPP)
80#if !ALOX_DBG_LOG && ALOX_DBG_LOG_CI
81# pragma message ( "Warning: ALox compiler symbol mismatch: ALOX_DBG_LOG_CI is true, while ALOX_DBG_LOG is false." )
82#endif
83#if !ALOX_REL_LOG && ALOX_REL_LOG_CI
84# pragma message ( "Warning: ALox compiler symbol mismatch: ALOX_REL_LOG_CI is true, while ALOX_REL_LOG is false" )
85#endif
86
87// #################################################################################################
88// Lox management
89// #################################################################################################
90#if !defined(ALIB_DOX)
91 namespace
92 {
94 }
95
96#if ALOX_DBG_LOG
97 Lox* theDebugLox = nullptr; // will be created in ALox::bootstrap
98#endif
99
100#endif
101
102
103// The lox singletons for debug and release logging
105{
107
108 // search
109 for( auto* it : loxes )
110 if( it->GetName().Equals<true, lang::Case::Ignore>( name ) )
111 return it;
112
113
114 // create?
115 if ( create == lang::CreateIfNotExists::Yes )
116 {
117 Lox* newLox= new Lox ( name, false );
118 loxes.EmplaceBack( newLox );
119 return newLox;
120 }
121
122 // not found
123 return nullptr;
124}
125
126void ALox::Register( Lox* lox, lang::ContainerOp operation )
127{
129
130 // check
131 if ( lox == nullptr )
132 {
133 ALIB_ERROR( "ALOX", "Nullptr given" )
134 return;
135 }
136
137 // remove
138 if( operation == lang::ContainerOp::Remove )
139 {
140 for( auto search= loxes.begin() ; search != loxes.end() ; ++search )
141 if ( *search == lox )
142 {
143 loxes.Erase( search );
144 return;
145 }
146 ALIB_WARNING( "ALOX", "Given lox named {!Q} could not be found for removal.",
147 lox != nullptr ? lox->GetName() : "<null>" )
148 }
149
150 // insert
151 else
152 {
153 for( auto* it : loxes )
154 if( it->GetName().Equals<false>( lox->GetName() ) )
155 {
156 ALIB_ERROR( "ALOX", "Given lox named {!Q} was already registered. Registration ignored.",
157 lox->GetName() )
158 return;
159 }
160 loxes.EmplaceBack( lox );
161 }
162}
163
164
165// #################################################################################################
166// ALox module initialization
167// #################################################################################################
168
170{
172 {
176 ALIB_BOXING_BOOTSTRAP_VTABLE_DBG_REGISTER( vt_lox_pair_verby_prio )
177
178
179#if !ALIB_RESOURCES_OMIT_DEFAULTS
181
182 "Var0" , A_CHAR( "1|ALOX|NO_IDE_LOGGER|" "||" ) ,
183 "Var1" , A_CHAR( "2|ALOX|CONSOLE_TYPE|" "||" ) ,
184 "Var2" , A_CHAR( "3|ALOX|%1_%2_VERBOSITY|" ";|=|1" ) ,
185 "Var3" , A_CHAR( "4|ALOX|GLOBAL_SOURCE_PATH_TRIM_RULES|" ";|=|1" ) ,
186 "Var4" , A_CHAR( "5|ALOX|%1_SOURCE_PATH_TRIM_RULES|" ";|=|1" ) ,
187 "Var5" , A_CHAR( "6|ALOX|%1_DOMAIN_SUBSTITUTION|" ";|->|1" ) ,
188 "Var6" , A_CHAR( "7|ALOX|%1_PREFIXES|" ";|=|1" ) ,
189 "Var7" , A_CHAR( "8|ALOX|%1_DUMP_STATE_ON_EXIT|" ",||" ) ,
190 "Var8" , A_CHAR("20|ALOX|%1_AUTO_SIZES|" "||" ) ,
191 "Var9" , A_CHAR("21|ALOX|%1_FORMAT|" ",||1" ) ,
192 "Var10", A_CHAR("22|ALOX|%1_FORMAT_DATE_TIME|" ",||" ) ,
193 "Var11", A_CHAR("23|ALOX|%1_FORMAT_MULTILINE|" ",||" ) ,
194 "Var12", A_CHAR("24|ALOX|%1_FORMAT_TIME_DIFF|" ",||" ) ,
195 "Var13", A_CHAR("25|ALOX|%1_MAX_ELAPSED_TIME|" ",||" ) ,
196 "Var14", A_CHAR("26|ALOX|%1_REPLACEMENTS|" ",||" ) ,
197 "Var15", A_CHAR("27|ALOX|CONSOLE_LIGHT_COLORS|" "||" ) ,
198 #if defined(_WIN32)
199 "Var16", A_CHAR("28|ALOX|CODEPAGE|" "||" ) ,
200 #endif
201
202 // configuration variable default values
203 "Var_D1", A_CHAR("false"),
204 "Var_D2", A_CHAR("default"),
205 "Var_D3", A_CHAR("writeback"),
206 "Var_D8", A_CHAR("none, verbosity=info, domain=/ALOX"),
207
208 "Var_D25", A_CHAR("0, limit=59"),
209 #if defined(_WIN32)
210 "Var_D28", A_CHAR("65001"),
211 #endif
212
213 // configuration variable comments
214 "Var_C1", A_CHAR("If true, the creation of an additional, ide-specific debug logger is suppressed." "\n"
215 "(In particular suppresses DebugLogger (C#) and VStudioLogger (C++))" ),
216
217 "Var_C2", A_CHAR("Influences the type of console logger to be created by method" "\n"
218 "Lox::CreateConsoleLogger which is also used by Log::AddDebugLogger" "\n"
219 "Possible values are: default, plain, ansi, windows, noqtcreator" ),
220
221 "Var_C3", A_CHAR("The verbosities of logger \"%2\" in lox \"%1\". Use 'writeback [VAR_NAME] ;'" "\n"
222 "to enable automatic writing on application exit." ),
223
224 "Var_C4", A_CHAR("Defines global source path trim rules (applicable for all Lox instances)." "\n"
225 " Format: [*]sourcepath [, inclusion, trimoffset, sensitivity, replacement] [ ; \u2026 ]" ),
226
227 "Var_C5", A_CHAR("Defines source path trim rules for Lox \"%1\". " "\n"
228 " Format: [*]sourcepath [, inclusion, trimoffset, sensitivity, replacement] [ ; \u2026 ]" ),
229
230 "Var_C7", A_CHAR("Prefix strings for log domains of lox \"%1\".\n"
231 " Format: [*]domainpath[*] = prefixstring [, inclusion] [ ; \u2026 ] " ),
232
233 "Var_C8", A_CHAR("Log information about lox \"%1\" on exit. Comma separated list of arguments define" "\n"
234 "verbosity, domain and content of output. Possible values content arguments are:" "\n"
235 " All, " "Basic, " "Version, " "SPTR, " "Loggers, " "Domains, " "InternalDomains" "\n"
236 " ScopeDomains, " "DSR, " "PrefixLogables" "Once, " "LogData, " "ThreadMappings, " "\n"
237 " CompilationFlags." " If NONE is given nothing is dumped." ),
238
239 "Var_C20", A_CHAR("Auto size values of last run of Logger '%1' (generated and temporary values)."),
240
241 "Var_C21", A_CHAR("Meta info format of text logger \"%1\", including signatures for verbosity strings and" "\n"
242 "an optional string added to the end of each log statement." "\n"
243 " Format: metaInfoFormat [, Error [, Warning [, Info [, Verbose [, MsgSuffix ]]]]]"),
244
245 "Var_C22", A_CHAR("Meta info date and time format of text logger \")%1\"." "\n"
246 " Format: DateFormat [, TimeOfDayFormat [, TimeElapsedDays ]]]"),
247
248 "Var_C23", A_CHAR("Multi-line format of text logger \"%1\"." "\n"
249 " Format: MultiLineMsgMode [, FmtMultiLineMsgHeadline [, FmtMultiLinePrefix [, FmtMultiLineSuffix\n"
250 " [, MultiLineDelimiter [, MultiLineDelimiterRepl ]]]]]"),
251
252 "Var_C24", A_CHAR("Meta info time difference entities of text logger \"%1\"." "\n"
253 " Format: TimeDiffMinimum [, TimeDiffNone [, TimeDiffNanos [, TimeDiffMicros [, TimeDiffMillis\n"
254 " [, TimeDiffSecs [, TimeDiffMins [, TimeDiffHours [, TimeDiffDays ]]]]]]]]"),
255
256 "Var_C25", A_CHAR("Maximum elapsed time of all runs of Logger '%1'. To reset elapsed time display""\n"
257 "width, set this to 0 manually. Generated and temporary value.)" ),
258
259 "Var_C26", A_CHAR("Pairs of search and replacement strings for text logger \"%1\"." "\n"
260 " Format: search, replacement [, search, replacement] [,...]"),
261
262 "Var_C27", A_CHAR("Evaluated by colorful loggers that dispose about light and dark colors. Those may" "\n"
263 "adjust their foreground and background color accordingly. If not given, under Windows OS" "\n"
264 "the right value is detected. Otherwise the value defaults to \"foreground\". In some" "\n"
265 "occasions, the (detected or set) runtime environment might also indicate a different" "\n"
266 "default value. Possible values are 'foreground', 'background' and 'never'."),
267
268 #if defined(_WIN32)
269 "Var_C28", A_CHAR("Code page used by class WindowsConsoleLogger. Defaults to 65001." "\n"
270 "(Only used on Windows OS)" ),
271 #endif
272
273 //###################################### Enums #######################################
274 "Verbosity", A_CHAR("0,Verbose,1,"
275 "1,Info,1,"
276 "2,Warning,1,"
277 "2,Warnings,1," //allow with trailing s when reading
278 "3,Error,1,"
279 "3,Errors,1," //allow with trailing s when reading
280 "4,Off,1" ),
281
282 "Scope", A_CHAR("0,Global,1,"
283 "1,ThreadOuter,7,"
284 "2,Filename,1,"
285 "3,Method,1,"
286 "4,ThreadInner,7,"
287 "5,Path,7" ),
288
289 "StateInfo", A_CHAR("0" "," "NONE" ",1,"
290 "1" "," "Basic" ",1,"
291 "2" "," "Version" ",1,"
292 "^9" "," "LogData" ",4,"
293 "4" "," "Loggers" ",1,"
294 "^6" "," "DSR" ",2,"
295 "8" "," "Domains" ",1,"
296 "^4" "," "InternalDomains" ",1,"
297 "0x100000" "," "SPTR" ",2,"
298 "^5" "," "ScopeDomains" ",1,"
299 "^7" "," "PrefixLogables" ",1,"
300 "^8" "," "Once" ",1,"
301 "^10" "," "ThreadMappings" ",1,"
302 "^21" "," "CompilationFlags" ",1,"
303 "0xFFFFFFFF" "," "All" ",1" ),
304
305 "LightColorUsage", A_CHAR("0,Auto,1,"
306 "1,Never,1,"
307 "2,Foreground,1,"
308 "3,Background,1" ),
309
310 //##################################### Various ######################################
311 "TLFmtExc", A_CHAR("\nAn exception occurred during formatting ALox logables:\n" ),
312
313 "INI_CMT_ALOX", A_CHAR("@>'/// '@HL-Settings controlling ALox log output.\n@HL-"),
314
315 // end of BootstrapBulk()
316 nullptr );
317#endif // !ALIB_RESOURCES_OMIT_DEFAULTS
318
319 // Add box-functions
323 ALIB_BOXING_BOOTSTRAP_REGISTER_FAPPEND_FOR_APPENDABLE_TYPE_N(std::pair<Verbosity ALIB_COMMA Priorities>)
324
325 return;
326 } // BootstrapPhases::PrepareResources
327
328 else if( phase == BootstrapPhases::PrepareConfig )
329 {
330 EnumRecords<Verbosity >::Bootstrap( *this, "Verbosity" );
331 EnumRecords<Scope >::Bootstrap( *this, "Scope" );
332 EnumRecords<StateInfo >::Bootstrap( *this, "StateInfo" );
333 EnumRecords<TextLogger::LightColorUsage>::Bootstrap( *this, "LightColorUsage" );
334
336 }
337
338 else if( phase == BootstrapPhases::Final )
339 {
340 #if ALIB_DEBUG
341 auto& ga=
343 theDebugLox= ga.Emplace<Lox>( "LOG");
345
346 dbgCheckQtyConfigPlugins= config->CountPlugins();
347 #endif
348 }
349}
350
351
353{
354 if( phase == ShutdownPhases::Announce )
356 GetResourcePool(), ResourceCategory, "INI_CMT_" );
357 #if ALOX_DBG_LOG
358 else if( phase == ShutdownPhases::Destruct )
359 {
360 if ( Log::DebugLogger != nullptr )
362
363 monomem::Destruct( theDebugLox );
364
365 while ( loxes.Size() > 0 )
366 detail::LI::Destruct( loxes.Back() );
367 }
368 #endif
369}
370
371
373{
374 Lox("trimruleresetlox", false).Reset(); // this clears the global source path trim rules
375
376 #if ALOX_DBG_LOG
377 if (Log::DebugLogger != nullptr )
379
380 monomem::Destruct( theDebugLox);
381 #endif
382
383 ALIB_ASSERT_ERROR(loxes.Size() == 0, "ALOX", "A Lox remained from the last test" )
384 ALIB_ASSERT_ERROR(config->CountPlugins() == dbgCheckQtyConfigPlugins,
385 "ALOX", "A config plug-in remained from the last test" )
386
387 dynamic_cast<InMemoryPlugin*>( config->GetPlugin( config::Priorities::DefaultValues ) )->Clear();
388 dynamic_cast<InMemoryPlugin*>( config->GetPlugin( config::Priorities::ProtectedValues) )->Clear();
389
390 #if ALOX_DBG_LOG
391 new ( theDebugLox) Lox( "LOG");
392 #endif
393}
394
395void ESC::ReplaceToReadable( AString& target, integer startIdx )
396{
397 while( (startIdx= target.IndexOf( '\033', startIdx ) ) >= 0 )
398 {
399 String32 val("{ESC::");
400 character c= target.CharAt( startIdx + 1 );
401 character c2= target.CharAt( startIdx + 2 );
402
403 const character* code= A_CHAR("ERROR");
404
405 // colors
406 if( c == 'c' || c == 'C' )
407 {
408 if ( c == 'C' )
409 val._<false>( A_CHAR("BG_") );
410 switch( c2 - '0' )
411 {
412 case 0: code= A_CHAR("RED") ; break;
413 case 1: code= A_CHAR("GREEN") ; break;
414 case 2: code= A_CHAR("YELLOW") ; break;
415 case 3: code= A_CHAR("BLUE") ; break;
416 case 4: code= A_CHAR("MAGENTA") ; break;
417 case 5: code= A_CHAR("CYAN") ; break;
418 case 6: code= A_CHAR("BLACK") ; break;
419 case 7: code= A_CHAR("WHITE") ; break;
420 case 8: code= A_CHAR("GRAY") ; break;
421 case 9: code= A_CHAR("RESET") ; break;
422 default: code= A_CHAR("COL_ERR"); break;
423 }
424
425 }
426
427 // styles
428 else if( c == 's' )
429 {
430 switch( c2 )
431 {
432 case 'B': code= A_CHAR("BOLD") ; break;
433 case 'I': code= A_CHAR("ITALICS") ; break;
434 case 'r': code= A_CHAR("STYLE_RESET") ; break;
435 case 'a': code= A_CHAR("RESET") ; break;
436 default: code= A_CHAR("STYLE_ERR") ; break;
437 }
438 }
439
440 // styles
441 else if( c == 'l' )
442 {
443 switch( c2 )
444 {
445 case 'S': code= A_CHAR("URL_START") ; break;
446 case 'E': code= A_CHAR("URL_END") ; break;
447 default: code= A_CHAR("URL_ERR") ; break;
448 }
449 }
450
451 // others
452 else if( c == 't' && c2 == '0' ) code= A_CHAR("TAB");
453 else if( c == 'A' && c2 == '0' ) code= A_CHAR("EOMETA");
454
455 // Replace
456 val._<false>(code)._('}');
457 target.ReplaceSubstring<false>( val, startIdx, 3 );
458 startIdx+= 3;
459 }
460}
461
462}} // namespace [alib::lox]
463
464#if !defined(ALIB_DOX)
465namespace alib { namespace strings {
466void T_Append<Scope,nchar>::operator()( TAString<nchar>& target, const lox::Scope src )
467{
468 Scope scope= src;
469 int pathLevel= UnderlyingIntegral( scope - Scope::Path );
470 if(pathLevel > 0 )
471 scope= Scope::Path;
472
473 target << "Scope::" << enums::GetRecord(scope).EnumElementName;
474
475 if( pathLevel > 0 )
476 target << '+' << pathLevel;
477}
478
479void T_Append<std::pair<Verbosity, Priorities>,nchar>::operator()( TAString<nchar>& target, const std::pair<Verbosity, Priorities>& src )
480{
481 target._( NFormat::Field( src.first, 7, lang::Alignment::Left) );
482 target._( '(' )._( src.second );
483 target.InsertAt( ")", target.LastIndexOfAny<lang::Inclusion::Exclude>( NDefaultWhitespaces() ) + 1 );
484}
485}}
486#endif // !defined(ALIB_DOX)
static ALIB_API void AddResourcedSectionComments(Configuration &config, ResourcePool &resourcePool, const NString &resourceCategory, const NString &resourceNamePrefix)
Definition inifile.cpp:616
resources::ResourcePool & GetResourcePool()
Definition camp.hpp:266
NCString ResourceCategory
Definition camp.hpp:142
lang::resources::ResourcePool * resourcePool
Definition camp.hpp:98
config::Configuration & GetConfig()
Definition camp.hpp:231
config::Configuration * config
Definition camp.hpp:121
TPlugin * GetPlugin(integer number)
virtual void BootstrapBulk(const nchar *category,...)=0
ALIB_API void Reset()
virtual void bootstrap(BootstrapPhases phase) override
virtual void shutdown(ShutdownPhases phase) override
ALIB_API void Register(Lox *lox, lang::ContainerOp operation)
ALIB_API Lox * Get(const NString &name, lang::CreateIfNotExists create=lang::CreateIfNotExists::No)
static ALIB_API void ReplaceToReadable(AString &target, integer startIdx)
static ALIB_API detail::textlogger::TextLogger * DebugLogger
Definition log.inl:53
void Reset(bool reInitialze=true)
Definition lox.inl:234
const NString & GetName()
Definition lox.inl:170
TAString & ReplaceSubstring(const TString< TChar > &src, integer regionStart, integer regionLength)
Definition astring.hpp:1708
TAString & _(const TString< TChar > &src, integer regionStart, integer regionLength=MAX_LEN)
Definition astring.hpp:1056
integer IndexOf(TChar needle, integer startIdx=0) const
Definition string.hpp:889
TChar CharAt(integer idx) const
Definition string.hpp:437
#define ALIB_WARNING(...)
Definition alib.hpp:981
#define ALIB_BOXING_VTABLE_DEFINE(TMapped, Identifier)
Definition vtable.inl:490
#define A_CHAR(STR)
#define ALIB_ERROR(...)
Definition alib.hpp:980
#define ALIB_BOXING_BOOTSTRAP_VTABLE_DBG_REGISTER(Identifier)
Definition vtable.inl:506
#define ALIB_ASSERT_ERROR(cond,...)
Definition alib.hpp:984
#define ALIB_BOXING_BOOTSTRAP_REGISTER_FAPPEND_FOR_APPENDABLE_TYPE_N(TAppendable)
#define Log_RemoveDebugLogger()
Definition macros.inl:56
#define ALIB_CALLER_PRUNED
Definition alib.hpp:845
#define ALIB_COMMA
Definition alib.hpp:825
#define ALIB_LOCK_WITH(lock)
const T_EnumRecords< TEnum >::Type & GetRecord(TEnum element)
@ Exclude
Chooses exclusion.
@ Left
Chooses left alignment.
@ Yes
Create if something does not exist.
@ Remove
Denotes removals.
static ALIB_FORCE_INLINE void Destruct(T *object)
ALIB_API ThreadLock GlobalAllocatorLock
void ReleaseGlobalAllocator()
MonoAllocator GlobalAllocator(8 *1024)
MonoAllocator & AcquireGlobalAllocator(const NCString &dbgFile, int dbgLine, const NCString &dbgFunc)
Definition alib.cpp:57
ShutdownPhases
Definition camp.hpp:35
@ Destruct
The main phase of termination that destructs everything.
constexpr NCString NDefaultWhitespaces()
Definition cstring.hpp:566
BootstrapPhases
Definition camp.hpp:26
@ PrepareConfig
Initializes up to the creation of a field config .
@ Final
The final initialization phase.
lox::Scope Scope
Type alias in namespace alib.
lox::ALox ALOX
characters::character character
Type alias in namespace alib.
lox::Lox Lox
Type alias in namespace alib.
Definition lox.inl:1492
characters::nchar nchar
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:286
static void Bootstrap(TEnum element, TArgs &&... args) noexcept
static ALIB_API void Destruct(Lox *lox)
Definition loxpimpl.cpp:282
void operator()(TAString< TChar > &target, const TAppendable &src)