mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-07-07 20:06:36 +02:00
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.
This commit is contained in:
parent
f595bc4731
commit
79f59f12ae
3 changed files with 32 additions and 20 deletions
13
src/Att.cpp
13
src/Att.cpp
|
@ -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);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue