SongFilter: implement operator "!="

Closes #89
This commit is contained in:
Max Kellermann 2018-07-24 23:24:42 +02:00
parent 5271e81ebe
commit 9263d6d07d
3 changed files with 14 additions and 6 deletions

2
NEWS
View File

@ -7,7 +7,7 @@ ver 0.21 (not yet released)
- "outputs" prints the plugin name - "outputs" prints the plugin name
- "outputset" sets runtime attributes - "outputset" sets runtime attributes
- close connection when client sends HTTP request - close connection when client sends HTTP request
- new filter syntax for "find"/"search" etc. - new filter syntax for "find"/"search" etc. with negation
* database * database
- simple: scan audio formats - simple: scan audio formats
* player * player

View File

@ -222,6 +222,10 @@
"<code>(TAG == 'VALUE')</code>": match a tag value. "<code>(TAG == 'VALUE')</code>": match a tag value.
</para> </para>
<para>
"<code>(TAG != 'VALUE')</code>": mismatch a tag value.
</para>
<para> <para>
The special tag "<parameter>any</parameter>" checks all The special tag "<parameter>any</parameter>" checks all
tag values. tag values.

View File

@ -81,7 +81,7 @@ SongFilter::Item::ToExpression() const noexcept
{ {
switch (tag) { switch (tag) {
case LOCATE_TAG_FILE_TYPE: case LOCATE_TAG_FILE_TYPE:
return "(" LOCATE_TAG_FILE_KEY " == \"" + value + "\")"; return std::string("(" LOCATE_TAG_FILE_KEY " ") + (IsNegated() ? "!=" : "==") + " \"" + value + "\")";
case LOCATE_TAG_BASE_TYPE: case LOCATE_TAG_BASE_TYPE:
return "(base \"" + value + "\")"; return "(base \"" + value + "\")";
@ -90,10 +90,10 @@ SongFilter::Item::ToExpression() const noexcept
return "(modified-since \"" + value + "\")"; return "(modified-since \"" + value + "\")";
case LOCATE_TAG_ANY_TYPE: case LOCATE_TAG_ANY_TYPE:
return "(" LOCATE_TAG_ANY_KEY " == \"" + value + "\")"; return std::string("(" LOCATE_TAG_ANY_KEY " ") + (IsNegated() ? "!=" : "==") + " \"" + value + "\")";
default: default:
return std::string("(") + tag_item_names[tag] + " == \"" + value + "\")"; return std::string("(") + tag_item_names[tag] + " " + (IsNegated() ? "!=" : "==") + " \"" + value + "\")";
} }
} }
@ -317,8 +317,11 @@ SongFilter::ParseExpression(const char *s, bool fold_case)
items.emplace_back(type, std::move(value), fold_case); items.emplace_back(type, std::move(value), fold_case);
return StripLeft(s + 1); return StripLeft(s + 1);
} else { } else {
if (s[0] != '=' || s[1] != '=') bool negated = false;
throw std::runtime_error("'==' expected"); if (s[0] == '!' && s[1] == '=')
negated = true;
else if (s[0] != '=' || s[1] != '=')
throw std::runtime_error("'==' or '!=' expected");
s = StripLeft(s + 2); s = StripLeft(s + 2);
auto value = ExpectQuoted(s); auto value = ExpectQuoted(s);
@ -326,6 +329,7 @@ SongFilter::ParseExpression(const char *s, bool fold_case)
throw std::runtime_error("')' expected"); throw std::runtime_error("')' expected");
items.emplace_back(type, std::move(value), fold_case); items.emplace_back(type, std::move(value), fold_case);
items.back().SetNegated(negated);
return StripLeft(s + 1); return StripLeft(s + 1);
} }
} }