SongFilter: add class NotSongFilter

This commit is contained in:
Max Kellermann 2018-07-25 10:19:49 +02:00
parent e47e3205b3
commit e5e623ffaa
3 changed files with 71 additions and 0 deletions

View File

@ -276,6 +276,12 @@
</para>
</listitem>
<listitem>
<para>
"<code>(!EXPRESSION)</code>": negate an expression.
</para>
</listitem>
<listitem>
<para>
"<code>(EXPRESSION1 AND EXPRESSION2 ...)</code>": combine two or

View File

@ -19,6 +19,7 @@
#include "config.h"
#include "Filter.hxx"
#include "NotSongFilter.hxx"
#include "UriSongFilter.hxx"
#include "BaseSongFilter.hxx"
#include "TagSongFilter.hxx"
@ -214,6 +215,20 @@ SongFilter::ParseExpression(const char *&s, bool fold_case)
}
}
if (*s == '!') {
s = StripLeft(s + 1);
if (*s != '(')
throw std::runtime_error("'(' expected");
auto inner = ParseExpression(s, fold_case);
if (*s != ')')
throw std::runtime_error("')' expected");
s = StripLeft(s + 1);
return std::make_unique<NotSongFilter>(std::move(inner));
}
auto type = ExpectFilterType(s);
if (type == LOCATE_TAG_MODIFIED_SINCE) {

View File

@ -0,0 +1,50 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_NOT_SONG_FILTER_HXX
#define MPD_NOT_SONG_FILTER_HXX
#include "ISongFilter.hxx"
/**
* Negate an #ISongFilter.
*/
class NotSongFilter final : public ISongFilter {
ISongFilterPtr child;
public:
template<typename C>
explicit NotSongFilter(C &&_child) noexcept
:child(std::forward<C>(_child)) {}
/* virtual methods from ISongFilter */
ISongFilterPtr Clone() const noexcept override {
return std::make_unique<NotSongFilter>(child->Clone());
}
std::string ToExpression() const noexcept override {
return "(!" + child->ToExpression() + ")";
}
bool Match(const LightSong &song) const noexcept override {
return !child->Match(song);
}
};
#endif