Regex
- Added regex support to expressions. - Implmented configurable case sensitivity.
This commit is contained in:
@@ -34,6 +34,7 @@
|
|||||||
#include <Duration.h>
|
#include <Duration.h>
|
||||||
#include <Nibbler.h>
|
#include <Nibbler.h>
|
||||||
#include <Variant.h>
|
#include <Variant.h>
|
||||||
|
#include <RegX.h>
|
||||||
#include <text.h>
|
#include <text.h>
|
||||||
#include <Expression.h>
|
#include <Expression.h>
|
||||||
|
|
||||||
@@ -199,39 +200,15 @@ bool Expression::eval (Task& task)
|
|||||||
else if (arg->first == "!~")
|
else if (arg->first == "!~")
|
||||||
{
|
{
|
||||||
// std::cout << "# " << left.dump () << " !~ " << right.dump () << "\n";
|
// 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,
|
// Matches against description are really against either description,
|
||||||
// annotations or project.
|
// annotations or project.
|
||||||
if (left._raw == "description")
|
// Short-circuit if match already failed.
|
||||||
|
if (result && left._raw == "description")
|
||||||
{
|
{
|
||||||
if (right._raw_type == "rx")
|
// TODO check further.
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
left = Variant (result);
|
left = Variant (result);
|
||||||
@@ -277,39 +254,15 @@ bool Expression::eval (Task& task)
|
|||||||
else if (arg->first == "~")
|
else if (arg->first == "~")
|
||||||
{
|
{
|
||||||
// std::cout << "# " << left.dump () << " ~ " << right.dump () << "\n";
|
// 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,
|
// Matches against description are really against either description,
|
||||||
// annotations or project.
|
// annotations or project.
|
||||||
if (left._raw == "description")
|
// Short-circuit if match is already found.
|
||||||
|
if (!result && left._raw == "description")
|
||||||
{
|
{
|
||||||
if (right._raw_type == "rx")
|
// TODO check further.
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
left = Variant (result);
|
left = Variant (result);
|
||||||
@@ -384,6 +337,32 @@ bool Expression::eval (Task& task)
|
|||||||
return pass_fail;
|
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 (
|
void Expression::create_variant (
|
||||||
Variant& variant,
|
Variant& variant,
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <stack>
|
#include <stack>
|
||||||
#include <Arguments.h>
|
#include <Arguments.h>
|
||||||
#include <Task.h>
|
#include <Task.h>
|
||||||
|
#include <RegX.h>
|
||||||
#include <Variant.h>
|
#include <Variant.h>
|
||||||
|
|
||||||
class Expression
|
class Expression
|
||||||
@@ -56,10 +57,11 @@ private:
|
|||||||
bool is_new_style ();
|
bool is_new_style ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool eval_match (Variant&, Variant&, bool);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Arguments _args;
|
Arguments _args;
|
||||||
|
std::map <std::string, RegX> _regexes;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -34,6 +34,14 @@
|
|||||||
//#define _POSIX_C_SOURCE 1
|
//#define _POSIX_C_SOURCE 1
|
||||||
#define MAX_MATCHES 64
|
#define MAX_MATCHES 64
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
RegX::RegX ()
|
||||||
|
: _compiled (false)
|
||||||
|
, _pattern ("")
|
||||||
|
, _case_sensitive (true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
RegX::RegX (
|
RegX::RegX (
|
||||||
const std::string& pattern,
|
const std::string& pattern,
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
class RegX
|
class RegX
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
RegX ();
|
||||||
RegX (const std::string&, bool caseSensitive = true);
|
RegX (const std::string&, bool caseSensitive = true);
|
||||||
RegX (const RegX&);
|
RegX (const RegX&);
|
||||||
RegX& operator= (const RegX&);
|
RegX& operator= (const RegX&);
|
||||||
|
|||||||
Reference in New Issue
Block a user