mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Regex
- Added regex support to expressions. - Implmented configurable case sensitivity.
This commit is contained in:
parent
8040ed5430
commit
03dbf7f468
4 changed files with 49 additions and 59 deletions
|
@ -34,6 +34,7 @@
|
|||
#include <Duration.h>
|
||||
#include <Nibbler.h>
|
||||
#include <Variant.h>
|
||||
#include <RegX.h>
|
||||
#include <text.h>
|
||||
#include <Expression.h>
|
||||
|
||||
|
@ -199,39 +200,15 @@ bool Expression::eval (Task& task)
|
|||
else if (arg->first == "!~")
|
||||
{
|
||||
// std::cout << "# " << left.dump () << " !~ " << right.dump () << "\n";
|
||||
bool result = false;
|
||||
bool case_sensitive = context.config.getBoolean ("search.case.sensitive");
|
||||
bool result = !eval_match (left, right, case_sensitive);
|
||||
|
||||
// Matches against description are really against either description,
|
||||
// annotations or project.
|
||||
if (left._raw == "description")
|
||||
// Short-circuit if match already failed.
|
||||
if (result && left._raw == "description")
|
||||
{
|
||||
if (right._raw_type == "rx")
|
||||
{
|
||||
throw std::string ("rx not supported");
|
||||
}
|
||||
else
|
||||
{
|
||||
left.cast (Variant::v_string);
|
||||
right.cast (Variant::v_string);
|
||||
if (left._string.find (right._string) == std::string::npos)
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Matches against non-description fields are treated as-is.
|
||||
else
|
||||
{
|
||||
if (right._raw_type == "rx")
|
||||
{
|
||||
throw std::string ("rx not supported");
|
||||
}
|
||||
else
|
||||
{
|
||||
left.cast (Variant::v_string);
|
||||
right.cast (Variant::v_string);
|
||||
if (left._string.find (right._string) == std::string::npos)
|
||||
result = true;
|
||||
}
|
||||
// TODO check further.
|
||||
}
|
||||
|
||||
left = Variant (result);
|
||||
|
@ -277,39 +254,15 @@ bool Expression::eval (Task& task)
|
|||
else if (arg->first == "~")
|
||||
{
|
||||
// std::cout << "# " << left.dump () << " ~ " << right.dump () << "\n";
|
||||
bool result = false;
|
||||
bool case_sensitive = context.config.getBoolean ("search.case.sensitive");
|
||||
bool result = eval_match (left, right, case_sensitive);
|
||||
|
||||
// Matches against description are really against either description,
|
||||
// annotations or project.
|
||||
if (left._raw == "description")
|
||||
// Short-circuit if match is already found.
|
||||
if (!result && left._raw == "description")
|
||||
{
|
||||
if (right._raw_type == "rx")
|
||||
{
|
||||
throw std::string ("rx not supported");
|
||||
}
|
||||
else
|
||||
{
|
||||
left.cast (Variant::v_string);
|
||||
right.cast (Variant::v_string);
|
||||
if (left._string.find (right._string) != std::string::npos)
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Matches against non-description fields are treated as-is.
|
||||
else
|
||||
{
|
||||
if (right._raw_type == "rx")
|
||||
{
|
||||
throw std::string ("rx not supported");
|
||||
}
|
||||
else
|
||||
{
|
||||
left.cast (Variant::v_string);
|
||||
right.cast (Variant::v_string);
|
||||
if (left._string.find (right._string) != std::string::npos)
|
||||
result = true;
|
||||
}
|
||||
// TODO check further.
|
||||
}
|
||||
|
||||
left = Variant (result);
|
||||
|
@ -384,6 +337,32 @@ bool Expression::eval (Task& task)
|
|||
return pass_fail;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool Expression::eval_match (Variant& left, Variant& right, bool case_sensitive)
|
||||
{
|
||||
if (right._raw_type == "rx")
|
||||
{
|
||||
left.cast (Variant::v_string);
|
||||
right.cast (Variant::v_string);
|
||||
|
||||
// Create a cached entry, if it does not already exist.
|
||||
if (_regexes.find (right._string) == _regexes.end ())
|
||||
_regexes[right._string] = RegX (right._string, case_sensitive);
|
||||
|
||||
if (_regexes[right._string].match (left._string))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
left.cast (Variant::v_string);
|
||||
right.cast (Variant::v_string);
|
||||
if (find (left._string, right._string, (bool) case_sensitive) != std::string::npos)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void Expression::create_variant (
|
||||
Variant& variant,
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <stack>
|
||||
#include <Arguments.h>
|
||||
#include <Task.h>
|
||||
#include <RegX.h>
|
||||
#include <Variant.h>
|
||||
|
||||
class Expression
|
||||
|
@ -56,10 +57,11 @@ private:
|
|||
bool is_new_style ();
|
||||
|
||||
private:
|
||||
|
||||
bool eval_match (Variant&, Variant&, bool);
|
||||
|
||||
private:
|
||||
Arguments _args;
|
||||
std::map <std::string, RegX> _regexes;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -34,6 +34,14 @@
|
|||
//#define _POSIX_C_SOURCE 1
|
||||
#define MAX_MATCHES 64
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
RegX::RegX ()
|
||||
: _compiled (false)
|
||||
, _pattern ("")
|
||||
, _case_sensitive (true)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
RegX::RegX (
|
||||
const std::string& pattern,
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
class RegX
|
||||
{
|
||||
public:
|
||||
RegX ();
|
||||
RegX (const std::string&, bool caseSensitive = true);
|
||||
RegX (const RegX&);
|
||||
RegX& operator= (const RegX&);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue