10# if !defined (HPP_ALIB_LANG_BASECAMP)
14# if !defined (HPP_ALOX_CONSOLE_LOGGER)
17# if !defined (HPP_ALOX_ANSI_LOGGER)
20# if !defined (HPP_ALOX_WINDOWS_CONSOLE_LOGGER)
24# if !defined(HPP_ALIB_ENUMS_SERIALIZATION)
27# if !defined (HPP_ALIB_LANG_COMMONENUMS)
30# if !defined (HPP_ALIB_STRINGS_UTIL_TOKENIZER)
33# if !defined (HPP_ALIB_STRINGS_FORMAT)
37#define HPP_ALIB_LOX_PROPPERINCLUDE
38# if !defined (HPP_ALOX_DETAIL_SCOPE)
41# if !defined (HPP_ALOX_DETAIL_SCOPEINFO)
45#undef HPP_ALIB_LOX_PROPPERINCLUDE
47#if !defined (HPP_ALIB_ALOXMODULE)
50#if !defined(HPP_ALIB_CAMP_MESSAGE_REPORT)
56 #define UNDEFINED_THREAD threads::UNDEFINED
58 #define UNDEFINED_THREAD 0
61namespace alib {
namespace lox {
namespace detail {
114 Search.
_( s, startPos, length );
149 int AcquirementsCount;
223 ,
Lock ( lang::Safeness::Safe )
225 , AcquirementsCount ( 0 )
256 return AcquirementsCount;
263#define ASSERT_ACQUIRED ALIB_ASSERT_ERROR ( impl->CountAcquirements() > 0, "ALOX", "Lox not acquired" )
272 #if ALIB_DEBUG_MONOMEM
315 ++impl->AcquirementsCount;
328 --impl->AcquirementsCount;
341 const NString internalDomainList[]= {
"LGR",
"DMN",
"PFX",
"THR",
"LGD",
"VAR" };
342 for (
auto& it : internalDomainList )
356 for(
int ruleNo= 0; ruleNo< variable.
Size(); ++ruleNo )
398 for (
int i=
static_cast<int>(domains->CountLoggers()) - 1 ; i >= 0 ; --i )
400 Logger* logger= domains->GetLogger( i );
401 int ii= internalDomains->GetLoggerNo( logger );
403 internalDomains->RemoveLogger( ii );
408 for (
int i=
static_cast<int>(internalDomains->CountLoggers()) - 1 ; i >= 0 ; --i )
410 Logger* logger= internalDomains->GetLogger( i );
419 if ( scopeDomains.globalStore.IsNotNull() )
420 delete[] scopeDomains.globalStore.Buffer();
424 for ( it.Initialize( scopeDomains.languageStore.Root() ); it.IsValid(); it.Next() )
425 if( it.Node().Value().IsNotNull() )
426 delete[] it.Node().Value().Buffer();
430 for (
auto& thread : scopeDomains.threadStore )
431 for (
auto& it : thread.second )
436 scopeDomains.Reset();
439 if ( scopePrefixes.globalStore )
440 delete static_cast<PrefixLogable*
>( scopePrefixes.globalStore );
444 for ( it.Initialize(scopePrefixes.languageStore.Root()); it.IsValid(); it.Next())
445 if( it.Node().Value() )
451 for (
auto& thread : scopePrefixes.threadStore )
452 for (
auto& it : thread.second )
457 scopePrefixes.Reset();
460 if ( scopeLogOnce.globalStore )
462 for(
auto mapEntry= scopeLogOnce.globalStore->begin();
463 mapEntry != scopeLogOnce.globalStore->end();
466 delete scopeLogOnce.globalStore;
471 for ( it.Initialize(scopeLogOnce.languageStore.Root()); it.IsValid(); it.Next() )
472 if( it.Node().Value() )
474 for(
auto mapEntry= it.Node().Value()->begin();
475 mapEntry != it.Node().Value()->end();
477 delete[] mapEntry->first.Buffer();
478 delete it.Node().Value();
484 for (
auto& it : scopeLogOnce.threadStore )
486 for(
auto mapEntry= it.second->begin();
487 mapEntry != it.second->end();
489 delete[] mapEntry->first.Buffer();
495 scopeLogOnce.
Reset();
498 if ( scopeLogData.globalStore )
500 for(
auto mapEntry= scopeLogData.globalStore->begin();
501 mapEntry != scopeLogData.globalStore->end();
503 delete[] mapEntry->first.Buffer();
504 delete scopeLogData.globalStore;
509 for ( it.Initialize(scopeLogData.languageStore.Root()); it.IsValid(); it.Next() )
510 if( it.Node().Value() != nullptr )
512 for(
auto mapEntry= it.Node().Value()->begin();
513 mapEntry != it.Node().Value()->end();
515 delete[] mapEntry->first.Buffer();
516 delete it.Node().Value();
522 for (
auto it : scopeLogData.threadStore )
524 for(
auto mapEntry= it.second->begin();
525 mapEntry != it.second->end();
527 delete[] mapEntry->first.Buffer();
535 scopeLogData .
Reset();
560 const NString& trimReplacement,
566 trimReplacement, reach, priority );
585 if ( (logger= impl->
domains ->
GetLogger( loggerName ) ) !=
nullptr )
return logger;
590 logables.
Add(
"No logger named {!Q} found.", loggerName );
603 for (
Domain& subDomain : domain.SubDomains )
604 verbositySettingToVariable( subDomain, loggerNo, var, tempBuf );
615 Variable variable( verbositiesDecl, replacements );
619 if ( variable.
Size() == 0 )
633 if (catSeparatorIdx >= 0 )
635 destVarCategory= firstArg.
Substring<
false>( 0 , catSeparatorIdx );
636 destVarName = firstArg.
Substring ( catSeparatorIdx + 1);
639 destVarName= firstArg;
644 logables.
Add(
"Argument 'writeback' in variable {!Q}.\n"
645 "Error: Wrong destination variable name format: {!Q}",
663 variable.
Declare( destVarCategory, destVarName, verbositiesDecl.
Delim );
667 << oldFullName <<
"\"." );
676 if ( loggerNoMainDom >= 0 ) verbositySettingToVariable( *impl->
domains , loggerNoMainDom, variable, tempBuf );
677 if ( loggerNoIntDom >= 0 ) verbositySettingToVariable( *impl->
internalDomains, loggerNoIntDom , variable, tempBuf );
687 logables.
Add(
"Argument 'writeback' in variable {!Q}:\n Verbosities for logger {!Q} written ",
688 oldFullName, logger->
GetName() );
691 logables.
Add(
"(to source variable)." );
693 logables.
Add(
"to variable {!Q}.", variable.
Fullname() );
700 logables.
Add(
" Value:");
701 for(
int i= 0; i< variable.
Size() ; ++i )
727 for(
int tokNo= 0; tokNo< variable.
Size(); ++tokNo )
740 enums::Parse<Verbosity>( tok, verbosity );
755 if( !enums::Parse<StateInfo>( tok, stateInfo ) )
770 logables.
Add(
"Unknown argument {!Q} in variable {} = {!Q}.",
777 LI::State( impl, domain, verbosity,
A_CHAR(
"Auto dump state on exit requested: "), flags );
789 if( noMainDom >= 0 || noIntDom >= 0 )
807 logables.
Add(
"Logger {!Q} not found. Nothing removed.", logger );
819 if( noMainDom >= 0 || noIntDom >= 0 )
836 logables.
Add(
"Logger {!Q} removed.", logger );
843 logables.
Add(
"Logger {!Q} not found. Nothing removed.", loggerName );
854 if ( logger ==
nullptr )
857 logables.
Add(
"Given Logger is \"null\". Verbosity not set." );
867 bool isNewLogger=
false;
877 .Add(
"Unable to add logger {!Q}. Logger with same name exists.", logger ) );
882 " Request was: SetVerbosity({!Q}, {!Q}, Verbosity::{}, {}). ",
883 logger, dom->
FullPath, verbosity, priority ) );
887 .Add(
" Existing Logger: {!Q}.", existingLogger ) );
916 logables.
Add(
"Logger {!Q}.", logger );
918 logables.
Add(
" added for internal log messages.");
920 logables.
Add(
" added.");
938 logables.
Add(
"Logger {!Q}: {!Fill}{!Q'}{!Fill}= Verbosity::{}.",
943 std::make_pair(verbosity, priority) );
946 if( actVerbosity != verbosity )
947 logables.
Add(
" Lower priority ({} < {}). Remains {}.",
962 int no= dom->GetLoggerNo( loggerName );
964 logger= dom->GetLogger( no );
975 logables.
Add(
"Logger not found. Request was: SetVerbosity({!Q}, {!Q}, Verbosity::{}, {}).",
976 loggerName, dom->FullPath, verbosity, priority );
1003 ThreadID threadID= thread !=
nullptr ? thread->
GetId() : UNDEFINED_THREAD;
1011 impl->
scopeDomains.InitAccess( scope, pathLevel, threadID );
1014 previousScopeDomain= impl->
scopeDomains.Remove( scopeDomain );
1024 previousScopeDomain= impl->
scopeDomains.Remove(
nullptr );
1029 if ( !removeNTRSD && scopeDomain.
IsNotEmpty() )
1031 logables.
Add(
"{!Q'} set as default for {}.", scopeDomain, (scope + pathLevel) );
1033 if ( previousScopeDomain ==
nullptr )
1037 if ( previousScopeDomain.
Equals<
false>( scopeDomain ) )
1039 logables.
Add(
" (Was already set.)" );
1044 logables.
Add(
" Replacing previous default {!Q'}.", previousScopeDomain );
1052 if ( previousScopeDomain !=
nullptr )
1054 logables.
Add(
"{!Q'} removed from {}.", previousScopeDomain, (scope + pathLevel) );
1060 logables.
Add(
"{!Q'} not found. Nothing removed for {}.", scopeDomain );
1062 logables.
Add(
"Empty Scope Domain given, nothing registered for {}.", scopeDomain);
1064 logables.
Add( scope + pathLevel);
1083 logables.
Add(
"Illegal parameter. No scope domain path given. Nothing removed for {}.",
1102 LI::logInternal( impl, Verbosity::Info,
"DMN",
"Domain substitution rules removed.");
1111 LI::logInternal( impl, Verbosity::Warning,
"DMN",
"Illegal domain substitution rule. Nothing stored." );
1119 if ( (*it).type == newRule.
type
1120 && (*it).Search.Equals<
false>( newRule.
Search ) )
1130 logables.
Add(
"Domain substitution rule {!Q} not found. Nothing to remove.", domainPath );
1135 logables.
Add(
"Domain substitution rule {!Q} -> {!Q} removed.", domainPath, (*it).Replacement );
1142 logables.
Add(
"Domain substitution rule {!Q} -> {!Q} set.", domainPath, newRule.
Replacement );
1148 msg <<
" Replacing previous -> \"" << (*it).Replacement <<
"\".";
1149 logables.
Add( msg );
1168 ThreadID threadID= thread !=
nullptr ? thread->
GetId() : UNDEFINED_THREAD;
1174 impl->
scopePrefixes.InitAccess( scope, pathLevel, threadID );
1175 bool isVoidOrEmpty= prefix.
IsType<
void>()
1184 logables.
Add(
"Object ");
1185 Verbosity intMsgVerbosity= Verbosity::Info;
1186 if ( !isVoidOrEmpty )
1188 logables.
Add( prefix,
" added as prefix logable for {}.", (scope + pathLevel) );
1190 if ( previousLogable !=
nullptr )
1194 logables.
Add(
" (Same as before.)");
1195 intMsgVerbosity= Verbosity::Verbose;
1198 logables.
Add(
" Replacing previous {}.", *previousLogable );
1203 if ( previousLogable !=
nullptr )
1204 logables.
Add(
"{!Q} removed from list of prefix logables for {}.", *previousLogable);
1207 logables.
Add(
"<nullptr> given but no prefix logable to remove for {}.");
1208 intMsgVerbosity= Verbosity::Warning;
1210 logables.
Add( scope + pathLevel );
1215 if ( previousLogable !=
nullptr )
1226 bool isVoidOrEmpty= prefix.
IsType<
void>()
1231 Verbosity intLogVerbosity= Verbosity::Info;
1234 if ( !isVoidOrEmpty )
1237 logables.
Add(
"Object {} added as prefix logable for ", prefix );
1239 dom->PrefixLogables.EmplaceBack(
new PrefixLogable( prefix ), otherPLs );
1243 auto qtyPLs= dom->PrefixLogables.
Size();
1246 removedLogable= dom->PrefixLogables.Back().first;
1247 dom->PrefixLogables.PopBack();
1248 logables.
Add(
"Object {} removed from list of prefix logables for",
1249 *
static_cast<Box*
>(removedLogable) );
1253 logables.
Add(
"No prefix logables to remove for" );
1254 intLogVerbosity= Verbosity::Warning;
1258 logables.
Add(
" domain {!Q'}.", dom->FullPath);
1261 if( removedLogable )
1262 delete removedLogable;
1266#if defined (__GLIBCXX__) || defined(__APPLE__) || defined(__ANDROID_NDK__)
1273#elif defined( _WIN32 )
1280 #pragma message "Unknown Platform in file: " __FILE__ )
1287 bool foundOne=
false;
1298 logables.
Add(
"Logger {!Q}: Start time set to ", logger->
GetName() );
1299 if ( !startTime.
IsSet() )
1302 logables.
Add(
"'now'" );
1308 if( asTextLogger !=
nullptr )
1312 logables.
Add(
"{:yyyy-MM-dd HH:mm:ss}", asDateTime );
1324 logables.
Add(
"Logger {!Q}: not found. Start time not set.", loggerName );
1345 origThreadName=
nullptr;
1352 logables.
Add(
"Mapped thread ID {} to {!Q}.",
id, threadName);
1353 if ( origThreadName.IsNotEmpty() )
1354 logables.
Add(
" Original thread name: {!Q}.", origThreadName );
1376 bool groupWasEmtpy= group.
IsEmpty();
1377 if ( groupWasEmtpy )
1380 if ( scope == Scope::Global )
1382 scope= Scope::Filename;
1394 impl->
scopeLogOnce.InitAccess( scope, pathLevel, UNDEFINED_THREAD );
1397 if( map ==
nullptr )
1399 map=
new std::map<NString, int>();
1404 auto it= map->find( group );
1405 if (it == map->end() )
1409 if ( quantity >= 0 )
1411 if ( it->second < quantity )
1420 if( it->second == quantity )
1423 logables.
Add(
"Once() reached limit of {} logs. No further logs for ", quantity );
1425 if ( groupWasEmtpy )
1426 logables.
Add( scope == Scope::Global ?
Box(
"this line" )
1427 :
Box(scope + pathLevel) );
1430 logables.
Add(
"group {!Q}", group );
1431 if ( scope != Scope::Global )
1432 logables.
Add(
" in ", (scope + pathLevel) );
1444 if ( it->second++ % -quantity == 0 )
1457 bool keyWasEmtpy= key.
IsEmpty();
1463 if ( scope > Scope::Path )
1465 pathLevel= UnderlyingIntegral( scope - Scope::Path );
1470 impl->
scopeLogData.InitAccess( scope, pathLevel, UNDEFINED_THREAD );
1472 if( map ==
nullptr )
1474 map=
new std::map<NString, Box>;
1481 auto it= map->find( key );
1482 if ( !data.
IsType<
void>() )
1484 bool replacedPrevious=
false;
1485 if ( it == map->end() )
1489 replacedPrevious=
true;
1494 logables.
Add(
"Stored data " );
1497 logables.
Add(
" with key {!Q} ", key );
1498 logables.
Add(
"in {}.", (scope + pathLevel) );
1499 if ( replacedPrevious )
1500 logables.
Add(
" (Replaced and deleted previous.)" );
1506 if ( it != map->end() )
1508 const nchar* keyBuffer= it->first.Buffer();
1510 if ( map->size() == 0 )
1515 delete [] keyBuffer;
1516 logables.
Add(
"Deleted map data " );
1519 logables.
Add(
"No map data found to delete " );
1522 logables.
Add(
" with key {!Q} ", key );
1523 logables.
Add(
"in {}.", (scope + pathLevel) );
1535 bool keyWasEmtpy= key.
IsEmpty();
1540 if ( scope > Scope::Path )
1542 pathLevel= UnderlyingIntegral( scope - Scope::Path );
1546 impl->
scopeLogData.InitAccess( scope, pathLevel, UNDEFINED_THREAD );
1548 for(
int i= 0; i < 2 ; ++i )
1551 if( map !=
nullptr )
1553 auto it= map->find( key );
1554 if ( it != map->end() )
1555 returnValue= it->second;
1558 if ( returnValue.
IsType<
void>() )
1566 logables.
Add(
"Data " );
1569 logables.
Add(
" with key {!Q} ", key );
1570 logables.
Add(
"in ", (scope + pathLevel), ( !returnValue.
IsType<
void>() ?
" received."
1571 :
" not found." ) );
1589 buf._<
false>( headLine ).
NewLine();
1602 while( static_cast<int>(impl->logableContainers.size()) < cntAcquirements )
1603 impl->logableContainers.emplace_back( impl->monoAllocator->Emplace<Boxes>(impl->monoAllocator) );
1604 Boxes& logables= *impl->logableContainers[static_cast<size_t>(cntAcquirements - 1)];
1609void LI::Entry(LoxImpl* impl, const NString& domain, Verbosity verbosity )
1613 // auto-initialization of debug loggers
1615 if( impl == Log::Get()->impl
1616 && impl->domains->CountLoggers() == 0
1617 && Log::DebugLogger == nullptr )
1618 Log::AddDebugLogger( Log::Get() );
1621 ALIB_ASSERT_ERROR(ALOX.IsBootstrapped(), "ALOX", "ALox (ALib) was not properly bootstrapped.
" )
1623 ++impl->CntLogCalls;
1625 if ( impl->domains->CountLoggers() == 0 )
1629 LI::evaluateResultDomain( impl, domain ),
1631 *impl->logableContainers[static_cast<size_t>(impl->CountAcquirements() - 1)],
1632 lang::Inclusion::Include );
1635int LI::IsActive( LoxImpl* impl, Verbosity verbosity, const NString& domain )
1639 // auto-initialization of debug loggers
1641 if( impl == Log::Get()->impl
1642 && impl->domains->CountLoggers() == 0
1643 && Log::DebugLogger == nullptr )
1644 Log::AddDebugLogger( Log::Get() );
1647 ALIB_ASSERT_ERROR(ALOX.IsBootstrapped(), "ALOX
", "ALox (ALib) was not properly bootstrapped.
" )
1649 if ( impl->domains->CountLoggers() == 0 )
1652 Domain* dom= LI::evaluateResultDomain( impl, domain );
1655 PrefixLogable marker(nullptr);
1656 for ( int i= 0; i < dom->CountLoggers() ; ++i )
1657 if( dom->IsActive( i, verbosity ) )
1662void LI::IncreaseLogCounter( LoxImpl* impl)
1664 ++impl->CntLogCalls;
1667void LI::entryDetectDomainImpl(LoxImpl* impl, Verbosity verbosity )
1669 Boxes& logables= *impl->logableContainers[static_cast<size_t>(impl->CountAcquirements() - 1)];
1670 if ( logables.Size() > 1 && logables[0].IsArrayOf<nchar>() )
1672 NString firstArg= logables[0].Unbox<NString>();
1674 // accept internal domain at the start
1676 if( firstArg.StartsWith( Lox::InternalDomains ) )
1677 idx+= Lox::InternalDomains.Length();
1679 // loop over domain and check for illegal characters
1680 bool illegalCharacterFound= false;
1681 for( ; idx< firstArg.Length() ; ++idx )
1683 char c= firstArg[idx];
1684 if (! ( isdigit( c )
1685 || ( c >= 'A' && c <= 'Z' )
1692 illegalCharacterFound= true;
1697 if ( illegalCharacterFound )
1699 LI::Entry( impl, nullptr, verbosity );
1703 logables.erase( logables.begin() );
1704 LI::Entry( impl, firstArg, verbosity );
1708 LI::Entry( impl, nullptr, verbosity );
1712// #################################################################################################
1714// #################################################################################################
1715Domain* LI::evaluateResultDomain(LoxImpl* impl, const NString& domainPath )
1717 NString128 resDomain;
1719 // 0. internal domain tree?
1720 if ( domainPath.StartsWith( Lox::InternalDomains ) )
1722 // cut "$/
" from the path
1723 resDomain._( domainPath, Lox::InternalDomains.Length() );
1724 return LI::findDomain( impl, *impl->internalDomains, resDomain );
1728 NString64 localPath; localPath.DbgDisableBufferReplacementWarning();
1729 impl->scopeDomains.InitWalk( Scope::ThreadInner,
1730 // we have to provide NullString if parameter is empty
1731 domainPath.IsNotEmpty() ? localPath._(domainPath)
1734 NString nextDefault;
1735 while( (nextDefault= impl->scopeDomains.Walk() ).IsNotNull() )
1737 ALIB_ASSERT( nextDefault.IsNotEmpty() )
1739 if ( resDomain.IsNotEmpty() )
1740 resDomain.InsertAt( "/
", 0);
1741 resDomain.InsertAt( nextDefault, 0 );
1743 // absolute path? That's it
1744 if ( resDomain.CharAtStart() == Domain::Separator() )
1748 return LI::findDomain( impl, *impl->domains, resDomain );
1751void LI::getVerbosityFromConfig(LoxImpl* impl, Logger* logger, Domain& dom )
1753 // get logger number. It may happen that the logger is not existent in this domain tree.
1754 int loggerNo= dom.GetLoggerNo( logger ) ;
1758 for( int varNo= 0; varNo< impl->tempVar.Size(); ++varNo )
1760 Tokenizer verbosityTknzr( impl->tempVar.GetString( varNo ), '=' );
1762 NString256 domainStrBuf;
1763 Substring domainStrParser= verbosityTknzr.Next();
1764 if ( domainStrParser.ConsumeString<lang::Case::Ignore>( A_CHAR("INTERNAL_DOMAINS
")) )
1766 while ( domainStrParser.ConsumeChar('/') )
1768 domainStrBuf << Lox::InternalDomains << domainStrParser;
1771 domainStrBuf._( domainStrParser );
1773 NSubstring domainStr= domainStrBuf ;
1775 Substring verbosityStr= verbosityTknzr.Next();
1776 if ( verbosityStr.IsEmpty() )
1780 if ( domainStr.ConsumeChar ( '*' ) ) searchMode+= 2;
1781 if ( domainStr.ConsumeCharFromEnd( '*' ) ) searchMode+= 1;
1782 if( ( searchMode == 0 && dom.FullPath.Equals <false,lang::Case::Ignore>( domainStr ) )
1783 || ( searchMode == 1 && dom.FullPath.StartsWith<true ,lang::Case::Ignore>( domainStr ) )
1784 || ( searchMode == 2 && dom.FullPath.EndsWith <true ,lang::Case::Ignore>( domainStr ) )
1785 || ( searchMode == 3 && dom.FullPath.IndexOf <true ,lang::Case::Ignore>( domainStr ) >=0 )
1788 Verbosity verbosity(Verbosity::Info);
1789 enums::Parse<Verbosity>(verbosityStr, verbosity );
1790 dom.SetVerbosity( loggerNo, verbosity, impl->tempVar.Priority() );
1795 ._<false>(
'\'' )._<
false>( dom.FullPath )
1797 ._(
"= Verbosity::" )
1798 ._( std::make_pair(verbosity, dom.GetPriority( loggerNo )) ).TrimEnd()
1808 Variable variable( Variables::PREFIXES,
1818 for(
int varNo= 0; varNo< variable.
Size(); ++varNo )
1831 domainStrBuf.
_( domainStrParser );
1843 prefixTokInner.
Next();
1844 if ( prefixTokInner.
Actual.IsNotEmpty() )
1848 if ( domainStr.
ConsumeChar (
'*' ) ) searchMode+= 2;
1859 NString128 msg; msg.
_<
false>(
"String \"" )._<false>( prefixStr ).
_<
false> (
"\" added as prefix logable for domain \'" )
1861 .
_<
false>(
"\'. (Retrieved from configuration variable" )
1862 ._<false>( variable.
Fullname() )._(
".)" );
1864 LI::logInternal( impl, Verbosity::Info,
"PFX", msg );
1872 LI::getVerbosityFromConfig( impl, logger, dom );
1876 LI::getAllVerbosities( impl, logger, subDomain );
1882 int maxSubstitutions= 10;
1891 dom= rootDomain.
Find( domainPath, 1, &wasCreated );
1899 Boxes& logables= LI::acquireInternalLogables(impl);
1900 logables.
Add(
"{!Q} registered.", dom->
FullPath );
1901 LI::logInternal( impl, Verbosity::Info,
"DMN", logables );
1910 Box replacements[2];
1914 replacements[0]= LI::GetName( impl );
1915 replacements[1]= logger->
GetName();
1918 LI::getVerbosityFromConfig( impl, logger, *dom );
1922 LI::getDomainPrefixFromConfig( impl, *dom );
1928 LI::logInternal( impl, Verbosity::Verbose,
"DMN",
" No loggers set, yet." );
1937 LI::logInternal( impl, Verbosity::Verbose,
"DMN", msg );
1949 while( maxSubstitutions-- > 0 )
1952 bool substituted=
false;
1957 case DomainSubstitutionRule::Type::StartsWith:
1971 substPath.
ReplaceSubstring<
false>( rule.Replacement, 0, rule.Search.Length() );
1978 case DomainSubstitutionRule::Type::EndsWith:
1990 if ( substPath.
EndsWith( rule.Search ) )
1992 substPath.
DeleteEnd( rule.Search.Length() )._( rule.Replacement );
2000 case DomainSubstitutionRule::Type::Substring:
2017 substPath.
ReplaceSubstring<
false>( rule.Replacement, idx, rule.Search.Length() );
2026 case DomainSubstitutionRule::Type::Exact:
2032 substPath.
_( rule.Replacement);
2039 if ( substPath.
Equals<
false>( rule.Search) )
2041 substPath.
Reset( rule.Replacement );
2059 if ( maxSubstitutions <= 0 && !impl->oneTimeWarningCircularDS )
2062 LI::logInternal( impl, Verbosity::Error,
"DMN",
2063 "The Limit of 10 domain substitutions was reached. Circular substitution assumed!"
2064 " (This error is only reported once!)" );
2068 if( substPath.
Length() > 0 )
2070 domainPath= substPath;
2082 if ( scope > Scope::Path )
2084 pathLevel= UnderlyingIntegral( scope - Scope::Path );
2092 Boxes& logables= LI::acquireInternalLogables(impl);
2093 logables.
Add(
"Missing scope information. Cant use {}.", (scope + pathLevel) );
2094 LI::logInternal( impl, Verbosity::Error, internalDomain, logables );
2103 if ( scope == Scope::ThreadOuter
2104 || scope == Scope::ThreadInner )
2107 Boxes& logables= LI::acquireInternalLogables(impl);
2108 logables.
Add(
"Illegal parameter, only Scope::ThreadOuter and Scope::ThreadInner allowed."
2109 " Given: {}.", scope );
2110 LI::logInternal( impl, Verbosity::Error,
"DMN", logables );
2115 "Illegal parameter, only Scope::ThreadOuter and Scope::ThreadInner allowed." );
2124 bool logablesCollected=
false;
2127 if( dom->
IsActive( i, verbosity ) )
2130 if ( !logablesCollected )
2132 logablesCollected=
true;
2133 impl->
scopePrefixes.InitWalk( Scope::ThreadInner, &marker );
2135 int qtyUserLogables=
static_cast<int>( logables.
Size() );
2136 int qtyThreadInners= -1;
2140 if( next != &marker )
2150 for (
int pfxI=
static_cast<int>(boxes->Size()) - 1 ; pfxI >= 0 ; --pfxI )
2151 logables.emplace( logables.begin() + ( qtyThreadInners < 0 ? qtyUserLogables : 0 ),
2152 (*boxes)[
static_cast<size_t>(pfxI)] );
2155 logables.emplace( logables.begin() + ( qtyThreadInners < 0 ? qtyUserLogables : 0 ), *next );
2162 bool excludeOthers=
false;
2163 qtyThreadInners=
static_cast<int>( logables.
Size() ) - qtyUserLogables;
2165 while ( pflDom !=
nullptr )
2174 for (
int pfxI=
static_cast<int>(boxes->Size()) - 1 ; pfxI >= 0 ; --pfxI )
2175 logables.emplace( logables.begin(),
2176 (*boxes)[
static_cast<size_t>(pfxI)] );
2179 logables.emplace( logables.begin(), prefix );
2184 excludeOthers=
true;
2189 pflDom= excludeOthers ? nullptr : pflDom->
Parent;
2195 for (
int ii= 0; ii < qtyThreadInners ; ++ii )
2196 logables.pop_back();
2206 logger->
Log( *dom, verbosity, logables, impl->
scopeInfo );
2232 Boxes& logables= LI::acquireInternalLogables(impl);
2233 logables.
Add( msg );
2234 LI::logInternal( impl, verbosity, subDomain, logables );
2237#if ALIB_DEBUG_MONOMEM
2245#if !defined(ALIB_DOX)
2254 buf.
InsertChars(
' ', maxDomainPathLength + 5 - idx + reference, idx);
2258 for (
Domain& subDomain : domain.SubDomains )
2259 getStateDomainRecursive( subDomain, maxDomainPathLength, buf );
2262void getStateDomainsWithDiffVerb(
Domain& dom,
int loggerNo, std::vector<Domain*>& results );
2263void getStateDomainsWithDiffVerb(
Domain& dom,
int loggerNo, std::vector<Domain*>& results )
2265 if ( dom.
Parent ==
nullptr
2267 results.emplace_back( &dom );
2269 for(
auto& it : dom.SubDomains )
2270 getStateDomainsWithDiffVerb( it, loggerNo, results );
2273void getStateCollectPrefixes( Domain& dom,
integer indentSpaces,
NAString& target );
2274void getStateCollectPrefixes( Domain& dom,
integer indentSpaces,
NAString& target )
2277 for (
auto& pfl : dom.PrefixLogables )
2282 buffer.
_( *
static_cast<Box*
>(pfl.first) );
2287 buffer.
_<
false>(
" (Excl.)" );
2289 buffer.
_<
false>(
"<domain> [" )._<false>( dom.FullPath ).
_<
false>(
']').
NewLine();
2293 for(
auto& subDom : dom.SubDomains )
2294 getStateCollectPrefixes( subDom, indentSpaces, target );
2309 if ( HasBits( flags, StateInfo::CompilationFlags ) )
2313 buf.
_<
false>(
"ALib Compiler Symbols:" ).
NewLine();
2328 if( alib::HasBits( flags, StateInfo::Basic ) )
2331 if( HasBits( flags, StateInfo::Version ) )
2339 if( HasBits( flags, StateInfo::Basic ) )
2342 if( HasBits( flags, StateInfo::Basic )
2343 || HasBits( flags, StateInfo::Version ) )
2347 if( HasBits( flags, StateInfo::SPTR ) )
2349 buf.
_<
false>(
"Source Path Trimming Rules: " ).
NewLine();
2353 for(
int trimInfoNo= 0; trimInfoNo < 2 ; ++trimInfoNo )
2356 std::vector<ScopeInfo::SourcePathTrimRule>* trimInfoList=
2357 trimInfoNo == 0 ? &ScopeInfo::GlobalSPTRs
2362 for (
auto& ti : *trimInfoList )
2365 buf.
_<
false>( trimInfoNo == 0 ?
" Global: "
2367 buf.
_<
false>( ti.IsPrefix ?
"\"" :
"\"*");
2368 buf.
_<
false>( ti.Path )._<false>(
"\", " );
2369 buf.
_<
false>( ti.IncludeString );
2370 if ( ti.TrimOffset != 0 )
2371 buf.
_<
false>( ti.Path )._<false>(
"\", Offset: " ).
_<
false>( ti.TrimOffset );
2372 buf.
_<
false>(
", Priority: " )._( ti.Priority );
2379 buf.
_<
false>(
" <no rules set>" ).
NewLine();
2384 if( HasBits( flags, StateInfo::DSR ) )
2386 buf.
_<
false>(
"Domain Substitution Rules: " ).
NewLine();
2392 if ( maxWidth < it.Search.Length() )
2393 maxWidth = it.Search.
Length();
2399 buf.
_<
false>(
" " );
2400 if ( it.type == DomainSubstitutionRule::Type::EndsWith
2401 || it.type == DomainSubstitutionRule::Type::Substring )
2402 buf.
_<
false>(
'*' );
2404 buf.
_<
false>( it.Search );
2405 if ( it.type == DomainSubstitutionRule::Type::StartsWith
2406 || it.type == DomainSubstitutionRule::Type::Substring )
2407 buf.
_<
false>(
'*' );
2411 .
_<
false>( it.Replacement );
2416 buf.
_<
false>(
" <no rules set>" ).
NewLine();
2421 if( HasBits( flags, StateInfo::Once ) )
2423 buf.
_<
false>(
"Once() Counters: " ).
NewLine();
2424 if ( scopeDump.writeStoreMap( &impl->
scopeLogOnce ) == 0 )
2425 buf.
_<
false>(
" <no Once() counters set>" ).
NewLine();
2430 if( HasBits( flags, StateInfo::LogData ) )
2432 buf.
_<
false>(
"Log Data: " ).
NewLine();
2433 if ( scopeDump.writeStoreMap( &impl->
scopeLogData ) == 0 )
2434 buf.
_<
false>(
" <no data objects stored>" ).
NewLine();
2439 if( HasBits( flags, StateInfo::PrefixLogables ) )
2441 buf.
_<
false>(
"Prefix Logables: " ).
NewLine();
2444 getStateCollectPrefixes( *impl->
domains, 2, buf );
2445 if ( oldLength == buf.
Length() )
2446 buf.
_<
false>(
" <no prefix logables set>" ).
NewLine();
2451 if( HasBits( flags, StateInfo::ThreadMappings ) )
2454 buf.
_<
false>(
"Named Threads: " ).
NewLine();
2456 buf.
_<
false>(
" <no thread name mappings set>" ).
NewLine();
2461 <<
'\"' << pair.second <<
'\"';
2469 if( HasBits( flags, StateInfo::ScopeDomains ) )
2471 buf.
_<
false>(
"Scope Domains: " ).
NewLine();
2472 if ( scopeDump.writeStore( &impl->
scopeDomains, 2 ) == 0 )
2473 buf.
_<
false>(
" <no scope domains set>" ).
NewLine();
2478 if( HasBits( flags, StateInfo::Loggers ) )
2481 std::vector<Domain*> domainsWithDiffVerb;
2482 for (
int treeNo= 0; treeNo < 2; ++treeNo )
2489 buf.
_<
false>(
"Loggers:" ).
NewLine();
2494 buf.
_<
false>(
"Loggers on Internal Domains:" ).
NewLine();
2497 for (
int loggerNo= 0; loggerNo< domTree->
CountLoggers(); ++loggerNo )
2504 buf.
_<
false>(
" " )._<false>( *logger ).
NewLine();
2505 buf.
_<
false>(
" Lines logged: " )._<false>( logger->
CntLogs ).
NewLine();
2513 domainsWithDiffVerb.clear();
2514 getStateDomainsWithDiffVerb( *domTree, loggerNo, domainsWithDiffVerb);
2515 for (
Domain* dom : domainsWithDiffVerb )
2518 ._( dom == *domainsWithDiffVerb.begin() ?
"Verbosities: "
2524 buf <<
"= " << std::make_pair(dom->GetVerbosity( loggerNo ), dom->GetPriority(loggerNo) )
2529 buf.
_<
false>(
" <no loggers attached>" ).
NewLine();
2535 if( HasBits( flags, StateInfo::InternalDomains ) )
2537 buf.
_<
false>(
"Internal Domains:" ).
NewLine();
2543 if( HasBits( flags, StateInfo::Domains ) )
2545 buf.
_<
false>(
"Domains:" ).
NewLine();
2561 Variable variable( Variables::CONSOLE_TYPE );
2566 val.
Equals<
false, lang::Case::Ignore>(
A_CHAR(
"default") ) )
goto DEFAULT;
2571 if( val.
Equals<
false, lang::Case::Ignore>(
A_CHAR(
"WINDOWS") ) )
2572 #if defined( _WIN32 )
2579 ALIB_WARNING(
"ALOX",
"Unrecognized value in config variable {!Q} = {!Q}.",
2584 #if defined( _WIN32 )
2598#undef UNDEFINED_THREAD
2599#undef ASSERT_ACQUIRED
integer UnboxLength() const
decltype(std::declval< typename TFDecl::Signature >()(std::declval< Box & >(), std::declval< TArgs >()...)) Call(TArgs &&... args) const
const TUnboxable Unbox() const
ALIB_API Priorities Load(Variable &variable)
ALIB_API Priorities Store(Variable &variable, const String &externalizedValue=nullptr)
void SetFmtHints(FormatHints hints)
void ReplaceFormatAttrAlignment(const String &newValue)
const String & FormatAttrAlignment() const
void ReplaceComments(const String &newValue)
FormatHints FmtHints() const
ALIB_API const String & Fullname()
void SetPriority(Priorities priority)
ALIB_API void Add(const String &value)
ALIB_API Variable & Declare(const VariableDecl &declaration, const Box &replacements)
const String & GetString(int idx=0)
Variable & ClearValues(int startIdx=0)
Priorities Priority() const
config::Configuration & GetConfig()
static Report & GetDefault()
ALIB_API void Set(const DateTime &timeStamp, lang::Timezone timezone=lang::Timezone::Local)
ALIB_API AString & Format(Substring format, AString &target, lang::CurrentData targetData=lang::CurrentData::Keep) const
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 void RemoveDebugLogger(Lox *lox)
static ALIB_API detail::textlogger::TextLogger * DebugLogger
static ALIB_FORCE_INLINE Lox * Get()
static constexpr NString InternalDomains
const NString & GetName()
Verbosity GetVerbosity(int loggerNo)
bool ConfigurationAlreadyRead
List< Domain > SubDomains
int AddLogger(detail::Logger *logger)
ALIB_API Verbosity SetVerbosity(int loggerNo, Verbosity verbosity, Priorities priority)
void ToString(NAString &target)
bool IsActive(int loggerNo, Verbosity statement)
Priorities GetPriority(int loggerNo)
void RemoveLogger(int loggerNo)
List< std::pair< PrefixLogable *, lang::Inclusion > > PrefixLogables
int GetLoggerNo(const NString &loggerName)
detail::Logger * GetLogger(const NString &loggerName)
ALIB_API Domain * Find(NSubstring domainPath, int maxCreate, bool *wasCreated)
virtual void AcknowledgeLox(LoxImpl *lox, lang::ContainerOp op)
const NString & GetName() const
time::Ticks TimeOfCreation
virtual void Log(Domain &dom, Verbosity verbosity, Boxes &logables, ScopeInfo &scope)=0
time::Ticks TimeOfLastLog
const NCString & GetOrigFile()
std::vector< SourcePathTrimRule > LocalSPTRs
const NString GetFullPath()
const NString GetFileName()
ThreadDictionary threadDictionary
const NCString GetMethod()
ALIB_API void SetSourcePathTrimRule(const NCString &path, lang::Inclusion includeString, int trimOffset, lang::Case sensitivity, const NString &trimReplacement, lang::Reach reach, Priorities priority)
std::vector< Scope, StdContMA< Scope > > scopes
const NString GetLoxName()
ALIB_API void Set(const NCString &source, int lineNumber, const NCString &method, threads::Thread *thread)
TickConverter DateConverter
textlogger::MetaInfo * MetaInfo
std::pair< Iterator, bool > EmplaceOrAssign(const KeyType &key, TArgs &&... args)
ALIB_FORCE_INLINE T * Emplace(TArgs &&... args)
static ALIB_API MonoAllocator * Create(size_t initialChunkSize, unsigned int chunkGrowthInPercent=200)
ALIB_API void Reset(const Snapshot &snapshot=Snapshot())
ALIB_API ~MonoAllocator()
TRecursiveIterator< false > RecursiveIterator
ALIB_API TAString & Trim(const TCString< TChar > &trimChars=TT_StringConstants< TChar >::DefaultWhitespaces())
TAString & DeleteEnd(integer regionLength)
TAString & ReplaceSubstring(const TString< TChar > &src, integer regionStart, integer regionLength)
TAString & InsertChars(TChar c, integer qty)
TAString & _(const TString< TChar > &src, integer regionStart, integer regionLength=MAX_LEN)
void DbgDisableBufferReplacementWarning()
ALIB_API void SetBuffer(integer newCapacity)
integer IndexOf(TChar needle, integer startIdx=0) const
constexpr bool IsEmpty() const
constexpr bool IsNotEmpty() const
constexpr integer Length() const
TChar CharAtStart() const
constexpr bool IsNotNull() const
TString< TChar > Substring(integer regionStart, integer regionLength=MAX_LEN) const
bool Equals(const TString< TChar > &rhs) const
bool EndsWith(const TString &needle) const
bool StartsWith(const TString &needle) const
TSubstring & Trim(const TCString< TChar > &whiteSpaces=TT_StringConstants< TChar >::DefaultWhitespaces())
bool ConsumeString(const TString< TChar > &consumable)
integer ConsumePartOf(const TString< TChar > &consumable, int minChars=1)
bool ConsumeCharFromEnd(TChar consumable)
ALIB_API TSubstring< TChar > & Next(lang::Whitespaces trimming=lang::Whitespaces::Trim, TChar newDelim='\0')
TSubstring< TChar > Actual
Thread * GetOwner() const
ALIB_API void Acquire(const NCString &dbgFile, int dbgLine, const NCString &dbgFunc)
lang::Safeness GetSafeness() const
int CountAcquirements() const
ALIB_API void Release()
defined(ALIB_DOX)
static Thread * GetCurrent()
virtual const CString GetName()
static ALIB_API DateTime FromFileTime(const FILETIME &fileTime)
static DateTime FromEpochSeconds(time_t epochSeconds)
Ticks ToTicks(DateTime dateTime)
DateTime ToDateTime(Ticks ticks)
void SetAs(const TDerived &other)
#define ALIB_WARNING(...)
#define ALIB_IF_THREADS(...)
#define ALIB_WARNINGS_RESTORE
#define ALIB_ASSERT_ERROR(cond,...)
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
#define ALIB_ASSERT_WARNING(cond,...)
#define ALIB_LOCK_WITH(lock)
#define ALIB_REL_DBG(releaseCode,...)
#define ALIB_CHARACTERS_WIDE
bool ParseEnumOrTypeBool(strings::TSubstring< TChar > &input, TEnum &result, TEnum falseValue, TEnum trueValue)
@ Exclude
Chooses exclusion.
@ Include
Chooses inclusion.
@ Trim
Trim whitespaces away.
@ On
Switch it on, switched on, etc.
@ Global
Denotes global reach.
@ Left
Chooses left alignment.
@ Remove
Denotes removals.
@ Insert
Denotes insertions.
static ALIB_FORCE_INLINE void Destruct(T *object)
strings::TString< TChar > AllocateCopy(const strings::TString< TChar > &src)
void DeleteString(const strings::TString< TChar > &string)
constexpr CString NewLine()
lang::basecamp::BaseCamp BASECAMP
void DbgCheckSingleThreaded()
LocalString< 32 > String32
Type alias name for TLocalString<character,32> .
ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE TCompilationFlags CompilationFlags
time::TickConverter TickConverter
Type alias in namespace alib.
LocalString< 256 > String256
Type alias name for TLocalString<character,256> .
constexpr NString NullNString()
characters::nchar nchar
Type alias in namespace alib.
boxing::Box Box
Type alias in namespace alib.
CompilationFlagMeaningsEntry CompilationFlagMeanings[30]
LocalString< 128 > String128
Type alias name for TLocalString<character,128> .
lang::integer integer
Type alias in namespace alib.
threads::ThreadID ThreadID
Type to store thread identifiers.
unsigned char bits[4]
The Flags.
@ EndsWith
Ends with match.
@ Substring
Any sub-string.
@ StartsWith
Starts with match.
NString32 Replacement
The replacement.
DomainSubstitutionRule(const NString &s, const NString &r)
NString32 Search
The path to search.
static ALIB_API void logInternal(LoxImpl *impl, Verbosity verbosity, const NString &subDomain, Boxes &msg)
static ALIB_API void writeVerbositiesOnLoggerRemoval(LoxImpl *impl, Logger *logger)
static ALIB_API void SetSourcePathTrimRule(LoxImpl *impl, const NCString &path, lang::Inclusion includeString, int trimOffset, lang::Case sensitivity, const NString &trimReplacement, lang::Reach reach, Priorities priority)
static ALIB_API void SetStartTime(LoxImpl *impl, Ticks startTime, const NString &loggerName)
static ALIB_API void SetDomainSubstitutionRule(LoxImpl *impl, const NString &domainPath, const NString &replacement)
static ALIB_API void setDomain(LoxImpl *impl, const NString &scopeDomain, Scope scope, bool removeNTRSD, threads::Thread *thread)
static ALIB_API detail::Logger * GetLogger(LoxImpl *impl, const NString &loggerName)
static ALIB_API void RemoveThreadDomain(LoxImpl *impl, const NString &scopeDomain, Scope scope, threads::Thread *thread)
static ALIB_API detail::Domain * evaluateResultDomain(LoxImpl *impl, const NString &domainPath)
static ALIB_API int checkScopeInformation(LoxImpl *impl, Scope &scope, const NString &internalDomain)
static ALIB_API bool RemoveLogger(LoxImpl *impl, detail::Logger *logger)
static ALIB_API void init(LoxImpl *impl)
static ALIB_API void store(LoxImpl *impl, const Box &data, const NString &pKey, Scope scope)
static ALIB_API void Release(LoxImpl *impl)
static ALIB_API void getAllVerbosities(LoxImpl *impl, detail::Logger *logger, detail::Domain &dom)
static ALIB_API Boxes & acquireInternalLogables(LoxImpl *impl)
static ALIB_API bool isThreadRelatedScope(LoxImpl *impl, Scope scope)
static ALIB_API void Construct(Lox *lox, const NString &name, bool doRegister)
static ALIB_API void Reset(LoxImpl *impl, bool reInitialze=true)
static ALIB_API Boxes & GetLogableContainer(LoxImpl *impl)
static ALIB_API void setPrefix(LoxImpl *impl, const Box &prefix, Scope scope, threads::Thread *thread)
static ALIB_API void GetState(LoxImpl *impl, NAString &buf, StateInfo flags)
static ALIB_API void MapThreadName(LoxImpl *impl, const String &threadName, threads::ThreadID id)
static ALIB_API void State(LoxImpl *impl, const NString &domain, Verbosity verbosity, const String &headLine, StateInfo flags)
static ALIB_API void dumpStateOnLoggerRemoval(LoxImpl *impl)
static ALIB_API void Destruct(Lox *lox)
static ALIB_API Box retrieve(LoxImpl *impl, const NString &pKey, Scope scope)
static ALIB_API integer & GetLogCounter(LoxImpl *impl)
static ALIB_API const NString & GetName(LoxImpl *impl)
static ALIB_API void SetDomain(LoxImpl *impl, const NString &scopeDomain, Scope scope, threads::Thread *thread)
static ALIB_API void Entry(LoxImpl *impl, const NString &domain, Verbosity verbosity)
static ALIB_API void once(LoxImpl *impl, const NString &domain, Verbosity verbosity, const Box &logables, const String &pGroup, Scope scope, int quantity)
static ALIB_API void Acquire(LoxImpl *impl, const NCString &file, int line, const NCString &func)
static ALIB_API void SetPrefix(LoxImpl *impl, const Box &prefix, const NString &domain, lang::Inclusion otherPLs)
static ALIB_API void SetVerbosity(LoxImpl *impl, detail::Logger *logger, Verbosity verbosity, const NString &domain, Priorities priority)
static ALIB_API threads::ThreadLock & getLock(LoxImpl *impl)
MonoAllocator::Snapshot initialSnapshot
bool oneTimeWarningCircularDS
ScopeStore< std::map< NString, Box > *, false > scopeLogData
MonoAllocator * monoAllocator
List< DomainSubstitutionRule > domainSubstitutions
LoxImpl(MonoAllocator *ma, const NString &name)
ScopeStore< NString, true > scopeDomains
ScopeStore< PrefixLogable *, true > scopePrefixes
integer maxLoggerNameLength
const alib::NString noKeyHashKey
ScopeStore< std::map< NString, int > *, false > scopeLogOnce
std::vector< Boxes *, StdContMA< Boxes * > > internalLogables
integer maxDomainPathLength
integer internalLogRecursionCounter
std::vector< Boxes *, StdContMA< Boxes * > > logableContainers
bool loggerAddedSinceLastDebugState