From 060908d5c44ba54e0871a83973245ff44dc52103 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 12 Nov 2018 12:41:29 +0100 Subject: song/Filter: add operator "contains" Closes #410 --- NEWS | 1 + doc/protocol.rst | 3 +++ src/song/Filter.cxx | 14 ++++++++++++++ src/song/StringFilter.hxx | 4 +++- 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index fa66df85a..53d81eeed 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ ver 0.21.2 (not yet released) * protocol - operator "=~" matches a regular expression + - operator "contains" matches substrings * decoder - ffmpeg: require FFmpeg 3.1 or later - ffmpeg: fix broken sound with certain codecs diff --git a/doc/protocol.rst b/doc/protocol.rst index 4818b55fb..e0d750f29 100644 --- a/doc/protocol.rst +++ b/doc/protocol.rst @@ -154,6 +154,9 @@ of: ``AlbumArtist`` does not exist. ``VALUE`` is what to find. +- ``(TAG contains 'VALUE')`` checks if the given value is a substring + of the tag value. + - ``(TAG =~ 'VALUE')`` and ``(TAG !~ 'VALUE')`` use a Perl-compatible regular expression instead of doing a simple string comparison. (This feature is only available if :program:`MPD` was compiled with diff --git a/src/song/Filter.cxx b/src/song/Filter.cxx index 2c47ebb59..0725083a6 100644 --- a/src/song/Filter.cxx +++ b/src/song/Filter.cxx @@ -206,6 +206,20 @@ ExpectQuoted(const char *&s) static StringFilter ParseStringFilter(const char *&s, bool fold_case) { + if (auto after_contains = StringAfterPrefixIgnoreCase(s, "contains ")) { + s = StripLeft(after_contains); + auto value = ExpectQuoted(s); + return StringFilter(std::move(value), + fold_case, true, false); + } + + if (auto after_not_contains = StringAfterPrefixIgnoreCase(s, "!contains ")) { + s = StripLeft(after_not_contains); + auto value = ExpectQuoted(s); + return StringFilter(std::move(value), + fold_case, true, true); + } + bool negated = false; #ifdef HAVE_PCRE diff --git a/src/song/StringFilter.hxx b/src/song/StringFilter.hxx index 0c7c3f5e8..b01a419a5 100644 --- a/src/song/StringFilter.hxx +++ b/src/song/StringFilter.hxx @@ -96,7 +96,9 @@ public: const char *GetOperator() const noexcept { return IsRegex() ? (negated ? "!~" : "=~") - : (negated ? "!=" : "=="); + : (substring + ? (negated ? "!contains" : "contains") + : (negated ? "!=" : "==")); } gcc_pure -- cgit v1.2.3