From 79f59f12ae744165beeb4294346a9a9c4e90b6ce Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 16 Aug 2009 13:01:28 -0400 Subject: [PATCH] Bug Fix - #252 - Fixed bug that prevented using end.after: and end.before: together to effect a range. - Required differentiation between positive and negative attribute modifiers, and special handling. --- src/Att.cpp | 13 ++++++++++++- src/Att.h | 1 + src/Filter.cpp | 38 +++++++++++++++++++------------------- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/Att.cpp b/src/Att.cpp index 608252c18..a25682492 100644 --- a/src/Att.cpp +++ b/src/Att.cpp @@ -407,6 +407,17 @@ std::string Att::type (const std::string& name) const return "text"; } +//////////////////////////////////////////////////////////////////////////////// +// The type of an attribute is useful for modifier evaluation. +std::string Att::modType (const std::string& name) const +{ + if (name == "hasnt" || + name == "isnt") + return "negative"; + + return "positive"; +} + //////////////////////////////////////////////////////////////////////////////// // // start --> name --> . --> mod --> : --> " --> value --> " --> end @@ -461,7 +472,7 @@ void Att::parse (Nibbler& n) else throw std::string ("Missing : after attribute name"); // TODO i18n -/* TODO This might be too slow to include. Test. +/* TODO This might be too slow to include. Test this assumption. validNameValue (mName, mMod, mValue); */ } diff --git a/src/Att.h b/src/Att.h index 324f85876..eccf2738a 100644 --- a/src/Att.h +++ b/src/Att.h @@ -50,6 +50,7 @@ public: static bool validNameValue (std::string&, std::string&, std::string&); static bool validMod (const std::string&); std::string type (const std::string&) const; + std::string modType (const std::string&) const; void parse (const std::string&); void parse (Nibbler&); bool match (const Att&) const; diff --git a/src/Filter.cpp b/src/Filter.cpp index 79f800372..10e8373d9 100644 --- a/src/Filter.cpp +++ b/src/Filter.cpp @@ -25,6 +25,7 @@ // //////////////////////////////////////////////////////////////////////////////// +#include // TODO Remove #include #include "Filter.h" #include "util.h" @@ -40,34 +41,33 @@ bool Filter::pass (const Record& record) const // First do description/annotation matches. foreach (att, (*this)) { - // Descriptions have special handling. + // Descriptions have special handling such that they are linked to + // annotations, and filtering on description implies identical filtering + // on annotations, and that both filter matches must succeed for the filter + // to succeed overall. if (att->name () == "description") { + bool description_result = true; + bool annotation_result = true; + if ((r = record.find (att->name ())) != record.end ()) { - // A description match failure can be salvaged by an annotation match. - if (! att->match (r->second)) - { - bool annoMatch = false; - foreach (ra, record) - { - if (ra->first.length () > 11 && - ra->first.substr (0, 11) == "annotation_") - { - if (att->match (ra->second)) - { - annoMatch = true; - break; - } - } - } + description_result = att->match (r->second); - if (!annoMatch) - return false; + foreach (ra, record) + { + if (ra->first.length () > 11 && + ra->first.substr (0, 11) == "annotation_") + annotation_result = annotation_result && att->match (ra->second); } } else if (! att->match (Att ())) return false; + + if (att->modType (att->mod ()) == "positive") + return description_result && annotation_result; + + return description_result || annotation_result; } // Annotations are skipped, because they are handled above.