- 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.
This commit is contained in:
Paul Beckingham 2009-08-16 13:01:28 -04:00
parent f595bc4731
commit 79f59f12ae
3 changed files with 32 additions and 20 deletions

View file

@ -407,6 +407,17 @@ std::string Att::type (const std::string& name) const
return "text"; 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 // start --> name --> . --> mod --> : --> " --> value --> " --> end
@ -461,7 +472,7 @@ void Att::parse (Nibbler& n)
else else
throw std::string ("Missing : after attribute name"); // TODO i18n 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); validNameValue (mName, mMod, mValue);
*/ */
} }

View file

@ -50,6 +50,7 @@ public:
static bool validNameValue (std::string&, std::string&, std::string&); static bool validNameValue (std::string&, std::string&, std::string&);
static bool validMod (const std::string&); static bool validMod (const std::string&);
std::string type (const std::string&) const; std::string type (const std::string&) const;
std::string modType (const std::string&) const;
void parse (const std::string&); void parse (const std::string&);
void parse (Nibbler&); void parse (Nibbler&);
bool match (const Att&) const; bool match (const Att&) const;

View file

@ -25,6 +25,7 @@
// //
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include <iostream> // TODO Remove
#include <sstream> #include <sstream>
#include "Filter.h" #include "Filter.h"
#include "util.h" #include "util.h"
@ -40,34 +41,33 @@ bool Filter::pass (const Record& record) const
// First do description/annotation matches. // First do description/annotation matches.
foreach (att, (*this)) 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") if (att->name () == "description")
{ {
bool description_result = true;
bool annotation_result = true;
if ((r = record.find (att->name ())) != record.end ()) if ((r = record.find (att->name ())) != record.end ())
{ {
// A description match failure can be salvaged by an annotation match. description_result = att->match (r->second);
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;
}
}
}
if (!annoMatch) foreach (ra, record)
return false; {
if (ra->first.length () > 11 &&
ra->first.substr (0, 11) == "annotation_")
annotation_result = annotation_result && att->match (ra->second);
} }
} }
else if (! att->match (Att ())) else if (! att->match (Att ()))
return false; 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. // Annotations are skipped, because they are handled above.