song/StringFilter: support regular expressions with "=~" and "!~"

This feature requires `libpcre`.
This commit is contained in:
Max Kellermann
2018-11-07 00:28:15 +01:00
parent fee75dc766
commit 72184dccfc
13 changed files with 294 additions and 1 deletions

View File

@@ -207,6 +207,20 @@ static StringFilter
ParseStringFilter(const char *&s, bool fold_case)
{
bool negated = false;
#ifdef HAVE_PCRE
if ((s[0] == '!' || s[0] == '=') && s[1] == '~') {
negated = s[0] == '!';
s = StripLeft(s + 2);
auto value = ExpectQuoted(s);
StringFilter f(std::move(value), fold_case, false, negated);
f.SetRegex(std::make_shared<UniqueRegex>(f.GetValue().c_str(),
false, false,
fold_case));
return f;
}
#endif
if (s[0] == '!' && s[1] == '=')
negated = true;
else if (s[0] != '=' || s[1] != '=')

View File

@@ -31,6 +31,11 @@ StringFilter::MatchWithoutNegation(const char *s) const noexcept
assert(s != nullptr);
#endif
#ifdef HAVE_PCRE
if (regex)
return regex->Match(s);
#endif
if (fold_case) {
return substring
? fold_case.IsIn(s)

View File

@@ -23,7 +23,12 @@
#include "lib/icu/Compare.hxx"
#include "util/Compiler.h"
#ifdef HAVE_PCRE
#include "lib/pcre/UniqueRegex.hxx"
#endif
#include <string>
#include <memory>
class StringFilter {
std::string value;
@@ -33,6 +38,10 @@ class StringFilter {
*/
IcuCompare fold_case;
#ifdef HAVE_PCRE
std::shared_ptr<UniqueRegex> regex;
#endif
/**
* Search for substrings instead of matching the whole string?
*/
@@ -53,6 +62,21 @@ public:
return value.empty();
}
bool IsRegex() const noexcept {
#ifdef HAVE_PCRE
return !!regex;
#else
return false;
#endif
}
#ifdef HAVE_PCRE
template<typename R>
void SetRegex(R &&_regex) noexcept {
regex = std::forward<R>(_regex);
}
#endif
const auto &GetValue() const noexcept {
return value;
}
@@ -70,7 +94,9 @@ public:
}
const char *GetOperator() const noexcept {
return negated ? "!=" : "==";
return IsRegex()
? (negated ? "!~" : "=~")
: (negated ? "!=" : "==");
}
gcc_pure

View File

@@ -19,6 +19,7 @@ song_dep = declare_dependency(
link_with: song,
dependencies: [
icu_dep,
pcre_dep,
tag_dep,
util_dep,
],