ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
scopeinfo.cpp
1
2using namespace alib::system;
3
4namespace alib { namespace lox { namespace detail {
5
6//##################################################################################################
7// Static
8//##################################################################################################
9
10std::vector<ScopeInfo::SourcePathTrimRule> ScopeInfo::GlobalSPTRs;
12
13ScopeInfo::ScopeInfo( const NString& pName, MonoAllocator& allocator )
14#if !ALIB_SINGLE_THREADED
15: threadDictionary (allocator)
16,
17#else
18:
19#endif
20 parsedFileNameCache(allocator, 4, 6)
21, callStack (allocator)
22, loxName (allocator, pName)
23{
24 callStack.reserve(2);
25 characters::ToUpper( const_cast<char*>( loxName.Buffer() ), loxName.Length() );
26 ALIB_ASSERT_ERROR( !loxName.Equals<NC>( "GLOBAL" ), "ALOX",
27 "Name \"GLOBAL\" not allowed for Lox instances" )
28
29 IF_ALIB_THREADS( threadDictionary.EmplaceUnique(Thread::GetMain()->GetID(), "PROCESS" ); )
30
31 // read trim rules from config
32 // do 2 times, 0== local list, 1== global list
33 std::vector<SourcePathTrimRule>* trimInfoList;
34 for( int trimInfoNo= 0; trimInfoNo < 2 ; ++trimInfoNo )
35 { ALIB_LOCK_WITH(ALOX.GetConfig())
37
38 // check if done... or set list
39 if ( trimInfoNo == 0 ) {
40 trimInfoList= &LocalSPTRs;
41 ALIB_STRINGS_FROM_NARROW(loxName,sLoxName, 1024)
42 variable.Declare( Variables::SPTR_LOX, sLoxName );
43 } else {
45 continue;
47
48 trimInfoList= &GlobalSPTRs;
50 }
51
52 if( variable.IsDefined() ) {
53 Tokenizer tokOuter;
54 tokOuter.Set(variable, ';', true);
55 while(tokOuter.HasNext()) {
56 Tokenizer ruleTknzr( tokOuter.Next(), ',' );
57 trimInfoList->emplace_back();
58 SourcePathTrimRule& rule=trimInfoList->back();
59 rule.Priority= variable.GetPriority();
60
61 ruleTknzr.Next();
62 if( ( rule.IsPrefix= !ruleTknzr.Actual.StartsWith( A_CHAR("*") ) ) == false )
63 ruleTknzr.Actual.ConsumeChars(1);
64 rule.Path._( ruleTknzr.Actual );
65 if ( rule.Path.CharAtEnd() == '*' )
66 rule.Path.DeleteEnd( 1 );
67
68 if ( rule.Path.IsEmpty() ) {
69 trimInfoList->pop_back();
70 continue;
71 }
72
73 if constexpr( DIRECTORY_SEPARATOR == '/' )
74 rule.Path.SearchAndReplace( '\\', '/' );
75 else
76 rule.Path.SearchAndReplace( '/' , '\\' );
77
79 ruleTknzr.Next().ConsumeInt( rule.TrimOffset );
81
82 rule.TrimReplacement.Reset( ruleTknzr.Next() );
83} } } }
84
85void ScopeInfo::Set ( const lang::CallerInfo& ci ) {
87 ALIB_ASSERT( callStackSize < 8, "ALOX")
88 if( callStack.size() == size_t(callStackSize) )
89 callStack.emplace_back();
90
91 FrameRecord& scope= callStack[size_t(callStackSize)];
92
93 scope.timeStamp = Ticks::Now();
94 scope.origLine = ci.Line;
95 scope.origMethod= ci.Func;
96 auto resultPair = parsedFileNameCache.Try( ci.File ); // search file in cache
97 if( resultPair.first == false )
98 resultPair.second.Construct(ci.File);
99 scope.Parsed = &*resultPair.second;
100
101 // we must not use ci.ThreadID, because this might be nulled with release logging
102 IF_ALIB_THREADS( threadNativeIDx= std::this_thread::get_id();
103 thread = nullptr;
104 threadName = nullptr;
105 )
106}
107
109 lang::Inclusion includeString,
110 int trimOffset,
111 lang::Case sensitivity,
112 const NString& trimReplacement,
113 lang::Reach reach,
114 Priority priority ) {
115 // clear cache to have lazy variables reset with the next invocation
116 parsedFileNameCache.Clear();
117
118 // clear command
119 if ( trimOffset == 999999 ) {
120 LocalSPTRs.clear();
121 if ( reach == lang::Reach::Global )
122 GlobalSPTRs.clear();
124
125 // reset config read flag. This is done for unit testing. Not really useful/needed in real life.
127 return;
128 }
129
130 // choose local or global list
131 std::vector<SourcePathTrimRule>* trimInfoList=
133 : &LocalSPTRs;
134
135 // insert sorted by priority
136 auto it= trimInfoList->begin();
137 while( it != trimInfoList->end() && priority < it->Priority )
138 ++it;
139
140 it= trimInfoList->emplace(it);
141 SourcePathTrimRule& rule= *it;
142 rule.Priority= priority;
143
144 // if path starts with '*', it is not a prefix. We store without *
145 rule.Path._(path, (rule.IsPrefix= (path.CharAtStart() != '*') ) == true ? 0 : 1 );
146 if ( rule.Path.CharAtEnd() == '*' )
147 rule.Path.DeleteEnd( 1 );
148 if ( rule.Path.IsEmpty() ) {
149 trimInfoList->erase( it );
150 return;
151 }
152
153 if constexpr ( DIRECTORY_SEPARATOR == '/' )
154 rule.Path.SearchAndReplace( '\\', '/' );
155 else
156 rule.Path.SearchAndReplace( '/' , '\\' );
157
158 rule.IncludeString= includeString;
159 rule.TrimOffset= trimOffset;
160 rule.Sensitivity= sensitivity;
161 rule.TrimReplacement.Reset( trimReplacement );
162 if constexpr ( DIRECTORY_SEPARATOR == '/' )
163 rule.TrimReplacement.SearchAndReplace( '\\', '/' );
164 else
165 rule.TrimReplacement.SearchAndReplace( '/' , '\\' );
166}
167
168
170 bool trimmed= false;
171
172 ParsedFileName* actual= callStack[size_t(callStackSize)].Parsed;
173 integer idx= getPathLength();
174 if( idx < 0 ) {
175 actual->trimmedPath= "";
176 return;
177 }
178 actual->trimmedPath= NString( actual->origFile.Buffer(), idx );
179
180
181 // do 2 times, 0== local list, 1== global list
182 for( int trimInfoNo= 0; trimInfoNo < 2 ; ++trimInfoNo ) {
183 // choose local or global list
184 std::vector<SourcePathTrimRule>* trimInfoList=
185 trimInfoNo == 0 ? &LocalSPTRs
186 : &GlobalSPTRs;
187
188 // loop over trimInfo
189 for ( auto& ti : *trimInfoList ) {
190 if( ti.IsPrefix )
191 idx= ( ti.Sensitivity == lang::Case::Sensitive ? actual->trimmedPath.StartsWith<CHK,lang::Case::Sensitive>( ti.Path )
192 : actual->trimmedPath.StartsWith<CHK,lang::Case::Ignore >( ti.Path )
193 )
194
195 ? 0 : -1;
196 else
197 idx= ti.Sensitivity == lang::Case::Sensitive ? actual->trimmedPath.IndexOf<CHK, lang::Case::Sensitive>( ti.Path )
198 : actual->trimmedPath.IndexOf<CHK, lang::Case::Ignore >( ti.Path );
199 if ( idx >= 0 ) {
200 integer startIdx= idx + ( ti.IncludeString == lang::Inclusion::Include ? ti.Path.Length() : 0 ) + ti.TrimOffset;
201 actual->trimmedPath= actual->trimmedPath.Substring( startIdx, actual->trimmedPath.Length() - startIdx );
202 actual->trimmedPathPrefix= ti.TrimReplacement;
203
204 trimmed= true;
205 break;
206 } }
207
208 if (trimmed)
209 break;
210 }
211
212 // if nothing was found and the flag is still set, try once to auto-detect rule
213 // from the 'difference' of source path and current working directory
214 if( !trimmed && AutoDetectTrimableSourcePath ) {
215 AutoDetectTrimableSourcePath= false; // do this only once
216
217 // get system execution path and compare to file path
218 Path currentDir(SystemFolders::Current);
219
220 // Get the prefix that is the same in both paths
221 integer i= 0;
222 integer maxIdx= currentDir.Length();
223 if ( maxIdx > actual->trimmedPath.Length() )
224 maxIdx= actual->trimmedPath.Length();
225
226 while ( i < maxIdx && characters::ToUpper( currentDir[i] )
227 == characters::ToUpper( character(actual->trimmedPath[i]) ) )
228 ++i;
229
230 if ( i > 1 ) {
231 currentDir.ShortenTo( i );
232 NCString origFile= actual->origFile;
233 ALIB_PATH_TO_NARROW(currentDir,nCurrentDir,1024)
235 lang::Reach::Local, Priority::AutoDetected );
236 actual->origFile= origFile;
237 trimPath(); // one recursive call
238} } }
239
240
241}}} // namespace [alib::lox::detail]
#define IF_ALIB_THREADS(...)
#define A_CHAR(STR)
#define ALIB_ASSERT(cond, domain)
#define ALIB_ASSERT_ERROR(cond, domain,...)
#define ALIB_LOCK_WITH(lock)
static std::vector< SourcePathTrimRule > GlobalSPTRs
List of trim definitions for portions of source paths to be ignored.
Definition scopeinfo.hpp:58
StdVectorMA< FrameRecord > callStack
A stack of scopes (allows recursive calls/nested logging).
static bool GlobalSPTRsReadFromConfig
Flag to determine if global rules have been read from config already.
Definition scopeinfo.hpp:65
ScopeInfo(const NString &name, MonoAllocator &allocator)
Definition scopeinfo.cpp:13
void SetSourcePathTrimRule(const NCString &path, lang::Inclusion includeString, int trimOffset, lang::Case sensitivity, const NString &trimReplacement, lang::Reach reach, Priority priority)
NString loxName
The name of the Lox we are attached to.
ThreadDictionary threadDictionary
Definition scopeinfo.hpp:86
String threadName
The name of the thread that executed the log.
Definition scopeinfo.hpp:82
LRUCacheTable< MonoAllocator, ValueDescriptorPFN, std::hash< NString > > parsedFileNameCache
Least recently used cache of parsed file name.
Thread * thread
The thread passed with #"Set".
Definition scopeinfo.hpp:79
int callStackSize
The current depth of recursive invocations.
void Set(const lang::CallerInfo &ci)
Definition scopeinfo.cpp:85
std::vector< SourcePathTrimRule > LocalSPTRs
List of trim definitions for portions of source paths to be ignored.
Definition scopeinfo.hpp:61
std::thread::id threadNativeIDx
The C++ native ID.
Definition scopeinfo.hpp:76
integer SearchAndReplace(TChar needle, TChar replacement, integer startIdx=0, integer endIdx=strings::MAX_LEN)
TAString & DeleteEnd(integer regionLength)
TAString & ShortenTo(integer newLength)
Definition tastring.hpp:741
TAString & _(const TAppendable &src)
constexpr integer Length() const
Definition string.hpp:300
constexpr bool IsEmpty() const
Definition string.hpp:349
TChar CharAtStart() const
Definition string.hpp:417
integer IndexOf(TChar needle, integer startIdx=0) const
Definition string.hpp:799
constexpr const TChar * Buffer() const
Definition string.hpp:295
TChar CharAtEnd() const
Definition string.hpp:436
TString< TChar > Substring(integer regionStart, integer regionLength=MAX_LEN) const
Definition string.hpp:368
bool StartsWith(const TString &needle) const
Definition string.hpp:735
bool ConsumeInt(std::integral auto &result, TNumberFormat< TChar > *numberFormat=nullptr)
integer ConsumeChars(integer regionLength, TSubstring *target=nullptr)
void Set(const TString< TChar > &src, TChar delimiter, bool skipEmptyTokens=false)
TSubstring< TChar > Actual
Definition tokenizer.hpp:64
TSubstring< TChar > & Next(lang::Whitespaces trimming=lang::Whitespaces::Trim, TChar newDelim='\0')
Definition tokenizer.cpp:4
static Thread * GetMain()
Definition thread.cpp:252
Variable & Declare(const String &name, const String &typeName, const String &defaultValue=NULL_STRING)
Definition variable.cpp:163
TChar ToUpper(TChar c)
bool ParseEnumOrTypeBool(strings::TSubstring< TChar > &input, TEnum &result, TEnum falseValue, TEnum trueValue)
Reach
Denotes the reach of something.
@ Global
Denotes global reach.
@ Local
Denotes local reach.
Case
Denotes upper and lower case character treatment.
Inclusion
Denotes how members of a set something should be taken into account.
@ Exclude
Chooses exclusion.
@ Include
Chooses inclusion.
@ SPTR_GLOBAL
Denotes configuration variable #"alxcvALOX_GLOBAL_SOURCE_PATH_TRIM_RULES".
Definition aloxcamp.hpp:30
@ SPTR_LOX
Denotes configuration variable #"alxcvALOX_LOXNAME_SOURCE_PATH_TRIM_RULES" used by class #"Lox".
Definition aloxcamp.hpp:33
variables::Variable CampVariable(camp::Camp &camp)
Definition camp.hpp:283
Definition alox.cpp:14
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
strings::TString< nchar > NString
Type alias in namespace #"%alib".
Definition string.hpp:2174
constexpr NString NULL_NSTRING
A nulled string of the narrow character type.
Definition string.hpp:2256
variables::Priority Priority
Type alias in namespace #"%alib".
strings::TCString< nchar > NCString
Type alias in namespace #"%alib".
Definition cstring.hpp:408
variables::Variable Variable
Type alias in namespace #"%alib".
strings::util::TTokenizer< character > Tokenizer
Type alias in namespace #"%alib".
lox::ALoxCamp ALOX
The singleton instance of ALib Camp class #"ALoxCamp".
Definition aloxcamp.cpp:5
lang::integer integer
Type alias in namespace #"%alib".
Definition integers.hpp:149
system::Path Path
Type alias in namespace #"%alib".
Definition path.hpp:417
constexpr PathCharType DIRECTORY_SEPARATOR
The standard path separator character. Defaults to '\' on Windows OS, '/' else.
Definition path.hpp:63
characters::character character
Type alias in namespace #"%alib".
#define ALIB_STRINGS_FROM_NARROW( src, dest, bufSize)
See sibling type #"NC".
Definition chk_nc.hpp:30
const char * File
The name of the source file as given by compiler.
int Line
The line number within #".File".
Ticks timeStamp
Time of the call that created this record.
NCString origMethod
Function/method name (given by the C++ preprocessor).
ParsedFileName * Parsed
The entry from the #"ScopeInfo::parsedFileNameCache;2".
int origLine
Line number within the source file (given by the C++ preprocessor).
NCString origFile
Path and name of source file (given by the C++ preprocessor).
Definition scopeinfo.hpp:93
NString trimmedPath
Trimmed path of source file (evaluated).
Definition scopeinfo.hpp:99
int TrimOffset
Additional offset of the trim position.
Definition scopeinfo.hpp:49
lang::Inclusion IncludeString
Denotes if #"Path" itself should be included when trimmed.
Definition scopeinfo.hpp:50
variables::Priority Priority
The priority of the rule. Depends on origin: source code, config...).
Definition scopeinfo.hpp:52
bool IsPrefix
true if path was not starting with '*', when provided.
Definition scopeinfo.hpp:53
lang::Case Sensitivity
The sensitivity of the comparison when trimming.
Definition scopeinfo.hpp:51
NAString TrimReplacement
Optional replacement string for trimmed paths.
Definition scopeinfo.hpp:48
#define ALIB_PATH_TO_NARROW( src, dest, bufSize)