ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
scopeinfo.hpp
Go to the documentation of this file.
1//==================================================================================================
2/// \file
3/// This header-file is part of module \alib_alox of the \aliblong.
4///
5/// Copyright 2013-2026 A-Worx GmbH, Germany.
6/// Published under #"mainpage_license".
7//==================================================================================================
8ALIB_EXPORT namespace alib { namespace lox { namespace detail {
9
10//==================================================================================================
11/// Encapsulates information of the caller that can be collected. This is platform-specific, in
12/// this case, C++. What we receive from the C++ preprocessor is the source file name
13/// of the calling code, the line number within the source file name, and the name of the method
14/// the call is placed in.
15/// Furthermore, we collect the <c>std::type_info*</c> in case the call was not placed in a
16/// static or namespace function.
17///
18/// The method has a list of interface functions that gets such source information and some derived
19/// variants of it. In addition, thread and timer information is stored and managed.
20///
21/// As far as possible, 'lazy' techniques come to practice with this class. This means, only
22/// the things that are queried in-between to invocations of method #"Set" are calculated.
23///
24/// ## Friends ##
25/// class #"Lox"
26//==================================================================================================
27class ScopeInfo {
28 public:
29#if !ALIB_SINGLE_THREADED
30 /// A map we use to translate thread IDs to thread names
32#endif
33
34 //################################################################################################
35 // Protected fields
36 //################################################################################################
37 protected:
38 #if !DOXYGEN
39 friend struct LoxImpl;
41 friend void LI::GetState( LoxImpl*, NAString&, StateInfo);
42 #endif
43
44 /// Defines how source paths names are to be trimmed. \alox allows a set of global rules and
45 /// a set that is 'local', hence specific to a #"%Lox".
47 NAString Path; ///< The path string
48 NAString TrimReplacement; ///< Optional replacement string for trimmed paths.
49 int TrimOffset; ///< Additional offset of the trim position
50 lang::Inclusion IncludeString; ///< Denotes if #"Path" itself should be included when trimmed
51 lang::Case Sensitivity; ///< The sensitivity of the comparison when trimming
52 variables::Priority Priority; ///< The priority of the rule. Depends on origin: source code, config...)
53 bool IsPrefix; ///< \c true if path was not starting with <c>'*'</c>, when provided.
54 };
55
56 /// List of trim definitions for portions of source paths to be ignored.
57 ALIB_DLL static
58 std::vector<SourcePathTrimRule> GlobalSPTRs;
59
60 /// List of trim definitions for portions of source paths to be ignored.
61 std::vector<SourcePathTrimRule> LocalSPTRs;
62
63 /// Flag to determine if global rules have been read from config already.
64 ALIB_DLL static
66
67 /// If true, next time a source path cannot be trimmed successfully with custom
68 /// trim information provided with
69 /// #"alib::lox::Lox::SetSourcePathTrimRule;Lox::SetSourcePathTrimRule"
70 /// some trim information is automatically created by comparing such source file's path
71 /// with the path of the executable of the current process.
73
74 #if !ALIB_SINGLE_THREADED
75 /// The C++ native ID.
76 std::thread::id threadNativeIDx;
77
78 /// The thread passed with #"Set".
79 Thread* thread =nullptr;
80
81 /// The name of the thread that executed the log.
83
84 /// Dictionary to translate thread IDs into something maybe nicer/shorter.
85 /// The dictionary may be filled by the user of the library using #"Lox.MapThreadName".
87 #endif
88
89 /// Information of a single source file.
90 /// Stored in the field #"ScopeInfo::parsedFileNameCache;2".
92 /// Path and name of source file (given by the C++ preprocessor).
94
95 /// Full path of source file (evaluated).
96 NString fullPath =nullptr;
97
98 /// Trimmed path of source file (evaluated).
100
101 /// Prefix for the trimmed path taken from trim rule. Has to be added on writing
102 /// the trimmed path *
104
105 /// File name (evaluated).
106 NString name =nullptr;
107
108 /// File name without extension (evaluated).
110
111 /// Index of the last path separator in #".origFile".
113
114 /// Constructor.
115 /// @param filename Stored in #".origFile".
116 ParsedFileName( const NCString filename) : origFile(filename) {}
117 };
118
119 /// Serves as template parameter \p{TValueDescriptor} of the field
120 /// #"ScopeInfo::parsedFileNameCache;2".
121 struct ValueDescriptorPFN : containers::TSubsetKeyDescriptor<ParsedFileName, NCString> {
122 /// Provides access to the key-portion of the cached set.
123 /// @param src The cached element.
124 /// @return The key portion of the element.
125 NCString Key (ParsedFileName& src) const { return src.origFile; }
126 };
127
128 /// Least recently used cache of parsed file name.
130
131 /// Holds values for the current scope. Because recursive logging might occur (e.g., when
132 /// parameters rely on method invocations which incorporate log statements), objects of this
133 /// class are stored in stack #"ScopeInfo::callStack".
134 struct FrameRecord {
135 /// Time of the call that created this record.
137
138 /// The entry from the #"ScopeInfo::parsedFileNameCache;2".
140
141 /// Line number within the source file (given by the C++ preprocessor).
143
144 /// Function/method name (given by the C++ preprocessor).
146
147 /// Type information. Nullptr if call from static or global function.
148 const std::type_info* typeInfo;
149 };
150
151 /// A stack of scopes (allows recursive calls/nested logging).
153
154 /// The current depth of recursive invocations.
156
157 //################################################################################################
158 // Types exposed
159 //################################################################################################
160 public:
161 /// The name of the Lox we are attached to.
163
164
165 //################################################################################################
166 // Constructor
167 //################################################################################################
168 public:
169 /// Constructs a scope info.
170 /// @param name The name of the Lox that this object belongs to.
171 /// Will be converted to upper case.
172 /// @param allocator The monotonic allocator of "our" #"%Lox", used for long-term allocations
174 ScopeInfo( const NString& name, MonoAllocator& allocator);
175
176 //#################################################################################################
177 // public interface
178 //#################################################################################################
179 public:
180 /// Changes the capacity of the #"%LRUCacheTable" for parsed file names by calling
181 /// #"LRUCacheTable::Reserve;*".
182 /// @param numberOfLists The number of LRU-lists to use.
183 /// @param entriesPerList The maximum length of each cache list.
184 void SetFileNameCacheCapacity( integer numberOfLists, integer entriesPerList )
185 { parsedFileNameCache.Reserve( numberOfLists, entriesPerList ); }
186
187 /// Stores C++ specific caller parameters and some other values like the time stamp.
188 /// Also, flags thread information is not received, yet.
189 /// Counts the recursion counter up.
190 /// @param ci The caller information.
192 void Set( const lang::CallerInfo& ci );
193
194 /// Releases latest scope information.
196
197
198 /// Implements for #"Lox::SetSourcePathTrimRule;2" and #"Lox::ClearSourcePathTrimRules;2".
199 /// @param path The path to search for. If not starting with <c> '*'</c>,
200 /// a prefix is searched.
201 /// @param includeString Determines if \p{path} should be included in the trimmed path or not.
202 /// @param trimOffset Adjusts the portion of \p{path} that is trimmed. 999999 to clear!
203 /// @param sensitivity Determines if the comparison of \p{path} with a source file's path
204 /// is performed case-sensitive or not.
205 /// @param trimReplacement Replacement string for trimmed portion of the path.
206 /// @param reach Denotes whether the rule is applied locally (to this #"%Lox" only)
207 /// or applies to all instances of class #"%Lox".
208 /// Defaults to #"%Reach::Global".
209 /// @param priority The priority of the setting.
211 void SetSourcePathTrimRule( const NCString& path,
212 lang::Inclusion includeString,
213 int trimOffset,
214 lang::Case sensitivity,
215 const NString& trimReplacement,
216 lang::Reach reach,
217 Priority priority );
218
219 /// Receives the name of the #"%Lox" we are belonging to (this is a 1:1 relationship).
220 /// @return The name of the #"%Lox".
221 const NString GetLoxName() { return loxName; }
222
223 /// Receives the original filename and path of the source file
224 /// (usually provided by the preprocessor).
225 /// @return The full path and filename of the source file.
226 const NCString& GetOrigFile() { return callStack[size_t(callStackSize)].Parsed->origFile; }
227
228 /// Receives the path of the source file (not trimmed, see #".GetTrimmedPath").
229 /// @return The path of the source file.
231 auto& srcFile= *callStack[size_t(callStackSize)].Parsed;
232 if( srcFile.fullPath.IsNull() ) {
233 integer idx= getPathLength();
234 if( idx >= 0 )
235 srcFile.fullPath= NString( srcFile.origFile.Buffer(), idx );
236 else
237 srcFile.fullPath= "";
238 }
239
240 return srcFile.fullPath;
241 }
242
243 /// Writes the path of the source file, trimmed according to trim-information provided
244 /// with #".SetSourcePathTrimRule" or detected according to #".AutoDetectTrimableSourcePath".
245 /// @param target The target string to append the trimmed path to.
246 void GetTrimmedPath( AString& target ) {
247 auto& srcFile= *callStack[size_t(callStackSize)].Parsed;
248 if( srcFile.trimmedPath.IsNull() )
249 trimPath();
250
251 target._( srcFile.trimmedPathPrefix )
252 ._( srcFile.trimmedPath );
253 }
254
255 /// Receives the source file name excluding the path (usually provided by the preprocessor).
256 /// @return The source file name excluding the path
258 auto& srcFile= *callStack[size_t(callStackSize)].Parsed;
259 if( srcFile.name.IsNull() ) {
260 integer idx= getPathLength();
261 if( idx >= 0 )
262 srcFile.name= NString( srcFile.origFile.Buffer() + idx + 1,
263 srcFile.origFile.Length() - idx - 1 );
264 else
265 srcFile.name= "";
266 }
267 return srcFile.name;
268 }
269
270 /// Receives the source file name excluding the path and without an extension
271 /// (usually provided by the preprocessor).
272 /// @return The source file name excluding the path and extension.
274 auto& srcFile= *callStack[size_t(callStackSize)].Parsed;
275 if( srcFile.nameWOExt.IsNull() ) {
276 srcFile.nameWOExt= GetFileName();
277 integer lastDot= srcFile.nameWOExt.LastIndexOf( '.' );
278 if ( lastDot > 0 )
279 srcFile.nameWOExt= NString( srcFile.nameWOExt.Buffer(), lastDot );
280 }
281 return srcFile.nameWOExt;
282 }
283
284
285 /// Receives the method name (usually provided by the preprocessor).
286 /// @return The method name.
287 const NCString GetMethod() { return callStack[size_t(callStackSize)].origMethod; }
288
289 /// Receives the source file line number (usually provided by the preprocessor).
290 /// @return The source file line number.
291 int GetLineNumber() { return callStack[size_t(callStackSize)].origLine; }
292
293 /// The timestamp of the last invocation of #".Set".
294 /// @return The latest timestamp.
295 Ticks GetTimeStamp() { return callStack[size_t(callStackSize)].timeStamp; }
296
297 /// Receives the type information of the caller.
298 /// If called from global function or static method, this will be \c nullptr.
299 /// @returns The type information, if available.
300 const std::type_info* GetTypeInfo() { return callStack[size_t(callStackSize)].typeInfo; }
301
302#if !ALIB_SINGLE_THREADED
303 /// Receives the thread ID of the caller.
304 /// @returns The thread ID.
306 if( thread == nullptr )
308 return thread->GetID();
309 }
310
311 /// Receives the thread ID of the caller.
312 /// @returns The thread ID.
313 std::thread::id GetThreadNativeID() { return threadNativeIDx; }
314
315 /// Receives information about the thread that the current call was invoked with.
316 /// @param id Output parameter receiving the \alib thread ID. If nullptr, it will be
317 /// ignored.
318 /// @returns The name of the current thread. The id is stored within the provided
319 /// pointer.
321 if ( threadName.IsNull() ) {
322 // get current thread, if not passed with set()
323 if( thread == nullptr )
325
326 if (id != nullptr)
327 *id= thread->GetID();
328
329 // do we have a dictionary entry?
330 auto it= threadDictionary.Find( thread->GetID() );
331 if (it != threadDictionary.end() )
332 threadName= it->second;
333 else
334 threadName= thread->GetName();
335 }
336
337 return threadName;
338 }
339#endif
340
341 //################################################################################################
342 // Internals
343 //################################################################################################
344 protected:
345
346 /// Tries to trim the source file's path. Sets variable SourceFile::trimmedPath to either
347 /// the successfully trimmed path or to the non-trimmed one. This way, it is executed
348 /// only once, at it is 'lazily' invoked by #".GetTrimmedPath"
350 void trimPath();
351
352 /// Gets the position of path/filename separator. This is evaluated only once after an
353 /// invocation of #".Set".
354 /// @return The index of the path separator in SourceFile::origFile.
356 auto& srcFile= *callStack[size_t(callStackSize)].Parsed;
357 if( srcFile.origFilePathLength == -2 ) {
358 srcFile.origFilePathLength= srcFile.origFile.LastIndexOf( DIRECTORY_SEPARATOR );
359
360 // it may happen that the path separator of scope information is Unix-style while the
361 // platform is WindowsOS (e.g. with MinGW-cross compilation).
362 #if defined( _WIN32 )
363 if( srcFile.origFilePathLength == -1 )
364 srcFile.origFilePathLength= srcFile.origFile.LastIndexOf( '/' );
365 #endif
366 }
367 return srcFile.origFilePathLength;
368 }
369}; // class ScopeInfo
370
371}}} // namespace [alib::lox::detail]
#define ALIB_DLL
#define ALIB_ASSERT(cond, domain)
#define ALIB_EXPORT
static std::vector< SourcePathTrimRule > GlobalSPTRs
List of trim definitions for portions of source paths to be ignored.
Definition scopeinfo.hpp:58
const NString GetFileNameWithoutExtension()
const NCString & GetOrigFile()
const alib::String & GetThreadNameAndID(threads::ThreadID *id)
std::thread::id GetThreadNativeID()
StdVectorMA< FrameRecord > callStack
A stack of scopes (allows recursive calls/nested logging).
void GetTrimmedPath(AString &target)
threads::ThreadID GetThreadID()
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.
void SetFileNameCacheCapacity(integer numberOfLists, integer entriesPerList)
ThreadDictionary threadDictionary
Definition scopeinfo.hpp:86
void PopNestedScope()
Releases latest scope information.
HashMap< MonoAllocator, threads::ThreadID, String32 > ThreadDictionary
A map we use to translate thread IDs to thread names.
Definition scopeinfo.hpp:31
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
const std::type_info * GetTypeInfo()
TAString & _(const TAppendable &src)
static Thread * Get(std::thread::id nativeID)
Definition thread.cpp:253
Reach
Denotes the reach of something.
Case
Denotes upper and lower case character treatment.
Inclusion
Denotes how members of a set something should be taken into account.
integer ThreadID
The ALib thread identifier type.
Definition thread.hpp:23
Definition alox.cpp:14
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
strings::TString< nchar > NString
Type alias in namespace #"%alib".
Definition string.hpp:2174
containers::LRUCacheTable< TAllocator, TValueDescriptor, THash, TEqual > LRUCacheTable
Type alias in namespace #"%alib".
variables::Priority Priority
Type alias in namespace #"%alib".
threads::Thread Thread
Type alias in namespace #"%alib".
Definition thread.hpp:387
strings::TCString< nchar > NCString
Type alias in namespace #"%alib".
Definition cstring.hpp:408
strings::TAString< nchar, lang::HeapAllocator > NAString
Type alias in namespace #"%alib".
lang::integer integer
Type alias in namespace #"%alib".
Definition integers.hpp:149
containers::HashMap< TAllocator, TKey, TMapped, THash, TEqual, THashCaching, TRecycling > HashMap
Type alias in namespace #"%alib".
strings::TString< character > String
Type alias in namespace #"%alib".
Definition string.hpp:2165
time::Ticks Ticks
Type alias in namespace #"%alib".
Definition ticks.hpp:86
constexpr PathCharType DIRECTORY_SEPARATOR
The standard path separator character. Defaults to '\' on Windows OS, '/' else.
Definition path.hpp:63
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace #"%alib".
std::vector< T, StdMA< T > > StdVectorMA
Type alias in namespace #"%alib".
static void GetState(LoxImpl *impl, NAString &buf, StateInfo flags)
static void MapThreadName(LoxImpl *impl, const String &threadName, threads::ThreadID id)
Ticks timeStamp
Time of the call that created this record.
const std::type_info * typeInfo
Type information. Nullptr if call from static or global function.
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 name
File name (evaluated).
NString nameWOExt
File name without extension (evaluated).
integer origFilePathLength
Index of the last path separator in #".origFile".
NString fullPath
Full path of source file (evaluated).
Definition scopeinfo.hpp:96
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
NCString Key(ParsedFileName &src) const