From 5f4571b0d08b1fe1660561a194a12b9241fb1974 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Wed, 31 Aug 2011 23:36:16 -0400 Subject: [PATCH] Expressions - Implemented expression escalation: when matching against description, escalate to include annotations on failure. Needs adjustment to DOM eval before it will work. --- src/E9.cpp | 87 +++++++++++++++++++++++++++++++++++++++++------------- src/E9.h | 4 +-- 2 files changed, 68 insertions(+), 23 deletions(-) diff --git a/src/E9.cpp b/src/E9.cpp index 3c06f577c..acd3ed0a8 100644 --- a/src/E9.cpp +++ b/src/E9.cpp @@ -137,8 +137,8 @@ void E9::eval (const Task& task, std::vector & value_stack) else if (arg->_raw == ">") operator_gt (result, left, right); else if (arg->_raw == "!=") operator_inequal (result, left, right, case_sensitive); else if (arg->_raw == "=") operator_equal (result, left, right, case_sensitive); - else if (arg->_raw == "~") operator_match (result, left, right, case_sensitive); - else if (arg->_raw == "!~") operator_nomatch (result, left, right, case_sensitive); + else if (arg->_raw == "~") operator_match (result, left, right, case_sensitive, task); + else if (arg->_raw == "!~") operator_nomatch (result, left, right, case_sensitive, task); else if (arg->_raw == "*") operator_multiply (result, left, right); else if (arg->_raw == "/") operator_divide (result, left, right); else if (arg->_raw == "+") operator_add (result, left, right); @@ -498,41 +498,86 @@ void E9::operator_equal ( } //////////////////////////////////////////////////////////////////////////////// +// Match may occur in description or any annotation. Short circuits. void E9::operator_match ( Arg& result, Arg& left, Arg& right, - bool case_sensitive) + bool case_sensitive, + const Task& task) { result._type = Arg::type_bool; - result._value = eval_match (left, right, case_sensitive) - ? "true" - : "false"; -// std::cout << "# " << left << " " << right << " --> " << result << "\n"; + // TODO The problem is that description/dom -> /string and we lose the original value. + + if (eval_match (left, right, case_sensitive)) + { + // std::cout << "# operator_match description match\n"; + result._value = "true"; + } + else if (left._raw == "description") + { + // std::cout << "# operator_match escalation\n"; + std::map annotations; + task.getAnnotations (annotations); + + std::map ::iterator a; + for (a = annotations.begin (); a != annotations.end (); ++a) + { + // Clone 'right', override _value. + Arg alternate (right); + alternate._value = a->second; + + if (eval_match (left, alternate, case_sensitive)) + { + // std::cout << "# operator_match annotation match\n"; + result._value = "true"; + break; + } + } + } + else + result._value = "false"; + + // std::cout << "# " << left << " " << right << " --> " << result << "\n"; } //////////////////////////////////////////////////////////////////////////////// -// 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. -// // Short-circuit if match already failed. -// if (result && left._raw == "description") -// { -// // TODO check further. -// } +// Match may not occur in description or any annotation. Short circuits. void E9::operator_nomatch ( Arg& result, Arg& left, Arg& right, - bool case_sensitive) + bool case_sensitive, + const Task& task) { result._type = Arg::type_bool; - result._value = eval_match (left, right, case_sensitive) - ? "false" - : "true"; + + if (eval_match (left, right, case_sensitive)) + { + result._value = "false"; + } + else if (left._raw == "description") + { + std::map annotations; + task.getAnnotations (annotations); + + std::map ::iterator a; + for (a = annotations.begin (); a != annotations.end (); ++a) + { + // Clone 'right', override _value. + Arg alternate (right); + alternate._value = a->second; + + if (eval_match (left, alternate, case_sensitive)) + { + result._value = "false"; + break; + } + } + } + else + result._value = "true"; // std::cout << "# " << left << " " << right << " --> " << result << "\n"; } diff --git a/src/E9.h b/src/E9.h index db4773249..9150b0051 100644 --- a/src/E9.h +++ b/src/E9.h @@ -59,8 +59,8 @@ private: void operator_gt (Arg&, Arg&, Arg&); void operator_inequal (Arg&, Arg&, Arg&, bool); void operator_equal (Arg&, Arg&, Arg&, bool); - void operator_match (Arg&, Arg&, Arg&, bool); - void operator_nomatch (Arg&, Arg&, Arg&, bool); + void operator_match (Arg&, Arg&, Arg&, bool, const Task&); + void operator_nomatch (Arg&, Arg&, Arg&, bool, const Task&); void operator_multiply (Arg&, Arg&, Arg&); void operator_divide (Arg&, Arg&, Arg&); void operator_add (Arg&, Arg&, Arg&);