ALib C++ Library
Library Version: 2402 R1
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_ALOX_DETAIL_SCOPEINFO
9#define HPP_ALOX_DETAIL_SCOPEINFO 1
10
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#if !defined (HPP_ALIB_TIME_TICKS)
19 #include "alib/time/ticks.hpp"
20#endif
21
22#if !defined (HPP_ALIB_CAMP_DIRECTORY)
24#endif
25
26#if ALIB_THREADS && !defined (HPP_ALIB_THREADS_THREAD)
28#endif
29
30#if !defined (HPP_ALIB_MONOMEM_HASHMAP)
32#endif
33#if !defined (HPP_ALIB_MONOMEM_STDCONTAINERMA)
35#endif
36
37namespace alib {
38
39namespace config { class Variable; }
40namespace lox { namespace detail {
41
42
43struct LoxImpl;
44
45/** ************************************************************************************************
46 * Encapsulates information of the caller that can be collected. This is platform specific, in
47 * this case, C++. What we receive from the C++ preprocessor, is the source file name
48 * of the calling code, the line number within the source file name and the name of the method
49 * the call is placed in. E.g., wee do not get the class name of the object or even its instance.
50 *
51 * The method has a list of interface functions that gets such source information and some derived
52 * variants of it. In addition, thread and timer information is stored and managed.
53 *
54 * As far as possible, 'lazy' techniques come to practice with this class. This means, only
55 * the things that are queried in-between to invocations of method #Set are calculated.
56 *
57 * ## Friends ##
58 * class \alib{lox;Lox}
59 **************************************************************************************************/
61{
62 #if !defined(ALIB_DOX)
63 friend void LI::Reset(LoxImpl*, bool);
65 friend void LI::GetState( LoxImpl*, NAString&, StateInfo);
66 #endif
67
68 // #############################################################################################
69 // Types exposed
70 // #############################################################################################
71 public:
72#if ALIB_THREADS
73 /** A std::map we use to translate thread IDs to thread names */
75#endif
76
77 /**
78 * The number of source file path and corresponding, evaluated derived values.
79 * This might be modified, prior to creating any object of class \b Lox.<br>
80 * Defaults to 5.
81 */
83 static int DefaultCacheSize;
84
85 /** The name of the Lox we are attached to. */
87
88 // #############################################################################################
89 // Protected fields
90 // #############################################################################################
91 protected:
92 /** Defines portions of source paths to be ignored. */
94 {
95 NAString Path; ///< The path string
96 bool IsPrefix; ///< true if path was not starting with '\*' when provided.
97 lang::Inclusion IncludeString; ///< Denotes if #Path itself should be included when trimmed
98 lang::Case Sensitivity; ///< The sensitivity of the comparison when trimming
99 int TrimOffset; ///< Additional offset of the trim position
100 NAString TrimReplacement; ///< Optional replacement string for trimmed paths.
101 Priorities Priority; ///< The priority of the rule. Depends on origin: source code, config...)
102 };
103
104 /** List of trim definitions for portions of source paths to be ignored. */
106 static std::vector<SourcePathTrimRule> GlobalSPTRs;
107
108 /** List of trim definitions for portions of source paths to be ignored. */
109 std::vector<SourcePathTrimRule> LocalSPTRs;
110
111 /** Flag to determine if global rules have been read from config already. */
114
115 /**
116 * If true, next time a source path can not be trimmed successfully with custom
117 * trim information provided with
118 * \ref alib::lox::Lox::SetSourcePathTrimRule "Lox::SetSourcePathTrimRule"
119 * some trim information is automatically created by comparing such source file's path
120 * with the path of the executable of the current process.
121 */
123
124
125#if ALIB_THREADS
126 /** The thread passed with #Set. */
127 Thread* thread = nullptr;
128
129 /** The name of the thread that executed the log. */
131
132 /**
133 * Dictionary to translate thread IDs into something maybe nicer/shorter.
134 * The dictionary may be filled by the user of the library using \alox{Lox.MapThreadName}.
135 */
137#endif
138
139 /** Information of a single source file. Stored in field #cache. */
141 {
142 /** 'Timestamp' for LRU overwriting (not a time, but using field #cacheRun). */
143 uint64_t timeStamp = 0;
144
145 /** Path and name of source file (given by the C++ preprocessor). */
147
148 /** Full path of source file (evaluated). */
149 NString fullPath = nullptr;
150
151 /** Trimmed path of source file (evaluated). */
153
154 /** Prefix for the trimmed path taken from trim rule. Has to be added on writing
155 * the trimmed path **/
157
158 /** File name (evaluated). */
159 NString name = nullptr;
160
161 /** File name without extension (evaluated). */
163
164 /** Index of last path separator in #origFile. */
166
167 /** Clears calculated values. Keeps #origFile intact. */
168 void Clear()
169 {
171 fullPath= nullptr;
172 trimmedPath= nullptr;
173 name= nullptr;
174 nameWOExt= nullptr;
175 }
176 };
177
178
179 /** The 'timestamp' used to identify the LRU entry. Incremented, whenever a different source
180 file is evaluated. */
181 uint64_t cacheRun = 0;
182
183 /**
184 * The number of source file path and corresponding, evaluated derived values.
185 * Determined in the constructor by reading static field #DefaultCacheSize.
186 */
188
189 /** An array of source files. Its size is dependent on static field #DefaultCacheSize. */
191
192 /**
193 * Holds values for the current scope. Because recursive logging might occur (e.g. when
194 * parameters rely on method invocations which incorporate log statements), objects of this
195 * class are stored in stack #scopes.
196 */
197 struct Scope
198 {
199 /** Time of the call represented by this instance. */
201
202 /** The entry of the source file cache */
204
205 /** Line number within the source file (given by the C++ preprocessor) */
207
208 /** Function/method name (given by the C++ preprocessor) */
210 };
211
212 /** A stack of scopes (allows recursive calls/nested logging). */
213 std::vector<Scope,StdContMA<Scope>> scopes;
214
215 /** The current depth of recursive invocations. */
217
218 /** The last source file used. This is tried first with next invocation. If it does not
219 * match, the cache is searched for another matching one.*/
221
222
223 // #############################################################################################
224 // Constructor
225 // #############################################################################################
226 public:
227 /** ****************************************************************************************
228 * Constructs a scope info.
229 * @param name The name of the Lox that this object belongs to.
230 * Will be converted to upper case.
231 * @param allocator The monotonic allocator of "our" \b %Lox, used for long-term allocations
232 * @param tempVar A temporary variable for internal use.
233 ******************************************************************************************/
235 ScopeInfo( const NString& name, MonoAllocator* allocator, config::Variable& tempVar);
236
237 // #############################################################################################
238 // public interface
239 // #############################################################################################
240 public:
241 #if defined(ALIB_DOX)
242 /** ****************************************************************************************
243 * Stores C++ specific caller parameters and some other values like the time stamp.
244 * Also, flags thread information as not received, yet.
245 * Counts the recursion counter up.
246 * @param source Name, including path, of the source code file of the actual log
247 * invocation (__FILE__).
248 * @param lineNumber Line number within the source code file of the actual log
249 * invocation (__LINE__).
250 * @param method Name of method or function of the actual log invocation (mostly
251 * __func__/ __FUNCTION__).
252 * @param thread The thread. If \c nullptr, it will be determined if needed.
253 ******************************************************************************************/
255 void Set( const NCString& source, int lineNumber, const NCString& method,
257 #else
258 void Set( const NCString& source, int lineNumber, const NCString& method
260 #endif
261
262 /** ****************************************************************************************
263 * Releases latest scope information.
264 ******************************************************************************************/
265 void Release()
266 {
267 lastSourceFile= scopes[static_cast<size_t>(actScopeDepth)].sourceFile;
270 }
271
272
273 /** ****************************************************************************************
274 * Does the job for
275 * \ref alib::lox::Lox::SetSourcePathTrimRule "Lox::SetSourcePathTrimRule" and
276 * \ref alib::lox::Lox::ClearSourcePathTrimRules "Lox::ClearSourcePathTrimRules".
277 *
278 * @param path The path to search for. If not starting with <c> '*'</c>,
279 * a prefix is searched.
280 * @param includeString Determines if \p{path} should be included in the trimmed path or not.
281 * @param trimOffset Adjusts the portion of \p{path} that is trimmed. 999999 to clear!
282 * @param sensitivity Determines if the comparison of \p{path} with a source file's path
283 * is performed case sensitive or not.
284 * @param trimReplacement Replacement string for trimmed portion of the path.
285 * @param reach Denotes whether the rule is applied locally (to this \b %Lox only)
286 * or applies to all instances of class \b %Lox.
287 * Defaults to \b %Reach::Global.
288 * @param priority The priority of the setting.
289 ******************************************************************************************/
291 void SetSourcePathTrimRule( const NCString& path,
292 lang::Inclusion includeString,
293 int trimOffset,
294 lang::Case sensitivity,
295 const NString& trimReplacement,
296 lang::Reach reach,
297 Priorities priority );
298
299 /** ****************************************************************************************
300 * Receives the name of the \b Lox we are belonging to (this is a 1:1 relationship).
301 * @return The name of the \b Lox.
302 ******************************************************************************************/
304 {
305 return loxName;
306 }
307
308 /** ****************************************************************************************
309 * Receives the original filename and path of the source file
310 * (usually provided by the preprocessor).
311 * @return The full path and filename of the source file.
312 ******************************************************************************************/
314 {
315 return scopes[static_cast<size_t>(actScopeDepth)].sourceFile->origFile;
316 }
317
318 /** ****************************************************************************************
319 * Receives the path of the source file (not trimmed, see #GetTrimmedPath).
320 * @return The path of the source file.
321 ******************************************************************************************/
323 {
324 SourceFile* actual= scopes[static_cast<size_t>(actScopeDepth)].sourceFile;
325 if( actual->fullPath.IsNull() )
326 {
327 integer idx= getPathLength();
328 if( idx >= 0 )
329 actual->fullPath= NString( actual->origFile.Buffer(), idx );
330 else
331 actual->fullPath= "";
332 }
333
334 return actual->fullPath;
335 }
336
337 /** ****************************************************************************************
338 * Writes the path of the source file, trimmed according to trim-information provided
339 * with #SetSourcePathTrimRule or detected according to #AutoDetectTrimableSourcePath.
340 * @param target The target string to append the trimmed path to.
341 ******************************************************************************************/
342 void GetTrimmedPath( AString& target )
343 {
344 SourceFile* actual= scopes[static_cast<size_t>(actScopeDepth)].sourceFile;
345 if( actual->trimmedPath.IsNull() )
346 trimPath();
347
348 target._( actual->trimmedPathPrefix )
349 ._( actual->trimmedPath );
350 }
351
352 /** ****************************************************************************************
353 * Receives the source file name excluding the path (usually provided by the preprocessor).
354 * @return The source file name excluding the path
355 ******************************************************************************************/
357 {
358 SourceFile* actual= scopes[static_cast<size_t>(actScopeDepth)].sourceFile;
359 if( actual->name.IsNull() )
360 {
361 integer idx= getPathLength();
362 if( idx >= 0 )
363 {
365 actual->name= NString( actual->origFile.Buffer() + idx + 1,
366 actual->origFile.Length() - idx - 1 );
368 }
369 else
370 actual->name= "";
371 }
372 return actual->name;
373 }
374
375 /** ****************************************************************************************
376 * Receives the source file name excluding the path and without an extension
377 * (usually provided by the preprocessor).
378 * @return The source file name excluding the path and extension.
379 ******************************************************************************************/
381 {
382 SourceFile* actual= scopes[static_cast<size_t>(actScopeDepth)].sourceFile;
383 if( actual->nameWOExt.IsNull() )
384 {
385 actual->nameWOExt= GetFileName();
386 integer lastDot= actual->nameWOExt.LastIndexOf( '.' );
387 if ( lastDot > 0 )
388 actual->nameWOExt= NString( actual->nameWOExt.Buffer(), lastDot );
389 }
390 return actual->nameWOExt;
391 }
392
393
394 /** ****************************************************************************************
395 * Receives the method name (usually provided by the preprocessor).
396 * @return The method name.
397 ******************************************************************************************/
399 {
400 return scopes[static_cast<size_t>(actScopeDepth)].origMethod;
401 }
402
403 /** ****************************************************************************************
404 * Receives the source file line number (usually provided by the preprocessor).
405 * @return The source file line number.
406 ******************************************************************************************/
408 {
409 return scopes[static_cast<size_t>(actScopeDepth)].origLine;
410 }
411
412 /** ****************************************************************************************
413 * The timestamp of the last invocation of #Set.
414 * @return The latest timestamp.
415 ******************************************************************************************/
417 {
418 return scopes[static_cast<size_t>(actScopeDepth)].timeStamp;
419 }
420
421#if ALIB_THREADS
422 /** ************************************************************************************
423 * Receives the thread ID of the caller.
424 * @returns The thread ID.
425 **************************************************************************************/
427 {
428 if( thread == nullptr )
430 return thread->GetId();
431 }
432
433 /** ************************************************************************************
434 * Receives information about the thread that the current call was invoked with.
435 * @param id Output parameter receiving the \alib thread ID. If nullptr, it will be
436 * ignored.
437 * @returns The name of the current thread. The id is stored within the provided
438 * pointer.
439 **************************************************************************************/
441 {
442 if ( threadName.IsNull() )
443 {
444 // get current thread, if not passed with set()
445 if( thread == nullptr )
447
448 if (id != nullptr)
449 *id= thread->GetId();
450
451 // do we have a dictionary entry?
452 auto it= threadDictionary.Find( thread->GetId() );
453 if (it != threadDictionary.end() )
454 threadName= it->second;
455 else
457 }
458
459 return threadName;
460 }
461#endif
462
463 // #############################################################################################
464 // Internals
465 // #############################################################################################
466 protected:
467
468 /** ************************************************************************************
469 * Tries to trim the source file's path. Sets variable SourceFile::trimmedPath to either
470 * the successfully trimmed path or to the non-trimmed one. This way, it is executed
471 * only once, at it is 'lazily' invoked by #GetTrimmedPath()
472 **************************************************************************************/
474 void trimPath();
475
476 /** ************************************************************************************
477 * Gets position of path/filename separator. This is evaluated only once after an
478 * invocation of #Set.
479 * @return The index of the path separator in SourceFile::origFile.
480 **************************************************************************************/
482 {
483 SourceFile* actual= scopes[static_cast<size_t>(actScopeDepth)].sourceFile;
484 if( actual->origFilePathLength == -1 )
485 return -1;
487 }
488}; // class ScopeInfo
489
490}}} // namespace [alib::lox::detail]
491
492#endif // HPP_ALOX_DETAIL_SCOPEINFO
static ALIB_API int DefaultCacheSize
Definition scopeinfo.inl:83
const NCString & GetOrigFile()
std::vector< SourcePathTrimRule > LocalSPTRs
threads::ThreadID GetThreadID()
static ALIB_API std::vector< SourcePathTrimRule > GlobalSPTRs
ALIB_API ScopeInfo(const NString &name, MonoAllocator *allocator, config::Variable &tempVar)
Definition scopeinfo.cpp:54
static ALIB_API bool GlobalSPTRsReadFromConfig
const alib::String & GetThreadNameAndID(threads::ThreadID *id)
ThreadDictionary threadDictionary
ALIB_API void SetSourcePathTrimRule(const NCString &path, lang::Inclusion includeString, int trimOffset, lang::Case sensitivity, const NString &trimReplacement, lang::Reach reach, Priorities priority)
const NString GetFileNameWithoutExtension()
std::vector< Scope, StdContMA< Scope > > scopes
ALIB_API void Set(const NCString &source, int lineNumber, const NCString &method, threads::Thread *thread)
void GetTrimmedPath(AString &target)
Iterator Find(const KeyType &key)
TAString & _(const TString< TChar > &src, integer regionStart, integer regionLength=MAX_LEN)
Definition astring.hpp:1056
constexpr bool IsNull() const
Definition string.hpp:395
constexpr integer Length() const
Definition string.hpp:357
ALIB_WARNINGS_RESTORE integer LastIndexOf(TChar needle, integer startIndex=MAX_LEN) const
Definition string.hpp:1027
constexpr const TChar * Buffer() const
Definition string.hpp:350
static Thread * GetCurrent()
Definition thread.hpp:288
virtual ThreadID GetId()
Definition thread.hpp:217
virtual const CString GetName()
Definition thread.hpp:226
#define ALIB_IF_THREADS(...)
Definition alib.hpp:303
#define ALIB_WARNINGS_RESTORE
Definition alib.hpp:715
#define ALIB_API
Definition alib.hpp:538
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
Definition alib.hpp:644
#define ALIB_ASSERT(cond)
Definition alib.hpp:983
StateInfo
Definition lox.inl:40
integer ThreadID
Definition loxpimpl.inl:34
Definition alib.cpp:57
config::Variable Variable
Type alias in namespace alib.
Definition variable.hpp:839
constexpr nchar DirectorySeparator
strings::TString< nchar > NString
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:286
static ALIB_API void Reset(LoxImpl *impl, bool reInitialze=true)
Definition loxpimpl.cpp:379
static ALIB_API void GetState(LoxImpl *impl, NAString &buf, StateInfo flags)
static ALIB_API void MapThreadName(LoxImpl *impl, const String &threadName, threads::ThreadID id)
NAString TrimReplacement
Optional replacement string for trimmed paths.
int TrimOffset
Additional offset of the trim position.
Definition scopeinfo.inl:99
lang::Inclusion IncludeString
Denotes if Path itself should be included when trimmed.
Definition scopeinfo.inl:97
Priorities Priority
The priority of the rule. Depends on origin: source code, config...)
lang::Case Sensitivity
The sensitivity of the comparison when trimming.
Definition scopeinfo.inl:98
bool IsPrefix
true if path was not starting with '*' when provided.
Definition scopeinfo.inl:96