Enhancement - related to, but not fixing bug #293

- Added new attribute modifiers 'word' and 'noword' which find the existence
  of whole words, or prove the non-existence of whole words.  If a task has
  the description "Pay the bill", then "description.word:the" will match, but
  "description.word:th" will not.  For partial word matches, there is still
  "description.contains:th".
- Added unit tests for the text.cpp functions.
- Added unit tests including the new modifiers in filters.
- Added unit tests to parse the new modifiers.
- Modified man page.
- Modified the Context::autoFilter processing to use the new modifiers for
  +tag and -tag filtering.
- Added a support email to an error message, while looking at the filter code.
- Added new modifiers to the help report.
- Modified a utf8.t unit test to include an alphanumeric tag, rather than a
  smiley face.
This commit is contained in:
Paul Beckingham 2009-12-07 01:35:47 -05:00
parent d019126086
commit 7acef0c9fd
12 changed files with 189 additions and 10 deletions

View file

@ -77,6 +77,8 @@ static const char* modifierNames[] =
"hasnt",
"startswith", "left",
"endswith", "right",
"word",
"noword"
};
#define NUM_INTERNAL_NAMES (sizeof (internalNames) / sizeof (internalNames[0]))
@ -375,7 +377,7 @@ bool Att::validNameValue (
}
////////////////////////////////////////////////////////////////////////////////
// TODO Obsolete
// TODO Deprecated - remove.
bool Att::validMod (const std::string& mod)
{
for (unsigned int i = 0; i < NUM_MODIFIER_NAMES; ++i)
@ -412,7 +414,8 @@ std::string Att::type (const std::string& name) const
std::string Att::modType (const std::string& name) const
{
if (name == "hasnt" ||
name == "isnt")
name == "isnt" ||
name == "noword")
return "negative";
return "positive";
@ -615,6 +618,35 @@ bool Att::match (const Att& other) const
}
}
// word = contains as a substring, with word boundaries.
else if (mMod == "word") // TODO i18n
{
// Fail if the substring is not found.
std::string::size_type sub = other.mValue.find (mValue);
if (sub == std::string::npos)
return false;
// Also fail if there is no word boundary at beginning and end.
if (!isWordStart (other.mValue, sub))
return false;
if (!isWordEnd (other.mValue, sub + mValue.length () - 1))
return false;
}
// noword = does not contain as a substring, with word boundaries.
else if (mMod == "noword") // TODO i18n
{
// Fail if the substring is not found.
std::string::size_type sub = other.mValue.find (mValue);
if (sub != std::string::npos &&
isWordStart (other.mValue, sub) &&
isWordEnd (other.mValue, sub + mValue.length () - 1))
{
return false;
}
}
return true;
}