reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

commit 04d8296a62a5a7c84e88ff9c32b16189eab6e3bc
parent 3757ac72991202f18c674b423ed94186f4f3d562
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Fri,  2 Sep 2016 21:45:25 -0400

filter: fix NOT ( a OR b ) OR c

Diffstat:
Msrc/filter.cpp | 26+++++++++++++++++---------
Mtest/filter.cpp | 22+++++++++++++++++++++-
2 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/src/filter.cpp b/src/filter.cpp @@ -88,7 +88,7 @@ Filter::Group *Filter::Group::push(string buf, int *flags) else if(buf == "OR") { if(m_nodes.empty()) return this; - else if(m_type == Group::MatchAny) { + else if(m_type == MatchAny) { m_open = true; return this; } @@ -99,7 +99,7 @@ Filter::Group *Filter::Group::push(string buf, int *flags) m_nodes.pop_back(); } - auto newGroup = make_shared<Group>(Group::MatchAny, 0, this); + auto newGroup = make_shared<Group>(MatchAny, 0, this); m_nodes.push_back(newGroup); if(prev) @@ -108,13 +108,24 @@ Filter::Group *Filter::Group::push(string buf, int *flags) return newGroup.get(); } else if(buf == "(") { - auto newGroup = make_shared<Group>(Group::MatchAll, *flags, this); + auto newGroup = make_shared<Group>(MatchAll, *flags, this); m_nodes.push_back(newGroup); *flags = 0; return newGroup.get(); } - else if(buf == ")") - return m_parent ? m_parent : this; + else if(buf == ")") { + Group *parent = this; + + while(parent->m_parent) { + const Type type = parent->m_type; + parent = parent->m_parent; + + if(type == MatchAll) + break; + } + + return parent; + } } if(size > 1 && buf[0] == '^') { @@ -128,10 +139,7 @@ Filter::Group *Filter::Group::push(string buf, int *flags) size--; } - Group *group = this; - - while(!group->m_open) - group = group->m_parent; + Group *group = m_open ? this : m_parent; group->push(make_shared<Token>(buf, *flags)); *flags = 0; diff --git a/test/filter.cpp b/test/filter.cpp @@ -270,10 +270,30 @@ TEST_CASE("AND grouping", M) { } SECTION("NOT + AND grouping") { - f.set("NOT ( apple OR orange )"); + f.set("NOT ( apple orange ) bacon"); + + REQUIRE(f.match({"bacon"})); + REQUIRE_FALSE(f.match({"apple bacon"})); + REQUIRE_FALSE(f.match({"orange bacon"})); + } + + SECTION("NOT + AND + OR grouping") { + f.set("NOT ( apple OR orange ) OR bacon"); + + REQUIRE_FALSE(f.match({"apple"})); + REQUIRE_FALSE(f.match({"orange"})); + REQUIRE(f.match({"test"})); + REQUIRE(f.match({"apple bacon"})); + REQUIRE(f.match({"bacon"})); + } + + SECTION("nested groups") { + f.set("NOT ( ( apple OR orange ) OR bacon )"); REQUIRE_FALSE(f.match({"apple"})); REQUIRE_FALSE(f.match({"orange"})); REQUIRE(f.match({"test"})); + REQUIRE_FALSE(f.match({"apple bacon"})); + REQUIRE_FALSE(f.match({"bacon"})); } }