In C++ and C#, ALox collects information about the source file name and this information by default includes the full file path. This chapter is addressing ALox for C++ and ALox for C# users only.
To collect the path information, in C++ the preprocessor macro __FILE__
is used when invoking Log Statements. In C#, some mechanics of namespace System.Runtime.CompilerServices
are leveraged.
The source file name and path information received is used in two ways:
Source file paths can become quite long and for different reasons, it might be wanted remove a redundant or irrelevant prefix from the it.
ALox provides a mechanism to trim the path of source files by using a set of rules.
Internally, different lists of such 'Source Path Trim Rules' are maintained. One is a static table, which stores trim information used by all instances of class Lox. In addition, each Lox has an own, private set of Source Path Trim Rules. The advantage of having the static, global table is that a user can set 'hints' for trimming the path only once (at bootstrap) and forget about it. All instances of Lox will use it.
ALox tries to detect trimable portions of a source path automatically. For that, ALox compares the actual path name of the executable of the currently running process with the path of a source file. The prefix both have in common is identified as trimable.
As an example, imagine a process' file name including the path is:
/home/lisa/bin/myapp(.exe)
When ALox finds a source file residing in:
/home/lisa/dev/myapp/src/ui/dialog.cpp
The trimable prefix of the path would be "/home/lisa/". Therefore, the trimmed file name would be:
dev/myapp/src/ui/dialog.cpp
The result is a more narrow log output which is probably even better readable.
Of-course, it would be even nicer to have
ui/dialog.cpp
or alternatively:
src/ui/dialog.cpp
Before we learn how we can configure ALox to trim the path like this, let us first better understand when ALox performs the automatic detection described above:
As you see, this auto-detection works nicely on small projects with source files kept local and the executable in a 'related' place.
When things become more complex, it is advisable to add Source Path Trim Rule explicitly.
A user of ALox may use method Lox.SetSourcePathTrimRule (C++, C#), to add Source Path Trim Rules explicitly.
When you reconsider the sample above, explicit setting leads to better results even in simple project. The sample used source file:
/home/lisa/dev/myapp/src/ui/dialog.cpp
Now, for a programmatically setting, Lisa invokes
as the very first statement before using ALox. The first parameter tells ALox which string to search. A leading wildcard character '*'
, indicates that the path is a substring of the file paths identified (no trailing '*'
is needed). The second, optional parameter tells ALox to include the given substring in the trimming. In other words, the substring will be excluded from the trimmed path. In other words: it means "the given portion of the path is included in the trimming action!
Now the trimmed source path leads to
ui/dialog.cpp
which is probably what is wanted. As we see, the huge advantages of explicitly setting Source Path Trim Rules is that they do a better job, are independently applied regardless of 'where' the executable is located and that any random behavior of trimming is eliminated.
'/'
, then characters '\'
found in parameters path and trimReplacement when setting rules are replaced by '\'
and vice versa. This allows to specify paths and substrings thereof in a platform independent way. The same is true when rules are defined in external configuration variables, as described later in this chapter.It is advisable to use set Source Path Trim Rules at the very start of a process. Even prior to attaching the debug Loggers or custom Loggers to any Lox instances. The reason for the latter is that already attaching a Logger lets class Lox evaluate the Scope and potentially create the internal automatic rule. This auto-rule might be conflicting with a user-given rule but be prioritized due to the fact that it was created prior to the users' rule.
Then, in a multi-threaded application, from the moment on parallel access to two different instances of class Lox are performed, it is not allowed to add 'global' rules, because, for performance reasons, the access to the rules is not protected by a mutex.
If multiple Source Path Trim Rules are set, those are applied in their order of creation. The private rules of a Lox are applied first, the global rules afterwards. Only one rule per source path is executed. In other words, as soon as a rule matches and modifies a source path, no further attempts for trimming are performed.
Setting Source Path Trim Rules 'from within the source code' is easy and straightforward. However, when working in a team such changes might not be appreciated by other team members. In this and other situations it is advisable to retrieve Source Path Trim Rule from external configuration data, command-line parameters or other sources at runtime.
For Source Path Trim Rules and also other configuration data, ALox leverages the configuration facility provided by underlying utility library ALib.
When an instance of class Lox is constructed, two a configuration variables are tried to be read:
ALOX_GLOBAL_SOURCE_PATH_TRIM_RULES
.ALOX_LOXNAME_SOURCE_PATH_TRIM_RULES
. The first is for defining global rules. The second variable is specific to a named Lox and the substring 'LOXNAME'
needs to be replaced by the name of the Lox in question.
Otherwise, the format of the variables are the same and the following description applies to both.
The variable may contain a list of Source Path Trim Rules separated by semicolons ';'
. Each rule consists of four values, separated by colons ','
. The four values correspond to the first four parameters of method Lox.SetSourcePathTrimRule (C++, C#). The same as parameter 3 (trimOffset) and 4 (sensitivity) are optional with method Lox.SetSourcePathTrimRule, providing them in the configuration variable is optional as well.
As an example, an INI file of an application might have the following sub-section:
This would install two rules. Note that values of parameters 2 and 4, which in the method declaration carry enum types Inclusion (C++, C#) and Case (C++, C#), in the INI file are expressed by boolean values as follows:
Inclusion::Include
== true
, Inclusion::Exclude
== false
Case::Sensitive
== true
, Case::Ignore
== false
Different trim rules might be redundant or even contradict each other. Therefore the rules are equipped with a priority. Rules with higher priority are applied first. Once a rule matches, no further rule is applied. The priority is an integer value and is lent from the ALib system for external configuration variables. It is are set as follows:
Configuration.PrioDefaultValues is a lower priority than (the default) priorities of the configuration plug-ins. Therefore, the configuration variables by default overrule what is hard-coded as a Source Path Trim Rule.
To change this behavior, any other priority may be specified in the source code, especially the pre-defined value of Priorities::DefaultValues (C++) respectively Configuration::PrioDefaultValues (C#). It allows the user to give the rule set in the source code the highest priority and this way to protect the rule from external manipulation.
With most methods invoked on class Lox, internal log messages are provided (See 11 - Internal Logging). When setting Source Path Trim Rules, this is not the case. The rational here is, that in most cases no Logger is attached to the Lox attached, yet. If something goes wrong with source path trimming, e.g. when you are not sure if a rule was read from external configuration variables, you can use method Lox.State (C++, C#) to dump out the current state of a Lox. Besides rules set programmatically or using configuration variables, if exists, also the auto-generated rule is displayed.
In very special situations (e.g. ALox uses it for unit testing) method Lox.ClearSourcePathTrimRules (C++, C#), can be used to clear the rules of a Lox instance, optionally including all global rules.
The benefits of having ALox using reduced length source file paths in consideration to Scopes is in respect to performance. All data associated with language-related Scopes is stored and retrieved in hash-tables with keys containing the source path.
Furthermore, the output of method Lox.State (C++, C#), might be better readable with these shorter paths.
It is also important to consider that when using Scope.Path, especially if increased by an amount of addressed parent directories, the source path must not be trimmed more than such use suggests. When the files are sorted in nested directories according to the nested namespace structure implemented in the files, then the directory prior to the tree of namespace directories should be included in the trimmed path.
Due to the rich meta information that ALox provides, the log output lines quickly become quite wide. Therefore, trimming the path of source files in the log output to a level that still allows to distinguish all files properly, can help a lot to reduce such width.
Class MetaInfo (C++, C#), with its instance found in every ALox TextLogger, provides a format string to structure the meta info. For the source path, two format parameters exists:
Directly from the log-output you can observe how trimming is performed by ALox and whether there is the need to add a trimming rule explicitly.
However, those IDEs which recognize certain patterns and allow to automatically link these patterns with the source file in their editor, sometimes need to see the full path name or a certain part of it. To adjust ALox to your IDE, you might have to play around a little. If your IDE supports clickable output lines, you might want to change the format of the meta info to match the pattern that your IDE requires.
Certain build systems/compilers might not provide the absolute path information in certain situations. In contrast, they might provide source directories in relative addressing in respect to a project file. This is at least true for C++. If then the IDE does not recognize the right origin of a relative path, this path needs correction to be absolute. ALox provides a feature to do such correction. An optional parameter of method Lox.SetSourcePathTrimRule (C++, C#) allows to specify a replacement string for what is cut by a rule. (This replacement string can of-course also be set using the configuration variables described in 1.3 Trim Rules Provided by External Configuration Variables.) Sometimes it might be needed to "fiddle around" with the options of the trim rules and the format of the TextLogger output, until finally your IDE recognizes the source information correctly. But once succeeded, it proofs being worth the effort!
When you are sure, that your IDE does not support the links to the editor, then you're unfortunate and your way to go is displaying a (best possible) trimmed path, to reduce overall log output width.