From 09431caf1cc8c4581e6d0d6e7ebaa4b951d7425e Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 19 Feb 2012 17:20:11 -0500 Subject: [PATCH] Bug - Tag matching was being performed using the regex \b\b, which makes taskwarrior dependent on regex lib bugs for basic functionality. This is now modified to use pseudo-operators _hastag_ and _notag_. --- src/A3.cpp | 73 +++++++++++++++++++++++++---------------------------- src/Arg.cpp | 1 + src/Arg.h | 2 +- src/E9.cpp | 49 ++++++++++++++++++++++++----------- src/E9.h | 1 + 5 files changed, 72 insertions(+), 54 deletions(-) diff --git a/src/A3.cpp b/src/A3.cpp index 8eafc1dd0..a8b9113f8 100644 --- a/src/A3.cpp +++ b/src/A3.cpp @@ -74,30 +74,34 @@ static struct char associativity; } operators[] = { - // Operator Precedence Type Symbol Associativity - { "and", 5, 'b', 0, 'l' }, // Conjunction - { "xor", 4, 'b', 0, 'l' }, // Disjunction + // Operator Precedence Type Symbol Associativity + { "and", 5, 'b', 0, 'l' }, // Conjunction + { "xor", 4, 'b', 0, 'l' }, // Disjunction - { "or", 3, 'b', 0, 'l' }, // Disjunction - { "<=", 10, 'b', 1, 'l' }, // Less than or equal - { ">=", 10, 'b', 1, 'l' }, // Greater than or equal - { "!~", 9, 'b', 1, 'l' }, // Regex non-match - { "!=", 9, 'b', 1, 'l' }, // Inequal + { "or", 3, 'b', 0, 'l' }, // Disjunction + { "<=", 10, 'b', 1, 'l' }, // Less than or equal + { ">=", 10, 'b', 1, 'l' }, // Greater than or equal + { "!~", 9, 'b', 1, 'l' }, // Regex non-match + { "!=", 9, 'b', 1, 'l' }, // Inequal - { "=", 9, 'b', 1, 'l' }, // Equal -// { "^", 16, 'b', 1, 'r' }, // Exponent - { ">", 10, 'b', 1, 'l' }, // Greater than - { "~", 9, 'b', 1, 'l' }, // Regex match - { "!", 15, 'u', 1, 'r' }, // Not -// { "-", 15, 'u', 1, 'r' }, // Unary minus - { "*", 13, 'b', 1, 'l' }, // Multiplication - { "/", 13, 'b', 1, 'l' }, // Division -// { "%", 13, 'b', 1, 'l' }, // Modulus - { "+", 12, 'b', 1, 'l' }, // Addition - { "-", 12, 'b', 1, 'l' }, // Subtraction - { "<", 10, 'b', 1, 'l' }, // Less than - { "(", 0, 'b', 1, 'l' }, // Precedence start - { ")", 0, 'b', 1, 'l' }, // Precedence end + { "=", 9, 'b', 1, 'l' }, // Equal +// { "^", 16, 'b', 1, 'r' }, // Exponent + { ">", 10, 'b', 1, 'l' }, // Greater than + { "~", 9, 'b', 1, 'l' }, // Regex match + { "!", 15, 'u', 1, 'r' }, // Not + + { "_hastag_", 9, 'b', 0, 'l'}, // +tag [Pseudo-op] + { "_notag_", 9, 'b', 0, 'l'}, // -tag [Pseudo-op] + +// { "-", 15, 'u', 1, 'r' }, // Unary minus + { "*", 13, 'b', 1, 'l' }, // Multiplication + { "/", 13, 'b', 1, 'l' }, // Division +// { "%", 13, 'b', 1, 'l' }, // Modulus + { "+", 12, 'b', 1, 'l' }, // Addition + { "-", 12, 'b', 1, 'l' }, // Subtraction + { "<", 10, 'b', 1, 'l' }, // Less than + { "(", 0, 'b', 1, 'l' }, // Precedence start + { ")", 0, 'b', 1, 'l' }, // Precedence end }; #define NUM_MODIFIER_NAMES (sizeof (modifierNames) / sizeof (modifierNames[0])) @@ -1047,24 +1051,16 @@ const A3 A3::expand (const A3& input) const throw format (STRING_A3_UNKNOWN_ATTMOD, mod); } - // [+-]value --> tags ~/!~ value + // [+-]value --> tags _hastag_/_notag_ value else if (arg->_category == Arg::cat_tag) { char type; std::string value; extract_tag (arg->_raw, type, value); - expanded.push_back (Arg ("tags", Arg::type_string, Arg::cat_dom)); - expanded.push_back (Arg (type == '+' ? "~" : "!~", Arg::cat_op)); -#ifdef DARWIN + expanded.push_back (Arg ("tags", Arg::type_string, Arg::cat_dom_)); + expanded.push_back (Arg (type == '+' ? "_hastag_" : "_notag_", Arg::cat_op)); expanded.push_back (Arg (value, Arg::type_string, Arg::cat_literal)); -#else -#ifdef SOLARIS - expanded.push_back (Arg ("\\<" + value + "\\>", Arg::type_string, Arg::cat_rx)); -#else - expanded.push_back (Arg ("\\b" + value + "\\b", Arg::type_string, Arg::cat_rx)); -#endif -#endif } // word --> description ~ word @@ -2053,23 +2049,24 @@ void A3::dump (const std::string& label) color_map[Arg::cat_program] = Color ("bold blue on blue"); color_map[Arg::cat_command] = Color ("bold cyan on cyan"); color_map[Arg::cat_rc] = Color ("bold red on red"); - color_map[Arg::cat_override] = Color ("bold red on red"); + color_map[Arg::cat_override] = color_map[Arg::cat_rc]; color_map[Arg::cat_terminator] = Color ("bold yellow on yellow"); color_map[Arg::cat_literal] = Color ("white on gray4"); // Filter colors. color_map[Arg::cat_attr] = Color ("bold red on gray4"); - color_map[Arg::cat_attmod] = Color ("bold red on gray4"); + color_map[Arg::cat_attmod] = color_map[Arg::cat_attr]; color_map[Arg::cat_pattern] = Color ("cyan on gray4"); color_map[Arg::cat_subst] = Color ("bold cyan on gray4"); color_map[Arg::cat_op] = Color ("green on gray4"); color_map[Arg::type_string] = Color ("bold yellow on gray4"); - color_map[Arg::cat_rx] = Color ("bold yellow on gray4"); - color_map[Arg::type_date] = Color ("bold yellow on gray4"); + color_map[Arg::cat_rx] = color_map[Arg::type_string]; + color_map[Arg::type_date] = color_map[Arg::type_string]; color_map[Arg::cat_dom] = Color ("bold white on gray4"); + color_map[Arg::cat_dom_] = color_map[Arg::cat_dom]; color_map[Arg::type_duration] = Color ("magenta on gray4"); color_map[Arg::cat_id] = Color ("white on gray4"); - color_map[Arg::cat_uuid] = Color ("white on gray4"); + color_map[Arg::cat_uuid] = color_map[Arg::cat_id]; // Default. color_map[Arg::cat_none] = Color ("black on white"); diff --git a/src/Arg.cpp b/src/Arg.cpp index 47a47104f..6c3a789c7 100644 --- a/src/Arg.cpp +++ b/src/Arg.cpp @@ -178,6 +178,7 @@ const std::string Arg::category_name (Arg::category c) case Arg::cat_pattern: return "pattern"; case Arg::cat_tag: return "tag"; case Arg::cat_dom: return "dom"; + case Arg::cat_dom_: return "[dom]"; case Arg::cat_op: return "op"; case Arg::cat_literal: return "literal"; } diff --git a/src/Arg.h b/src/Arg.h index c052095ea..0cf095ca2 100644 --- a/src/Arg.h +++ b/src/Arg.h @@ -36,7 +36,7 @@ class Arg { public: - enum category {cat_none=1, cat_terminator, cat_program, cat_command, cat_rc, cat_override, cat_attr, cat_attmod, cat_id, cat_uuid, cat_subst, cat_pattern, cat_rx, cat_tag, cat_dom, cat_op, cat_literal}; + enum category {cat_none=1, cat_terminator, cat_program, cat_command, cat_rc, cat_override, cat_attr, cat_attmod, cat_id, cat_uuid, cat_subst, cat_pattern, cat_rx, cat_tag, cat_dom_, cat_dom, cat_op, cat_literal}; enum type {type_none=20, type_pseudo, type_bool, type_string, type_date, type_duration, type_number}; Arg (); diff --git a/src/E9.cpp b/src/E9.cpp index f86c818c6..2c868135f 100644 --- a/src/E9.cpp +++ b/src/E9.cpp @@ -135,21 +135,23 @@ void E9::eval (const Task& task, std::vector & value_stack) Arg left = value_stack.back (); value_stack.pop_back (); - if (arg->_raw == "and") operator_and (result, left, right); - else if (arg->_raw == "or") operator_or (result, left, right); - else if (arg->_raw == "xor") operator_xor (result, left, right); - else if (arg->_raw == "<") operator_lt (result, left, right); - else if (arg->_raw == "<=") operator_lte (result, left, right); - else if (arg->_raw == ">=") operator_gte (result, left, right); - 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, 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); - else if (arg->_raw == "-") operator_subtract (result, left, right); + if (arg->_raw == "and") operator_and (result, left, right); + else if (arg->_raw == "or") operator_or (result, left, right); + else if (arg->_raw == "xor") operator_xor (result, left, right); + else if (arg->_raw == "<") operator_lt (result, left, right); + else if (arg->_raw == "<=") operator_lte (result, left, right); + else if (arg->_raw == ">=") operator_gte (result, left, right); + 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, 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); + else if (arg->_raw == "-") operator_subtract (result, left, right); + else if (arg->_raw == "_hastag_") operator_hastag (result, right, false, task); + else if (arg->_raw == "_notag_") operator_hastag (result, right, true, task); else throw format (STRING_E9_UNSUPPORTED, arg->_raw); } @@ -628,6 +630,23 @@ void E9::operator_subtract (Arg& result, Arg& left, Arg& right) // std::cout << "# " << left << " " << right << " --> " << result << "\n"; } +//////////////////////////////////////////////////////////////////////////////// +void E9::operator_hastag ( + Arg& result, + Arg& right, + bool invert, + const Task& task) +{ + result._type = Arg::type_bool; + + if (task.hasTag (right._raw)) + result._value = invert ? "false" : "true"; + else + result._value = invert ? "true" : "false"; + + std::cout << "# tags" << (invert ? " " : " ") << right << " --> " << result << "\n"; +} + //////////////////////////////////////////////////////////////////////////////// const Arg E9::coerce (const Arg& input, const Arg::type type) { diff --git a/src/E9.h b/src/E9.h index a4335ca7c..2f85ed728 100644 --- a/src/E9.h +++ b/src/E9.h @@ -67,6 +67,7 @@ private: void operator_divide (Arg&, Arg&, Arg&); void operator_add (Arg&, Arg&, Arg&); void operator_subtract (Arg&, Arg&, Arg&); + void operator_hastag (Arg&, Arg&, bool, const Task&); const Arg coerce (const Arg&, const Arg::type); bool get_bool (const Arg&);