ALib C++ Library
Library Version: 2412 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
scopeinfo.inl
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/// \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8#ifndef HPP_ALIB_LOX_DETAIL_SCOPEINFO
9#define HPP_ALIB_LOX_DETAIL_SCOPEINFO 1
10#pragma once
11#if !defined(HPP_ALIB_LOX_PROPPERINCLUDE)
12# error "ALib sources with ending '.inl' must not be included from outside."
13#endif
14
15// #################################################################################################
16// includes
17// #################################################################################################
18#include "alib/time/ticks.hpp"
21#if ALIB_THREADS
23#endif
26
27namespace alib {
28
29namespace config { class Variable; }
30namespace lox { namespace detail {
31
32
33struct LoxImpl;
34
35//==================================================================================================
36/// Encapsulates information of the caller that can be collected. This is platform-specific, in
37/// this case, C++. What we receive from the C++ preprocessor is the source file name
38/// of the calling code, the line number within the source file name and the name of the method
39/// the call is placed in.
40/// Furthermore, we collect the <c>std::type_info*</c> in case the call was not placed in a
41/// static or namespace function.
42///
43/// The method has a list of interface functions that gets such source information and some derived
44/// variants of it. In addition, thread and timer information is stored and managed.
45///
46/// As far as possible, 'lazy' techniques come to practice with this class. This means, only
47/// the things that are queried in-between to invocations of method #Set are calculated.
48///
49/// ## Friends ##
50/// class \alib{lox;Lox}
51//==================================================================================================
53{
54 public:
55#if ALIB_THREADS
56 /// A map we use to translate thread IDs to thread names
58#endif
59
60 // ###############################################################################################
61 // Protected fields
62 // ###############################################################################################
63 protected:
64 #if !DOXYGEN
65 friend struct LoxImpl;
67 friend void LI::GetState( LoxImpl*, NAString&, StateInfo);
68 #endif
69
70 /// Defines how source paths names are to be trimmed. \alox allows a set of global rules and
71 /// a set that is 'local', hence specific to a \b Lox.
73 {
74 NAString Path; ///< The path string
75 NAString TrimReplacement; ///< Optional replacement string for trimmed paths.
76 int TrimOffset; ///< Additional offset of the trim position
77 lang::Inclusion IncludeString; ///< Denotes if #Path itself should be included when trimmed
78 lang::Case Sensitivity; ///< The sensitivity of the comparison when trimming
79 config::Priority Priority; ///< The priority of the rule. Depends on origin: source code, config...)
80 bool IsPrefix; ///< \c true if path was not starting with <c>'*'</c>, when provided.
81 };
82
83 /// List of trim definitions for portions of source paths to be ignored.
85 static std::vector<SourcePathTrimRule> GlobalSPTRs;
86
87 /// List of trim definitions for portions of source paths to be ignored.
88 std::vector<SourcePathTrimRule> LocalSPTRs;
89
90 /// Flag to determine if global rules have been read from config already.
93
94 /// If true, next time a source path cannot be trimmed successfully with custom
95 /// trim information provided with
96 /// \ref alib::lox::Lox::SetSourcePathTrimRule "Lox::SetSourcePathTrimRule"
97 /// some trim information is automatically created by comparing such source file's path
98 /// with the path of the executable of the current process.
100
101 #if ALIB_THREADS
102 /// The C++ native ID.
103 std::thread::id threadNativeIDx;
104
105 /// The thread passed with #Set.
106 Thread* thread = nullptr;
107
108 /// The name of the thread that executed the log.
110
111 /// Dictionary to translate thread IDs into something maybe nicer/shorter.
112 /// The dictionary may be filled by the user of the library using \alox{Lox.MapThreadName}.
114 #endif
115
116 /// Information of a single source file. Stored in field #parsedFileNameCache.
118 {
119 /// Path and name of source file (given by the C++ preprocessor).
121
122 /// Full path of source file (evaluated).
123 NString fullPath = nullptr;
124
125 /// Trimmed path of source file (evaluated).
127
128 /// Prefix for the trimmed path taken from trim rule. Has to be added on writing
129 /// the trimmed path *
131
132 /// File name (evaluated).
133 NString name = nullptr;
134
135 /// File name without extension (evaluated).
137
138 /// Index of last path separator in #origFile.
140
141 /// Constructor.
142 /// @param filename Stored in #origFile.
143 ParsedFileName( const NCString filename) : origFile(filename) {}
144 };
145
146 /// Serves as template parameter \p{TValueDescriptor} of field #parsedFileNameCache.
147 struct ValueDescriptorPFN : containers::TSubsetKeyDescriptor<ParsedFileName, NCString>
148 {
149 /// Provides access to the key-portion of the cached set.
150 /// @param src The cached element.
151 /// @return The key portion of the element.
152 NCString Key (ParsedFileName& src) const { return src.origFile; }
153 };
154
155 /// Least recently used cache of parsed file name.
157
158 /// Holds values for the current scope. Because recursive logging might occur (e.g., when
159 /// parameters rely on method invocations which incorporate log statements), objects of this
160 /// class are stored in stack #callStack.
162 {
163 /// Time of the call that created this record.
165
166 /// The entry from the #parsedFileNameCache
168
169 /// Line number within the source file (given by the C++ preprocessor)
171
172 /// Function/method name (given by the C++ preprocessor)
174
175 /// Type information. Nullptr if call from static or global function.
176 const std::type_info* typeInfo;
177 };
178
179 /// A stack of scopes (allows recursive calls/nested logging).
181
182 /// The current depth of recursive invocations.
184
185 // #############################################################################################
186 // Types exposed
187 // #############################################################################################
188 public:
189 /// The name of the Lox we are attached to.
191
192
193 // #############################################################################################
194 // Constructor
195 // #############################################################################################
196 public:
197 //==========================================================================================
198 /// Constructs a scope info.
199 /// @param name The name of the Lox that this object belongs to.
200 /// Will be converted to upper case.
201 /// @param allocator The monotonic allocator of "our" \b %Lox, used for long-term allocations
202 //==========================================================================================
204 ScopeInfo( const NString& name, MonoAllocator& allocator);
205
206 // #############################################################################################
207 // public interface
208 // #############################################################################################
209 public:
210 /// Changes the capacity of the \b %LRUCacheTable for parsed file names by calling
211 /// \alib{containers;LRUCacheTable::Reserve}.
212 /// @param numberOfLists The number of LRU-lists to use.
213 /// @param entriesPerList The maximum length of each cache list.
214 void SetFileNameCacheCapacity( integer numberOfLists, integer entriesPerList )
215 { parsedFileNameCache.Reserve( numberOfLists, entriesPerList ); }
216
217 //==========================================================================================
218 /// Stores C++ specific caller parameters and some other values like the time stamp.
219 /// Also, flags thread information as not received, yet.
220 /// Counts the recursion counter up.
221 /// @param ci The caller information.
222 //==========================================================================================
224 void Set( const lang::CallerInfo& ci );
225
226 /// Releases latest scope information.
228 {
231 }
232
233
234 //==========================================================================================
235 /// Does the job for
236 /// \ref alib::lox::Lox::SetSourcePathTrimRule "Lox::SetSourcePathTrimRule" and
237 /// \ref alib::lox::Lox::ClearSourcePathTrimRules "Lox::ClearSourcePathTrimRules".
238 ///
239 /// @param path The path to search for. If not starting with <c> '*'</c>,
240 /// a prefix is searched.
241 /// @param includeString Determines if \p{path} should be included in the trimmed path or not.
242 /// @param trimOffset Adjusts the portion of \p{path} that is trimmed. 999999 to clear!
243 /// @param sensitivity Determines if the comparison of \p{path} with a source file's path
244 /// is performed case-sensitive or not.
245 /// @param trimReplacement Replacement string for trimmed portion of the path.
246 /// @param reach Denotes whether the rule is applied locally (to this \b %Lox only)
247 /// or applies to all instances of class \b %Lox.
248 /// Defaults to \b %Reach::Global.
249 /// @param priority The priority of the setting.
250 //==========================================================================================
252 void SetSourcePathTrimRule( const NCString& path,
253 lang::Inclusion includeString,
254 int trimOffset,
255 lang::Case sensitivity,
256 const NString& trimReplacement,
257 lang::Reach reach,
258 Priority priority );
259
260 //==========================================================================================
261 /// Receives the name of the \b Lox we are belonging to (this is a 1:1 relationship).
262 /// @return The name of the \b Lox.
263 //==========================================================================================
265 {
266 return loxName;
267 }
268
269 //==========================================================================================
270 /// Receives the original filename and path of the source file
271 /// (usually provided by the preprocessor).
272 /// @return The full path and filename of the source file.
273 //==========================================================================================
275 {
276 return callStack[size_t(callStackSize)].Parsed->origFile;
277 }
278
279 //==========================================================================================
280 /// Receives the path of the source file (not trimmed, see #GetTrimmedPath).
281 /// @return The path of the source file.
282 //==========================================================================================
284 {
285 auto& srcFile= *callStack[size_t(callStackSize)].Parsed;
286 if( srcFile.fullPath.IsNull() )
287 {
288 integer idx= getPathLength();
289 if( idx >= 0 )
290 srcFile.fullPath= NString( srcFile.origFile.Buffer(), idx );
291 else
292 srcFile.fullPath= "";
293 }
294
295 return srcFile.fullPath;
296 }
297
298 //==========================================================================================
299 /// Writes the path of the source file, trimmed according to trim-information provided
300 /// with #SetSourcePathTrimRule or detected according to #AutoDetectTrimableSourcePath.
301 /// @param target The target string to append the trimmed path to.
302 //==========================================================================================
303 void GetTrimmedPath( AString& target )
304 {
305 auto& srcFile= *callStack[size_t(callStackSize)].Parsed;
306 if( srcFile.trimmedPath.IsNull() )
307 trimPath();
308
309 target._( srcFile.trimmedPathPrefix )
310 ._( srcFile.trimmedPath );
311 }
312
313 //==========================================================================================
314 /// Receives the source file name excluding the path (usually provided by the preprocessor).
315 /// @return The source file name excluding the path
316 //==========================================================================================
318 {
319 auto& srcFile= *callStack[size_t(callStackSize)].Parsed;
320 if( srcFile.name.IsNull() )
321 {
322 integer idx= getPathLength();
323 if( idx >= 0 )
324 {
326 srcFile.name= NString( srcFile.origFile.Buffer() + idx + 1,
327 srcFile.origFile.Length() - idx - 1 );
329 }
330 else
331 srcFile.name= "";
332 }
333 return srcFile.name;
334 }
335
336 //==========================================================================================
337 /// Receives the source file name excluding the path and without an extension
338 /// (usually provided by the preprocessor).
339 /// @return The source file name excluding the path and extension.
340 //==========================================================================================
342 {
343 auto& srcFile= *callStack[size_t(callStackSize)].Parsed;
344 if( srcFile.nameWOExt.IsNull() )
345 {
346 srcFile.nameWOExt= GetFileName();
347 integer lastDot= srcFile.nameWOExt.LastIndexOf( '.' );
348 if ( lastDot > 0 )
349 srcFile.nameWOExt= NString( srcFile.nameWOExt.Buffer(), lastDot );
350 }
351 return srcFile.nameWOExt;
352 }
353
354
355 //==========================================================================================
356 /// Receives the method name (usually provided by the preprocessor).
357 /// @return The method name.
358 //==========================================================================================
360 {
361 return callStack[size_t(callStackSize)].origMethod;
362 }
363
364 //==========================================================================================
365 /// Receives the source file line number (usually provided by the preprocessor).
366 /// @return The source file line number.
367 //==========================================================================================
369 {
370 return callStack[size_t(callStackSize)].origLine;
371 }
372
373 //==========================================================================================
374 /// The timestamp of the last invocation of #Set.
375 /// @return The latest timestamp.
376 //==========================================================================================
378 {
379 return callStack[size_t(callStackSize)].timeStamp;
380 }
381
382 //==========================================================================================
383 /// Receives the type information of the caller.
384 /// If called from global function or static method, this will be \c nullptr.
385 /// @returns The type information, if available.
386 //==========================================================================================
387 const std::type_info* GetTypeInfo()
388 {
389 return callStack[size_t(callStackSize)].typeInfo;
390 }
391
392#if ALIB_THREADS
393 //==========================================================================================
394 /// Receives the thread ID of the caller.
395 /// @returns The thread ID.
396 //==========================================================================================
398 {
399 if( thread == nullptr )
401 return thread->GetID();
402 }
403
404 //==========================================================================================
405 /// Receives the thread ID of the caller.
406 /// @returns The thread ID.
407 //==========================================================================================
408 std::thread::id GetThreadNativeID() { return threadNativeIDx; }
409
410 //==========================================================================================
411 /// Receives information about the thread that the current call was invoked with.
412 /// @param id Output parameter receiving the \alib thread ID. If nullptr, it will be
413 /// ignored.
414 /// @returns The name of the current thread. The id is stored within the provided
415 /// pointer.
416 //==========================================================================================
418 {
419 if ( threadName.IsNull() )
420 {
421 // get current thread, if not passed with set()
422 if( thread == nullptr )
424
425 if (id != nullptr)
426 *id= thread->GetID();
427
428 // do we have a dictionary entry?
429 auto it= threadDictionary.Find( thread->GetID() );
430 if (it != threadDictionary.end() )
431 threadName= it->second;
432 else
434 }
435
436 return threadName;
437 }
438#endif
439
440 // #############################################################################################
441 // Internals
442 // #############################################################################################
443 protected:
444
445 //==========================================================================================
446 /// Tries to trim the source file's path. Sets variable SourceFile::trimmedPath to either
447 /// the successfully trimmed path or to the non-trimmed one. This way, it is executed
448 /// only once, at it is 'lazily' invoked by #GetTrimmedPath()
449 //==========================================================================================
451 void trimPath();
452
453 //==========================================================================================
454 /// Gets position of path/filename separator. This is evaluated only once after an
455 /// invocation of #Set.
456 /// @return The index of the path separator in SourceFile::origFile.
457 //==========================================================================================
459 {
460 auto& srcFile= *callStack[size_t(callStackSize)].Parsed;
461 if( srcFile.origFilePathLength == -2 )
462 srcFile.origFilePathLength= srcFile.origFile.LastIndexOf( lang::system::DIRECTORY_SEPARATOR );
463 return srcFile.origFilePathLength;
464 }
465}; // class ScopeInfo
466
467}}} // namespace [alib::lox::detail]
468
469#endif // HPP_ALIB_LOX_DETAIL_SCOPEINFO
470
Iterator Find(const KeyType &key)
NString loxName
The name of the Lox we are attached to.
const NCString & GetOrigFile()
std::vector< SourcePathTrimRule > LocalSPTRs
List of trim definitions for portions of source paths to be ignored.
Definition scopeinfo.inl:88
StdVectorMono< FrameRecord > callStack
A stack of scopes (allows recursive calls/nested logging).
threads::ThreadID GetThreadID()
static ALIB_API std::vector< SourcePathTrimRule > GlobalSPTRs
List of trim definitions for portions of source paths to be ignored.
Definition scopeinfo.inl:85
static ALIB_API bool GlobalSPTRsReadFromConfig
Flag to determine if global rules have been read from config already.
Definition scopeinfo.inl:92
const alib::String & GetThreadNameAndID(threads::ThreadID *id)
void SetFileNameCacheCapacity(integer numberOfLists, integer entriesPerList)
ThreadDictionary threadDictionary
std::thread::id GetThreadNativeID()
Thread * thread
The thread passed with Set.
ALIB_API void Set(const lang::CallerInfo &ci)
std::thread::id threadNativeIDx
The C++ native ID.
int callStackSize
The current depth of recursive invocations.
const NString GetFileNameWithoutExtension()
void PopNestedScope()
Releases latest scope information.
ALIB_API void SetSourcePathTrimRule(const NCString &path, lang::Inclusion includeString, int trimOffset, lang::Case sensitivity, const NString &trimReplacement, lang::Reach reach, Priority priority)
String threadName
The name of the thread that executed the log.
const std::type_info * GetTypeInfo()
void GetTrimmedPath(AString &target)
LRUCacheTable< MonoAllocator, ValueDescriptorPFN, std::hash< NString > > parsedFileNameCache
Least recently used cache of parsed file name.
ALIB_API ScopeInfo(const NString &name, MonoAllocator &allocator)
Definition scopeinfo.cpp:38
TAString & _(const TString< TChar > &src, integer regionStart, integer regionLength=MAX_LEN)
constexpr bool IsNull() const
Definition string.hpp:364
virtual const CString GetName() const
Definition thread.hpp:225
ThreadID GetID() const
Definition thread.hpp:207
static ALIB_API Thread * Get(std::thread::id nativeID)
Definition thread.cpp:321
#define ALIB_WARNINGS_RESTORE
Definition alib.hpp:849
#define ALIB_API
Definition alib.hpp:639
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
Definition alib.hpp:760
#define ALIB_ASSERT(cond)
Definition alib.hpp:1270
static constexpr PathCharType DIRECTORY_SEPARATOR
The standard path separator character. Defaults to '\' on Windows OS, '/' else.
Definition path.hpp:99
Inclusion
Denotes how members of a set something should be taken into account.
Reach
Denotes the reach of something.
Case
Denotes upper and lower case character treatment.
StateInfo
Definition lox.inl:25
integer ThreadID
The ALib thread identifier type.
Definition loxpimpl.inl:28
Definition alib.cpp:69
std::vector< T, SCAMono< T > > StdVectorMono
Type alias in namespace alib.
Definition stdvector.hpp:21
strings::TString< nchar > NString
Type alias in namespace alib.
config::Variable Variable
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:273
static ALIB_API void GetState(LoxImpl *impl, NAString &buf, StateInfo flags)
static ALIB_API void MapThreadName(LoxImpl *impl, const String &threadName, threads::ThreadID id)
Ticks timeStamp
Time of the call that created this record.
ParsedFileName * Parsed
The entry from the parsedFileNameCache.
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)
int origLine
Line number within the source file (given by the C++ preprocessor)
Information of a single source file. Stored in field parsedFileNameCache.
NCString origFile
Path and name of source file (given by the C++ preprocessor).
integer origFilePathLength
Index of last path separator in origFile.
NString nameWOExt
File name without extension (evaluated).
NString trimmedPath
Trimmed path of source file (evaluated).
NString name
File name (evaluated).
NString fullPath
Full path of source file (evaluated).
NAString TrimReplacement
Optional replacement string for trimmed paths.
Definition scopeinfo.inl:75
int TrimOffset
Additional offset of the trim position.
Definition scopeinfo.inl:76
lang::Inclusion IncludeString
Denotes if Path itself should be included when trimmed.
Definition scopeinfo.inl:77
lang::Case Sensitivity
The sensitivity of the comparison when trimming.
Definition scopeinfo.inl:78
config::Priority Priority
The priority of the rule. Depends on origin: source code, config...)
Definition scopeinfo.inl:79
bool IsPrefix
true if path was not starting with '*', when provided.
Definition scopeinfo.inl:80
Serves as template parameter TValueDescriptor of field parsedFileNameCache.
NCString Key(ParsedFileName &src) const