Replace the boolean parameters for including user metadata and evaluating conditions with MergeMode and EvalMode enums.
The C++ and Python wrappers still use booleans because they're more constrained than enums in those languages, which can be given invalid values.
It uses about 56 MB less memory when LOOT launches into my Skyrim SE
large test load order with the latest masterlist and prelude, and
explicitly targets ECMAScript-like syntax like C++ std::regex does,
though supports newer functionality.
Compared to fancy-regex's syntax support, regress adds support for the
\0 nul character escape and removes support for:
- modifiers (e.g. `(?i)`)
- some Unicode character classes (e.g. used with `\p{}` and `\P{}`)
- the ASCII/POSIX character classes (e.g. `[:alpha:]`)
- various character escapes, including \A \a \z \b{start} \<
\b{end} \> \b{start-half} \b{end-half}
- (?P<name>exp) named capture groups
However, since regress's v flag requires more characters to be escaped
inside character classes than fancy-regex's Unicode support requires,
it's not used, so that further restricts the supported Unicode character
classes, and means that character class intersection, union and
subtraction syntaxes aren't supported.
The nul character escape is irrelevant for filename matching as it's not
allowed in Windows or Linux filenames.
Compared to C++ std::regex, the new restrictions are:
- the lack of support for ASCII/POSIX character classes
- the lack of support for control character escapes (e.g. `\cX`)
The lack of support for control character escapes is irrelevant as
control characters aren't allowed in Windows filenames.
A search of the masterlists doesn't find any use of the ASCII character
classes, and it's very unlikely that any user metadata would use them.
If such syntax is in use, it'll cause an error.
fancy-regex supports more syntax than C++ std::regex, but for the syntax
that they both accept:
- std::regex matches . against a single character, fancy-regex matches
it against a Unicode codepoint
- \w \W \d \D \s \S \b and \B are locale-dependent in std::regex but
Unicode-aware and locale-independent in fancy-regex
- case-insensitive comparisons are locale-dependent in std::regex but
are Unicode-aware and locale-independent in fancy-regex
- std::regex supports \0 and \cX escapes, where X is in [A-Za-z] but
fancy-regex does not. This is not significant for libloot's usage as
nul and control characters are not allowed in Windows filenames.
- std::regex treats \< and \> as < and > respectively, but fancy-regex
treats them as start- and end-of-word boundary assertions
respectively. This is not significant for libloot's usage as they are
not allowed in Windows filenames.
- std::regex allows a literal [ to appear within a character class, but
fancy-regex requires it to be escaped.
These differences are unlikely to cause any issues.
This makes it so that all non-public functions use camelCase and all public functions use PascalCase.
I regret choosing to use PascalCase for function names, but it's not worth breaking the whole public API to change that, and at least this approach has precedent in how Go decides if a function is public or private.