mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Expression Refactor
- Refactoring complete. Arg objects now uses enumerations for _type and _category, which should help with performance.
This commit is contained in:
parent
9086f51d29
commit
7aa4efef8d
6 changed files with 331 additions and 247 deletions
338
src/A3.cpp
338
src/A3.cpp
|
@ -160,8 +160,8 @@ void A3::capture_first (const std::string& arg)
|
|||
// immediately after the program and command arguments.
|
||||
std::vector <Arg>::iterator position;
|
||||
for (position = this->begin (); position != this->end (); ++position)
|
||||
if (position->_category != "program" &&
|
||||
position->_category != "command")
|
||||
if (position->_category != Arg::cat_program &&
|
||||
position->_category != Arg::cat_command)
|
||||
break;
|
||||
|
||||
this->insert (position, series.begin (), series.end ());
|
||||
|
@ -194,13 +194,13 @@ void A3::categorize ()
|
|||
if (arg->_raw == "--")
|
||||
{
|
||||
terminated = true;
|
||||
arg->_category = "terminator";
|
||||
arg->_category = Arg::cat_terminator;
|
||||
}
|
||||
|
||||
// program
|
||||
else if (arg == this->begin ())
|
||||
{
|
||||
arg->_category = "program";
|
||||
arg->_category = Arg::cat_program;
|
||||
|
||||
if ((arg->_raw.length () >= 3 &&
|
||||
arg->_raw.substr (arg->_raw.length () - 3) == "cal") ||
|
||||
|
@ -208,7 +208,7 @@ void A3::categorize ()
|
|||
arg->_raw.substr (arg->_raw.length () - 8) == "calendar"))
|
||||
{
|
||||
arg->_raw = "calendar";
|
||||
arg->_category = "command";
|
||||
arg->_category = Arg::cat_command;
|
||||
found_command = true;
|
||||
}
|
||||
}
|
||||
|
@ -218,26 +218,26 @@ void A3::categorize ()
|
|||
is_command (keywords, arg->_raw))
|
||||
{
|
||||
found_command = true;
|
||||
arg->_category = "command";
|
||||
arg->_category = Arg::cat_command;
|
||||
_read_only_command = context.commands[arg->_raw]->read_only ();
|
||||
}
|
||||
|
||||
// rc:<file>
|
||||
// Note: This doesn't break a sequence chain.
|
||||
else if (arg->_raw.substr (0, 3) == "rc:")
|
||||
arg->_category = "rc";
|
||||
arg->_category = Arg::cat_rc;
|
||||
|
||||
// rc.<name>:<value>
|
||||
// Note: This doesn't break a sequence chain.
|
||||
else if (arg->_raw.substr (0, 3) == "rc.")
|
||||
arg->_category = "override";
|
||||
arg->_category = Arg::cat_override;
|
||||
|
||||
// If the type is not known, it is treated as a generic word.
|
||||
}
|
||||
|
||||
// All post-termination arguments are simply words.
|
||||
else
|
||||
arg->_category = "literal";
|
||||
arg->_category = Arg::cat_literal;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -295,7 +295,7 @@ void A3::rc_override (
|
|||
std::vector <Arg>::iterator arg;
|
||||
for (arg = this->begin (); arg != this->end (); ++arg)
|
||||
{
|
||||
if (arg->_category == "rc")
|
||||
if (arg->_category == Arg::cat_rc)
|
||||
{
|
||||
rc = File (arg->_raw.substr (3));
|
||||
home = rc;
|
||||
|
@ -325,7 +325,7 @@ void A3::get_data_location (std::string& data)
|
|||
std::vector <Arg>::iterator arg;
|
||||
for (arg = this->begin (); arg != this->end (); ++arg)
|
||||
{
|
||||
if (arg->_category == "override")
|
||||
if (arg->_category == Arg::cat_override)
|
||||
{
|
||||
if (arg->_raw.substr (0, 16) == "rc.data.location" &&
|
||||
(arg->_raw[16] == ':' || arg->_raw[16] == '='))
|
||||
|
@ -404,7 +404,7 @@ void A3::apply_overrides ()
|
|||
std::vector <Arg>::iterator arg;
|
||||
for (arg = this->begin (); arg != this->end (); ++arg)
|
||||
{
|
||||
if (arg->_category == "override")
|
||||
if (arg->_category == Arg::cat_override)
|
||||
{
|
||||
std::string name;
|
||||
std::string value;
|
||||
|
@ -436,18 +436,18 @@ void A3::inject_defaults ()
|
|||
std::vector <Arg>::iterator arg;
|
||||
for (arg = this->begin (); arg != this->end (); ++arg)
|
||||
{
|
||||
if (arg->_category == "command")
|
||||
if (arg->_category == Arg::cat_command)
|
||||
found_command = true;
|
||||
|
||||
/* TODO no "id" or "uuid" categories exist at this time. Hmm.
|
||||
else if (arg->_category == "id" ||
|
||||
arg->_category == "uuid")
|
||||
else if (arg->_category == Arg::cat_id ||
|
||||
arg->_category == Arg::cat_uuid)
|
||||
found_sequence = true;
|
||||
*/
|
||||
|
||||
else if (arg->_category != "program" &&
|
||||
arg->_category != "override" &&
|
||||
arg->_category != "rc")
|
||||
else if (arg->_category != Arg::cat_program &&
|
||||
arg->_category != Arg::cat_override &&
|
||||
arg->_category != Arg::cat_rc)
|
||||
found_other = true;
|
||||
}
|
||||
|
||||
|
@ -522,7 +522,7 @@ bool A3::find_command (std::string& command) const
|
|||
std::vector <Arg>::const_iterator arg;
|
||||
for (arg = this->begin (); arg != this->end (); ++arg)
|
||||
{
|
||||
if (arg->_category == "command")
|
||||
if (arg->_category == Arg::cat_command)
|
||||
{
|
||||
command = arg->_raw;
|
||||
return true;
|
||||
|
@ -556,14 +556,14 @@ const A3 A3::extract_filter () const
|
|||
std::vector <Arg>::const_iterator arg;
|
||||
for (arg = this->begin (); arg != this->end (); ++arg)
|
||||
{
|
||||
if (arg->_category == "command")
|
||||
if (arg->_category == Arg::cat_command)
|
||||
before_command = false;
|
||||
|
||||
if (arg->_category == "program" ||
|
||||
arg->_category == "rc" ||
|
||||
arg->_category == "override" ||
|
||||
arg->_category == "command" ||
|
||||
arg->_category == "terminator")
|
||||
if (arg->_category == Arg::cat_program ||
|
||||
arg->_category == Arg::cat_rc ||
|
||||
arg->_category == Arg::cat_override ||
|
||||
arg->_category == Arg::cat_command ||
|
||||
arg->_category == Arg::cat_terminator)
|
||||
;
|
||||
|
||||
else if (before_command || _read_only_command)
|
||||
|
@ -585,14 +585,14 @@ const A3 A3::extract_modifications () const
|
|||
std::vector <Arg>::const_iterator arg;
|
||||
for (arg = this->begin (); arg != this->end (); ++arg)
|
||||
{
|
||||
if (arg->_category == "command")
|
||||
if (arg->_category == Arg::cat_command)
|
||||
before_command = false;
|
||||
|
||||
else if (! before_command)
|
||||
{
|
||||
// "rc" and "override" categories are not included.
|
||||
if (arg->_category == "rc" ||
|
||||
arg->_category == "override")
|
||||
// rc and override categories are not included.
|
||||
if (arg->_category == Arg::cat_rc ||
|
||||
arg->_category == Arg::cat_override)
|
||||
{
|
||||
;
|
||||
}
|
||||
|
@ -603,12 +603,12 @@ const A3 A3::extract_modifications () const
|
|||
// lines that do not otherwise include an id, such as:
|
||||
//
|
||||
// task add Read the article on page 2
|
||||
else if (arg->_category == "id" ||
|
||||
arg->_category == "uuid")
|
||||
else if (arg->_category == Arg::cat_id ||
|
||||
arg->_category == Arg::cat_uuid)
|
||||
{
|
||||
Arg downgrade (*arg);
|
||||
downgrade._type = "string";
|
||||
downgrade._category = "literal";
|
||||
downgrade._type = Arg::type_string;
|
||||
downgrade._category = Arg::cat_literal;
|
||||
mods.push_back (downgrade);
|
||||
}
|
||||
|
||||
|
@ -630,11 +630,11 @@ const std::vector <std::string> A3::extract_words () const
|
|||
std::vector <Arg>::const_iterator arg;
|
||||
for (arg = this->begin (); arg != this->end (); ++arg)
|
||||
{
|
||||
if (arg->_category == "program" ||
|
||||
arg->_category == "rc" ||
|
||||
arg->_category == "override" ||
|
||||
arg->_category == "command" ||
|
||||
arg->_category == "terminator")
|
||||
if (arg->_category == Arg::cat_program ||
|
||||
arg->_category == Arg::cat_rc ||
|
||||
arg->_category == Arg::cat_override ||
|
||||
arg->_category == Arg::cat_command ||
|
||||
arg->_category == Arg::cat_terminator)
|
||||
;
|
||||
|
||||
else
|
||||
|
@ -690,28 +690,28 @@ const A3 A3::tokenize (const A3& input) const
|
|||
else if (n.getQuoted ('"', s, true) ||
|
||||
n.getQuoted ('\'', s, true))
|
||||
{
|
||||
output.push_back (Arg (s, "string", "literal"));
|
||||
output.push_back (Arg (s, Arg::type_string, Arg::cat_literal));
|
||||
if (found_sequence)
|
||||
found_something_after_sequence = true;
|
||||
}
|
||||
|
||||
else if (is_subst (n, s))
|
||||
{
|
||||
output.push_back (Arg (s, "subst"));
|
||||
output.push_back (Arg (s, Arg::cat_subst));
|
||||
if (found_sequence)
|
||||
found_something_after_sequence = true;
|
||||
}
|
||||
|
||||
else if (is_pattern (n, s))
|
||||
{
|
||||
output.push_back (Arg (s, "", "pattern"));
|
||||
output.push_back (Arg (s, Arg::cat_pattern));
|
||||
if (found_sequence)
|
||||
found_something_after_sequence = true;
|
||||
}
|
||||
|
||||
else if (is_tag (n, s))
|
||||
{
|
||||
output.push_back (Arg (s, "", "tag"));
|
||||
output.push_back (Arg (s, Arg::cat_tag));
|
||||
if (found_sequence)
|
||||
found_something_after_sequence = true;
|
||||
}
|
||||
|
@ -720,7 +720,7 @@ const A3 A3::tokenize (const A3& input) const
|
|||
// Must be higher than operator.
|
||||
else if (n.getDate (date_format, t))
|
||||
{
|
||||
output.push_back (Arg (Date (t).toString (date_format), "date", "literal"));
|
||||
output.push_back (Arg (Date (t).toString (date_format), Arg::type_date, Arg::cat_literal));
|
||||
if (found_sequence)
|
||||
found_something_after_sequence = true;
|
||||
}
|
||||
|
@ -729,14 +729,14 @@ const A3 A3::tokenize (const A3& input) const
|
|||
// Must be higher than operator.
|
||||
else if (is_duration (n, s))
|
||||
{
|
||||
output.push_back (Arg (s, "duration", "literal"));
|
||||
output.push_back (Arg (s, Arg::type_duration, Arg::cat_literal));
|
||||
if (found_sequence)
|
||||
found_something_after_sequence = true;
|
||||
}
|
||||
|
||||
else if (n.getOneOf (operators, s))
|
||||
{
|
||||
output.push_back (Arg (s, "op"));
|
||||
output.push_back (Arg (s, Arg::cat_op));
|
||||
if (found_sequence)
|
||||
found_something_after_sequence = true;
|
||||
}
|
||||
|
@ -773,7 +773,7 @@ const A3 A3::tokenize (const A3& input) const
|
|||
|
||||
else if (n.getDateISO (t))
|
||||
{
|
||||
output.push_back (Arg (Date (t).toISO (), "date", "literal"));
|
||||
output.push_back (Arg (Date (t).toISO (), Arg::type_date, Arg::cat_literal));
|
||||
if (found_sequence)
|
||||
found_something_after_sequence = true;
|
||||
}
|
||||
|
@ -782,11 +782,11 @@ const A3 A3::tokenize (const A3& input) const
|
|||
{
|
||||
if (found_something_after_sequence)
|
||||
{
|
||||
output.push_back (Arg (s, "number", "literal"));
|
||||
output.push_back (Arg (s, Arg::type_number, Arg::cat_literal));
|
||||
}
|
||||
else
|
||||
{
|
||||
output.push_back (Arg (s, "number", "id"));
|
||||
output.push_back (Arg (s, Arg::type_number, Arg::cat_id));
|
||||
found_sequence = true;
|
||||
}
|
||||
}
|
||||
|
@ -795,25 +795,25 @@ const A3 A3::tokenize (const A3& input) const
|
|||
{
|
||||
if (found_something_after_sequence)
|
||||
{
|
||||
output.push_back (Arg (s, "string", "literal"));
|
||||
output.push_back (Arg (s, Arg::type_string, Arg::cat_literal));
|
||||
}
|
||||
else
|
||||
{
|
||||
output.push_back (Arg (s, "string", "uuid"));
|
||||
output.push_back (Arg (s, Arg::type_string, Arg::cat_uuid));
|
||||
found_sequence = true;
|
||||
}
|
||||
}
|
||||
|
||||
else if (is_number (n, d))
|
||||
{
|
||||
output.push_back (Arg (format (d), "number", "literal"));
|
||||
output.push_back (Arg (format (d), Arg::type_number, Arg::cat_literal));
|
||||
if (found_sequence)
|
||||
found_something_after_sequence = true;
|
||||
}
|
||||
|
||||
else if (is_integer (n, i))
|
||||
{
|
||||
output.push_back (Arg (format (i), "number", "literal"));
|
||||
output.push_back (Arg (format (i), Arg::type_number, Arg::cat_literal));
|
||||
if (found_sequence)
|
||||
found_something_after_sequence = true;
|
||||
}
|
||||
|
@ -822,9 +822,9 @@ const A3 A3::tokenize (const A3& input) const
|
|||
n.getWord (s))
|
||||
{
|
||||
if (Date::valid (s))
|
||||
output.push_back (Arg (s, "date", "literal"));
|
||||
output.push_back (Arg (s, Arg::type_date, Arg::cat_literal));
|
||||
else
|
||||
output.push_back (Arg (s, "string", "literal"));
|
||||
output.push_back (Arg (s, Arg::type_string, Arg::cat_literal));
|
||||
|
||||
if (found_sequence)
|
||||
found_something_after_sequence = true;
|
||||
|
@ -835,7 +835,7 @@ const A3 A3::tokenize (const A3& input) const
|
|||
if (! n.getUntilWS (s))
|
||||
n.getUntilEOS (s);
|
||||
|
||||
output.push_back (Arg (s, "string", "literal"));
|
||||
output.push_back (Arg (s, Arg::type_string, Arg::cat_literal));
|
||||
if (found_sequence)
|
||||
found_something_after_sequence = true;
|
||||
}
|
||||
|
@ -844,7 +844,7 @@ const A3 A3::tokenize (const A3& input) const
|
|||
{
|
||||
if (n.getUntilEOS (s))
|
||||
{
|
||||
output.push_back (Arg (s, "string", "literal"));
|
||||
output.push_back (Arg (s, Arg::type_string, Arg::cat_literal));
|
||||
if (found_sequence)
|
||||
found_something_after_sequence = true;
|
||||
}
|
||||
|
@ -867,7 +867,7 @@ const A3 A3::tokenize (const A3& input) const
|
|||
//
|
||||
const A3 A3::infix (const A3& input) const
|
||||
{
|
||||
Arg previous ("?", "op");
|
||||
Arg previous ("?", Arg::cat_op);
|
||||
|
||||
A3 modified;
|
||||
modified._limit = input._limit;
|
||||
|
@ -876,10 +876,10 @@ const A3 A3::infix (const A3& input) const
|
|||
for (arg = input.begin (); arg != input.end (); ++arg)
|
||||
{
|
||||
// Old-style filters need 'and' conjunctions.
|
||||
if ((previous._category != "op" || previous._raw == ")") &&
|
||||
(arg->_category != "op" || arg->_raw == "("))
|
||||
if ((previous._category != Arg::cat_op || previous._raw == ")") &&
|
||||
(arg->_category != Arg::cat_op || arg->_raw == "("))
|
||||
{
|
||||
modified.push_back (Arg ("and", "op"));
|
||||
modified.push_back (Arg ("and", Arg::cat_op));
|
||||
}
|
||||
|
||||
// Now insert the adjacent non-operator.
|
||||
|
@ -902,19 +902,19 @@ const A3 A3::expand (const A3& input) const
|
|||
for (arg = input.begin (); arg != input.end (); ++arg)
|
||||
{
|
||||
// name:value --> name = value
|
||||
if (arg->_category == "attr")
|
||||
if (arg->_category == Arg::cat_attr)
|
||||
{
|
||||
std::string name;
|
||||
std::string value;
|
||||
A3::extract_attr (arg->_raw, name, value);
|
||||
|
||||
expanded.push_back (Arg (name, "string", "dom"));
|
||||
expanded.push_back (Arg ("=", "op"));
|
||||
expanded.push_back (Arg (value, "string", "literal"));
|
||||
expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
|
||||
expanded.push_back (Arg ("=", Arg::cat_op));
|
||||
expanded.push_back (Arg (value, Arg::type_string, Arg::cat_literal));
|
||||
}
|
||||
|
||||
// name.mod:value --> name <op sub mod> value
|
||||
else if (arg->_category == "attmod")
|
||||
else if (arg->_category == Arg::cat_attmod)
|
||||
{
|
||||
std::string name;
|
||||
std::string mod;
|
||||
|
@ -925,133 +925,133 @@ const A3 A3::expand (const A3& input) const
|
|||
// name.before:value --> name < value
|
||||
if (mod == "before" || mod == "under" || mod == "below")
|
||||
{
|
||||
expanded.push_back (Arg (name, "string", "dom"));
|
||||
expanded.push_back (Arg ("<", "op"));
|
||||
expanded.push_back (Arg (value, "string", "literal"));
|
||||
expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
|
||||
expanded.push_back (Arg ("<", Arg::cat_op));
|
||||
expanded.push_back (Arg (value, Arg::type_string, Arg::cat_literal));
|
||||
}
|
||||
|
||||
// name.after:value --> name > value
|
||||
else if (mod == "after" || mod == "over" || mod == "above")
|
||||
{
|
||||
expanded.push_back (Arg (name, "string", "dom"));
|
||||
expanded.push_back (Arg (">", "op"));
|
||||
expanded.push_back (Arg (value, "string", "literal"));
|
||||
expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
|
||||
expanded.push_back (Arg (">", Arg::cat_op));
|
||||
expanded.push_back (Arg (value, Arg::type_string, Arg::cat_literal));
|
||||
}
|
||||
|
||||
// name.none: --> name == ""
|
||||
else if (mod == "none")
|
||||
{
|
||||
expanded.push_back (Arg (name, "string", "dom"));
|
||||
expanded.push_back (Arg ("=", "op"));
|
||||
expanded.push_back (Arg ("", "string", ""));
|
||||
expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
|
||||
expanded.push_back (Arg ("=", Arg::cat_op));
|
||||
expanded.push_back (Arg ("", Arg::type_string, Arg::cat_none));
|
||||
}
|
||||
|
||||
// name.any: --> name != ""
|
||||
else if (mod == "any")
|
||||
{
|
||||
expanded.push_back (Arg (name, "string", "dom"));
|
||||
expanded.push_back (Arg ("!=", "op"));
|
||||
expanded.push_back (Arg ("", "string", ""));
|
||||
expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
|
||||
expanded.push_back (Arg ("!=", Arg::cat_op));
|
||||
expanded.push_back (Arg ("", Arg::type_string, Arg::cat_none));
|
||||
}
|
||||
|
||||
// name.is:value --> name = value
|
||||
else if (mod == "is" || mod == "equals")
|
||||
{
|
||||
expanded.push_back (Arg (name, "string", "dom"));
|
||||
expanded.push_back (Arg ("=", "op"));
|
||||
expanded.push_back (Arg (value, "string", ""));
|
||||
expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
|
||||
expanded.push_back (Arg ("=", Arg::cat_op));
|
||||
expanded.push_back (Arg (value, Arg::type_string, Arg::cat_none));
|
||||
}
|
||||
|
||||
// name.isnt:value --> name != value
|
||||
else if (mod == "isnt" || mod == "not")
|
||||
{
|
||||
expanded.push_back (Arg (name, "string", "dom"));
|
||||
expanded.push_back (Arg ("!=", "op"));
|
||||
expanded.push_back (Arg (value, "string", ""));
|
||||
expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
|
||||
expanded.push_back (Arg ("!=", Arg::cat_op));
|
||||
expanded.push_back (Arg (value, Arg::type_string, Arg::cat_none));
|
||||
}
|
||||
|
||||
// name.has:value --> name ~ value
|
||||
else if (mod == "has" || mod == "contains")
|
||||
{
|
||||
expanded.push_back (Arg (name, "string", "dom"));
|
||||
expanded.push_back (Arg ("~", "op"));
|
||||
expanded.push_back (Arg (value, "string", "rx"));
|
||||
expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
|
||||
expanded.push_back (Arg ("~", Arg::cat_op));
|
||||
expanded.push_back (Arg (value, Arg::type_string, Arg::cat_rx));
|
||||
}
|
||||
|
||||
// name.hasnt:value --> name !~ value
|
||||
else if (mod == "hasnt")
|
||||
{
|
||||
expanded.push_back (Arg (name, "string", "dom"));
|
||||
expanded.push_back (Arg ("!~", "op"));
|
||||
expanded.push_back (Arg (value, "string", "rx"));
|
||||
expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
|
||||
expanded.push_back (Arg ("!~", Arg::cat_op));
|
||||
expanded.push_back (Arg (value, Arg::type_string, Arg::cat_rx));
|
||||
}
|
||||
|
||||
// name.startswith:value --> name ~ ^value
|
||||
else if (mod == "startswith" || mod == "left")
|
||||
{
|
||||
expanded.push_back (Arg (name, "string", "dom"));
|
||||
expanded.push_back (Arg ("~", "op"));
|
||||
expanded.push_back (Arg ("^" + value, "string", "rx"));
|
||||
expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
|
||||
expanded.push_back (Arg ("~", Arg::cat_op));
|
||||
expanded.push_back (Arg ("^" + value, Arg::type_string, Arg::cat_rx));
|
||||
}
|
||||
|
||||
// name.endswith:value --> name ~ value$
|
||||
else if (mod == "endswith" || mod == "right")
|
||||
{
|
||||
expanded.push_back (Arg (name, "string", "dom"));
|
||||
expanded.push_back (Arg ("~", "op"));
|
||||
expanded.push_back (Arg (value + "$", "string", "rx"));
|
||||
expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
|
||||
expanded.push_back (Arg ("~", Arg::cat_op));
|
||||
expanded.push_back (Arg (value + "$", Arg::type_string, Arg::cat_rx));
|
||||
}
|
||||
|
||||
// name.word:value --> name ~ \bvalue\b
|
||||
else if (mod == "word")
|
||||
{
|
||||
expanded.push_back (Arg (name, "string", "dom"));
|
||||
expanded.push_back (Arg ("~", "op"));
|
||||
expanded.push_back (Arg ("\\b" + value + "\\b", "string", "rx"));
|
||||
expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
|
||||
expanded.push_back (Arg ("~", Arg::cat_op));
|
||||
expanded.push_back (Arg ("\\b" + value + "\\b", Arg::type_string, Arg::cat_rx));
|
||||
}
|
||||
|
||||
// name.noword:value --> name !~ \bvalue\n
|
||||
else if (mod == "noword")
|
||||
{
|
||||
expanded.push_back (Arg (name, "string", "dom"));
|
||||
expanded.push_back (Arg ("!~", "op"));
|
||||
expanded.push_back (Arg ("\\b" + value + "\\b", "string", "rx"));
|
||||
expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
|
||||
expanded.push_back (Arg ("!~", Arg::cat_op));
|
||||
expanded.push_back (Arg ("\\b" + value + "\\b", Arg::type_string, Arg::cat_rx));
|
||||
}
|
||||
else
|
||||
throw std::string ("Error: unrecognized attribute modifier '") + mod + "'.";
|
||||
}
|
||||
|
||||
// [+-]value --> tags ~/!~ value
|
||||
else if (arg->_category == "tag")
|
||||
else if (arg->_category == Arg::cat_tag)
|
||||
{
|
||||
char type;
|
||||
std::string value;
|
||||
extract_tag (arg->_raw, type, value);
|
||||
|
||||
expanded.push_back (Arg ("tags", "string", "dom"));
|
||||
expanded.push_back (Arg (type == '+' ? "~" : "!~", "op"));
|
||||
expanded.push_back (Arg (value, "string", "literal"));
|
||||
expanded.push_back (Arg ("tags", Arg::type_string, Arg::cat_dom));
|
||||
expanded.push_back (Arg (type == '+' ? "~" : "!~", Arg::cat_op));
|
||||
expanded.push_back (Arg (value, Arg::type_string, Arg::cat_literal));
|
||||
}
|
||||
|
||||
// word --> description ~ word
|
||||
// Note: use of previous prevents desc~foo --> desc~desc~foo
|
||||
else if (arg->_category == "literal" &&
|
||||
previous->_category != "op")
|
||||
else if (arg->_category == Arg::cat_literal &&
|
||||
previous->_category != Arg::cat_op)
|
||||
{
|
||||
expanded.push_back (Arg ("description", "string", "dom"));
|
||||
expanded.push_back (Arg ("~", "op"));
|
||||
expanded.push_back (Arg (arg->_raw, "string", "literal"));
|
||||
expanded.push_back (Arg ("description", Arg::type_string, Arg::cat_dom));
|
||||
expanded.push_back (Arg ("~", Arg::cat_op));
|
||||
expanded.push_back (Arg (arg->_raw, Arg::type_string, Arg::cat_literal));
|
||||
}
|
||||
|
||||
// /pattern/ --> description ~ pattern
|
||||
else if (arg->_category == "pattern")
|
||||
else if (arg->_category == Arg::cat_pattern)
|
||||
{
|
||||
std::string value;
|
||||
extract_pattern (arg->_raw, value);
|
||||
|
||||
expanded.push_back (Arg ("description", "string", "dom"));
|
||||
expanded.push_back (Arg ("~", "op"));
|
||||
expanded.push_back (Arg (value, "string", "rx"));
|
||||
expanded.push_back (Arg ("description", Arg::type_string, Arg::cat_dom));
|
||||
expanded.push_back (Arg ("~", Arg::cat_op));
|
||||
expanded.push_back (Arg (value, Arg::type_string, Arg::cat_rx));
|
||||
}
|
||||
|
||||
// Default --> preserve
|
||||
|
@ -1079,10 +1079,10 @@ const A3 A3::sequence (const A3& input) const
|
|||
std::vector <Arg>::const_iterator arg;
|
||||
for (arg = input.begin (); arg != input.end (); ++arg)
|
||||
{
|
||||
if (arg->_category == "id")
|
||||
if (arg->_category == Arg::cat_id)
|
||||
extract_id (arg->_raw, ids);
|
||||
|
||||
else if (arg->_category == "uuid")
|
||||
else if (arg->_category == Arg::cat_uuid)
|
||||
extract_uuid (arg->_raw, uuids);
|
||||
}
|
||||
|
||||
|
@ -1093,42 +1093,42 @@ const A3 A3::sequence (const A3& input) const
|
|||
// Copy everything up to the first id/uuid.
|
||||
for (arg = input.begin (); arg != input.end (); ++arg)
|
||||
{
|
||||
if (arg->_category == "id" || arg->_category == "uuid")
|
||||
if (arg->_category == Arg::cat_id || arg->_category == Arg::cat_uuid)
|
||||
break;
|
||||
|
||||
sequenced.push_back (*arg);
|
||||
}
|
||||
|
||||
// Insert the algebraic form.
|
||||
sequenced.push_back (Arg ("(", "op"));
|
||||
sequenced.push_back (Arg ("(", Arg::cat_op));
|
||||
|
||||
for (unsigned int i = 0; i < ids.size (); ++i)
|
||||
{
|
||||
if (i)
|
||||
sequenced.push_back (Arg ("or", "op"));
|
||||
sequenced.push_back (Arg ("or", Arg::cat_op));
|
||||
|
||||
sequenced.push_back (Arg ("id", "number", "dom"));
|
||||
sequenced.push_back (Arg ("=", "op"));
|
||||
sequenced.push_back (Arg (format(ids[i]), "number", "literal"));
|
||||
sequenced.push_back (Arg ("id", Arg::type_number, Arg::cat_dom));
|
||||
sequenced.push_back (Arg ("=", Arg::cat_op));
|
||||
sequenced.push_back (Arg (format(ids[i]), Arg::type_number, Arg::cat_literal));
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < uuids.size (); ++i)
|
||||
{
|
||||
if (ids.size ())
|
||||
sequenced.push_back (Arg ("or", "op"));
|
||||
sequenced.push_back (Arg ("or", Arg::cat_op));
|
||||
|
||||
sequenced.push_back (Arg ("uuid", "string", "dom"));
|
||||
sequenced.push_back (Arg ("=", "op"));
|
||||
sequenced.push_back (Arg (uuids[i], "string", "literal"));
|
||||
sequenced.push_back (Arg ("uuid", Arg::type_string, Arg::cat_dom));
|
||||
sequenced.push_back (Arg ("=", Arg::cat_op));
|
||||
sequenced.push_back (Arg (uuids[i], Arg::type_string, Arg::cat_literal));
|
||||
}
|
||||
|
||||
sequenced.push_back (Arg (")", "op"));
|
||||
sequenced.push_back (Arg (")", Arg::cat_op));
|
||||
|
||||
// Now copy everything after the last id/uuid.
|
||||
bool found_id = false;
|
||||
for (arg = input.begin (); arg != input.end (); ++arg)
|
||||
{
|
||||
if (arg->_category == "id" || arg->_category == "uuid")
|
||||
if (arg->_category == Arg::cat_id || arg->_category == Arg::cat_uuid)
|
||||
found_id = true;
|
||||
|
||||
else if (found_id)
|
||||
|
@ -1271,16 +1271,16 @@ bool A3::is_attr (Nibbler& n, Arg& arg)
|
|||
*/
|
||||
|
||||
arg._raw = name + ':' + value;
|
||||
arg._category = "attr";
|
||||
arg._category = Arg::cat_attr;
|
||||
|
||||
// Most attributes are standard, some are pseudo-attributes, such as
|
||||
// 'limit:page', which is not represented by a column object, and
|
||||
// therefore not stored.
|
||||
Column* col = context.columns[name];
|
||||
if (col)
|
||||
arg._type = col->type ();
|
||||
arg._type = Arg::type_id (col->type ());
|
||||
else
|
||||
arg._type = "pseudo";
|
||||
arg._type = Arg::type_pseudo;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1340,8 +1340,8 @@ bool A3::is_attmod (Nibbler& n, Arg& arg)
|
|||
*/
|
||||
|
||||
arg._raw = name + '.' + modifier + ':' + value;
|
||||
arg._type = context.columns[name]->type ();
|
||||
arg._category = "attmod";
|
||||
arg._type = Arg::type_id (context.columns[name]->type ());
|
||||
arg._category = Arg::cat_attmod;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1437,7 +1437,7 @@ bool A3::is_dom (Nibbler& n, Arg& arg)
|
|||
}
|
||||
|
||||
arg._raw = result;
|
||||
arg._category = "dom";
|
||||
arg._category = Arg::cat_dom;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1452,8 +1452,8 @@ bool A3::is_dom (Nibbler& n, Arg& arg)
|
|||
{
|
||||
result = format (id) + '.' + name;
|
||||
arg._raw = result;
|
||||
arg._type = context.columns[name]->type ();
|
||||
arg._category = "dom";
|
||||
arg._type = Arg::type_id (context.columns[name]->type ());
|
||||
arg._category = Arg::cat_dom;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1467,8 +1467,8 @@ bool A3::is_dom (Nibbler& n, Arg& arg)
|
|||
is_attribute (name, name))
|
||||
{
|
||||
arg._raw = uuid + '.' + name;
|
||||
arg._type = context.columns[name]->type ();
|
||||
arg._category = "dom";
|
||||
arg._type = Arg::type_id (context.columns[name]->type ());
|
||||
arg._category = Arg::cat_dom;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1480,8 +1480,8 @@ bool A3::is_dom (Nibbler& n, Arg& arg)
|
|||
is_attribute (name, name))
|
||||
{
|
||||
arg._raw = name;
|
||||
arg._type = context.columns[name]->type ();
|
||||
arg._category = "dom";
|
||||
arg._type = Arg::type_id (context.columns[name]->type ());
|
||||
arg._category = Arg::cat_dom;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1990,30 +1990,30 @@ bool A3::is_operator (
|
|||
void A3::dump (const std::string& label)
|
||||
{
|
||||
// Set up a color mapping.
|
||||
std::map <std::string, Color> color_map;
|
||||
color_map["program"] = Color ("bold blue on blue");
|
||||
color_map["command"] = Color ("bold cyan on cyan");
|
||||
color_map["rc"] = Color ("bold red on red");
|
||||
color_map["override"] = Color ("bold red on red");
|
||||
color_map["terminator"] = Color ("bold yellow on yellow");
|
||||
color_map["literal"] = Color ("white on gray4");
|
||||
std::map <int, Color> color_map;
|
||||
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_terminator] = Color ("bold yellow on yellow");
|
||||
color_map[Arg::cat_literal] = Color ("white on gray4");
|
||||
|
||||
// Filter colors.
|
||||
color_map["attr"] = Color ("bold red on gray4");
|
||||
color_map["attmod"] = Color ("bold red on gray4");
|
||||
color_map["pattern"] = Color ("cyan on gray4");
|
||||
color_map["subst"] = Color ("bold cyan on gray4");
|
||||
color_map["op"] = Color ("green on gray4");
|
||||
color_map["string"] = Color ("bold yellow on gray4");
|
||||
color_map["rx"] = Color ("bold yellow on gray4");
|
||||
color_map["date"] = Color ("bold yellow on gray4");
|
||||
color_map["dom"] = Color ("bold white on gray4");
|
||||
color_map["duration"] = Color ("magenta on gray4");
|
||||
color_map["id"] = Color ("white on gray4");
|
||||
color_map["uuid"] = Color ("white on gray4");
|
||||
color_map[Arg::cat_attr] = Color ("bold red on gray4");
|
||||
color_map[Arg::cat_attmod] = Color ("bold red on gray4");
|
||||
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_dom] = Color ("bold white on gray4");
|
||||
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");
|
||||
|
||||
// Default.
|
||||
color_map["none"] = Color ("black on white");
|
||||
color_map[Arg::cat_none] = Color ("black on white");
|
||||
|
||||
Color color_debug (context.config.get ("color.debug"));
|
||||
std::stringstream out;
|
||||
|
@ -2033,21 +2033,21 @@ void A3::dump (const std::string& label)
|
|||
|
||||
for (unsigned int i = 0; i < this->size (); ++i)
|
||||
{
|
||||
std::string value = (*this)[i]._value;
|
||||
std::string raw = (*this)[i]._raw;
|
||||
std::string type = (*this)[i]._type;
|
||||
std::string category = (*this)[i]._category;
|
||||
std::string value = (*this)[i]._value;
|
||||
std::string raw = (*this)[i]._raw;
|
||||
Arg::type type = (*this)[i]._type;
|
||||
Arg::category category = (*this)[i]._category;
|
||||
|
||||
Color c;
|
||||
if (color_map[category].nontrivial ())
|
||||
c = color_map[category];
|
||||
else
|
||||
c = color_map["none"];
|
||||
c = color_map[Arg::cat_none];
|
||||
|
||||
view.set (0, i, value, c);
|
||||
view.set (1, i, raw, c);
|
||||
view.set (2, i, type, c);
|
||||
view.set (3, i, category, c);
|
||||
view.set (0, i, value, c);
|
||||
view.set (1, i, raw, c);
|
||||
view.set (2, i, Arg::type_name (type), c);
|
||||
view.set (3, i, Arg::category_name (category), c);
|
||||
}
|
||||
|
||||
out << view.render ();
|
||||
|
|
101
src/Arg.cpp
101
src/Arg.cpp
|
@ -34,8 +34,8 @@ extern Context context;
|
|||
Arg::Arg ()
|
||||
: _value ("")
|
||||
, _raw ("")
|
||||
, _type ("")
|
||||
, _category ("")
|
||||
, _type (type_none)
|
||||
, _category (cat_none)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -43,31 +43,31 @@ Arg::Arg ()
|
|||
Arg::Arg (const std::string& raw)
|
||||
: _value ("")
|
||||
, _raw (raw)
|
||||
, _type ("")
|
||||
, _category ("")
|
||||
, _type (type_none)
|
||||
, _category (cat_none)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Arg::Arg (
|
||||
const std::string& raw,
|
||||
const std::string& category)
|
||||
const category c)
|
||||
: _value ("")
|
||||
, _raw (raw)
|
||||
, _type ("")
|
||||
, _category (category)
|
||||
, _type (type_none)
|
||||
, _category (c)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Arg::Arg (
|
||||
const std::string& raw,
|
||||
const std::string& type,
|
||||
const std::string& category)
|
||||
const type t,
|
||||
const category c)
|
||||
: _value ("")
|
||||
, _raw (raw)
|
||||
, _type (type)
|
||||
, _category (category)
|
||||
, _type (t)
|
||||
, _category (c)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -104,4 +104,83 @@ bool Arg::operator== (const Arg& other) const
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const Arg::type Arg::type_id (const std::string& input)
|
||||
{
|
||||
if (input == "bool") return Arg::type_bool;
|
||||
else if (input == "string") return Arg::type_string;
|
||||
else if (input == "date") return Arg::type_date;
|
||||
else if (input == "duration") return Arg::type_duration;
|
||||
else if (input == "number") return Arg::type_number;
|
||||
else if (input == "pseudo") return Arg::type_pseudo;
|
||||
|
||||
return Arg::type_none;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const std::string Arg::type_name (Arg::type t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case Arg::type_none: return "none";
|
||||
case Arg::type_pseudo: return "pseudo";
|
||||
case Arg::type_bool: return "bool";
|
||||
case Arg::type_string: return "string";
|
||||
case Arg::type_date: return "date";
|
||||
case Arg::type_duration: return "duration";
|
||||
case Arg::type_number: return "number";
|
||||
}
|
||||
|
||||
return "none";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const Arg::category Arg::category_id (const std::string& input)
|
||||
{
|
||||
if (input == "terminator") return Arg::cat_terminator;
|
||||
else if (input == "program") return Arg::cat_program;
|
||||
else if (input == "command") return Arg::cat_command;
|
||||
else if (input == "rc") return Arg::cat_rc;
|
||||
else if (input == "rx") return Arg::cat_rx;
|
||||
else if (input == "override") return Arg::cat_override;
|
||||
else if (input == "attr") return Arg::cat_attr;
|
||||
else if (input == "attmod") return Arg::cat_attmod;
|
||||
else if (input == "id") return Arg::cat_id;
|
||||
else if (input == "uuid") return Arg::cat_uuid;
|
||||
else if (input == "subst") return Arg::cat_subst;
|
||||
else if (input == "pattern") return Arg::cat_pattern;
|
||||
else if (input == "tag") return Arg::cat_tag;
|
||||
else if (input == "dom") return Arg::cat_dom;
|
||||
else if (input == "op") return Arg::cat_op;
|
||||
else if (input == "literal") return Arg::cat_literal;
|
||||
|
||||
return Arg::cat_none;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const std::string Arg::category_name (Arg::category c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case Arg::cat_none: return "none";
|
||||
case Arg::cat_terminator: return "terminator";
|
||||
case Arg::cat_program: return "program";
|
||||
case Arg::cat_command: return "command";
|
||||
case Arg::cat_rc: return "rc";
|
||||
case Arg::cat_rx: return "rx";
|
||||
case Arg::cat_override: return "override";
|
||||
case Arg::cat_attr: return "attr";
|
||||
case Arg::cat_attmod: return "attmod";
|
||||
case Arg::cat_id: return "id";
|
||||
case Arg::cat_uuid: return "uuid";
|
||||
case Arg::cat_subst: return "subst";
|
||||
case Arg::cat_pattern: return "pattern";
|
||||
case Arg::cat_tag: return "tag";
|
||||
case Arg::cat_dom: return "dom";
|
||||
case Arg::cat_op: return "op";
|
||||
case Arg::cat_literal: return "literal";
|
||||
}
|
||||
|
||||
return "none";
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
17
src/Arg.h
17
src/Arg.h
|
@ -35,19 +35,28 @@
|
|||
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 type {type_none=20, type_pseudo, type_bool, type_string, type_date, type_duration, type_number};
|
||||
|
||||
Arg ();
|
||||
Arg (const std::string&);
|
||||
Arg (const std::string&, const std::string&);
|
||||
Arg (const std::string&, const std::string&, const std::string&);
|
||||
Arg (const std::string&, const category);
|
||||
Arg (const std::string&, const type, const category);
|
||||
Arg (const Arg&);
|
||||
Arg& operator= (const Arg&);
|
||||
bool operator== (const Arg&) const;
|
||||
|
||||
static const type type_id (const std::string&);
|
||||
static const std::string type_name (type);
|
||||
|
||||
static const category category_id (const std::string&);
|
||||
static const std::string category_name (category);
|
||||
|
||||
public:
|
||||
std::string _value; // Interpreted value
|
||||
std::string _raw; // Raw input token, never modified
|
||||
std::string _type; // Data type
|
||||
std::string _category; // Categorized argument
|
||||
type _type; // Data type
|
||||
category _category; // Categorized argument
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
114
src/E9.cpp
114
src/E9.cpp
|
@ -36,10 +36,10 @@ extern Context context;
|
|||
|
||||
std::ostream& operator<< (std::ostream& out, const Arg& term)
|
||||
{
|
||||
out << term._value << "|"
|
||||
<< term._raw << "|"
|
||||
<< term._type << "|"
|
||||
<< term._category;
|
||||
out << term._value << "|"
|
||||
<< term._raw << "|"
|
||||
<< Arg::type_name (term._type) << "|"
|
||||
<< Arg::category_name (term._category);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ bool E9::evalFilter (const Task& task)
|
|||
// Coerce result to Boolean.
|
||||
Arg result = value_stack.back ();
|
||||
value_stack.pop_back ();
|
||||
return get_bool (coerce (result, "bool"));
|
||||
return get_bool (coerce (result, Arg::type_bool));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -94,7 +94,7 @@ void E9::eval (const Task& task, std::vector <Arg>& value_stack)
|
|||
std::vector <Arg>::const_iterator arg;
|
||||
for (arg = _terms.begin (); arg != _terms.end (); ++arg)
|
||||
{
|
||||
if (arg->_category == "op")
|
||||
if (arg->_category == Arg::cat_op)
|
||||
{
|
||||
Arg result;
|
||||
|
||||
|
@ -156,22 +156,22 @@ void E9::eval (const Task& task, std::vector <Arg>& value_stack)
|
|||
Arg operand (*arg);
|
||||
|
||||
// Expand the value if possible.
|
||||
if (operand._category == "dom" && _dom)
|
||||
if (operand._category == Arg::cat_dom && _dom)
|
||||
{
|
||||
operand._value = context.dom.get (operand._raw, task);
|
||||
operand._category = "literal";
|
||||
operand._category = Arg::cat_literal;
|
||||
}
|
||||
else if (operand._type == "date" &&
|
||||
operand._category == "literal")
|
||||
else if (operand._type == Arg::type_date &&
|
||||
operand._category == Arg::cat_literal)
|
||||
{
|
||||
operand._value = Date (operand._raw, _dateformat).toEpochString ();
|
||||
operand._category = "literal";
|
||||
operand._category = Arg::cat_literal;
|
||||
}
|
||||
else if (operand._type == "duration" &&
|
||||
operand._category == "literal")
|
||||
else if (operand._type == Arg::type_duration &&
|
||||
operand._category == Arg::cat_literal)
|
||||
{
|
||||
operand._value = (std::string)Duration (operand._raw);
|
||||
operand._category = "literal";
|
||||
operand._category = Arg::cat_literal;
|
||||
}
|
||||
else
|
||||
operand._value = operand._raw;
|
||||
|
@ -189,10 +189,10 @@ void E9::eval (const Task& task, std::vector <Arg>& value_stack)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
bool E9::eval_match (Arg& left, Arg& right, bool case_sensitive)
|
||||
{
|
||||
if (right._category == "rx")
|
||||
if (right._category == Arg::cat_rx)
|
||||
{
|
||||
left = coerce (left, "string");
|
||||
right = coerce (right, "string");
|
||||
left = coerce (left, Arg::type_string);
|
||||
right = coerce (right, Arg::type_string);
|
||||
|
||||
// Create a cached entry, if it does not already exist.
|
||||
if (_regexes.find (right._value) == _regexes.end ())
|
||||
|
@ -203,8 +203,8 @@ bool E9::eval_match (Arg& left, Arg& right, bool case_sensitive)
|
|||
}
|
||||
else
|
||||
{
|
||||
left = coerce (left, "string");
|
||||
right = coerce (right, "string");
|
||||
left = coerce (left, Arg::type_string);
|
||||
right = coerce (right, Arg::type_string);
|
||||
if (find (left._value, right._value, (bool) case_sensitive) != std::string::npos)
|
||||
return true;
|
||||
}
|
||||
|
@ -216,7 +216,7 @@ bool E9::eval_match (Arg& left, Arg& right, bool case_sensitive)
|
|||
void E9::operator_not (Arg& result, Arg& right)
|
||||
{
|
||||
// TODO This is not right.
|
||||
result = Arg (right._value, "bool", right._category);
|
||||
result = Arg (right._value, Arg::type_bool, right._category);
|
||||
|
||||
// std::cout << "# <operator_not> " << right << " --> " << result << "\n";
|
||||
}
|
||||
|
@ -226,13 +226,12 @@ void E9::operator_and (Arg& result, Arg& left, Arg& right)
|
|||
{
|
||||
// Assume failure.
|
||||
result._value = "false";
|
||||
result._category = "bool";
|
||||
result._type = Arg::type_bool;
|
||||
|
||||
if (coerce (left, "bool")._value == "true" &&
|
||||
coerce (right, "bool")._value == "true" )
|
||||
if (coerce (left, Arg::type_bool)._value == "true" &&
|
||||
coerce (right, Arg::type_bool)._value == "true" )
|
||||
{
|
||||
result._value = "true";
|
||||
result._category = "bool";
|
||||
}
|
||||
|
||||
// std::cout << "# " << left << " <operator_and> " << right << " --> " << result << "\n";
|
||||
|
@ -243,13 +242,12 @@ void E9::operator_or (Arg& result, Arg& left, Arg& right)
|
|||
{
|
||||
// Assume failure.
|
||||
result._value = "false";
|
||||
result._category = "bool";
|
||||
result._type = Arg::type_bool;
|
||||
|
||||
if (coerce (left, "bool")._value == "true" ||
|
||||
coerce (right, "bool")._value == "true" )
|
||||
if (coerce (left, Arg::type_bool)._value == "true" ||
|
||||
coerce (right, Arg::type_bool)._value == "true" )
|
||||
{
|
||||
result._value = "true";
|
||||
result._category = "bool";
|
||||
}
|
||||
|
||||
// std::cout << "# " << left << " <operator_or> " << right << " --> " << result << "\n";
|
||||
|
@ -260,16 +258,15 @@ void E9::operator_xor (Arg& result, Arg& left, Arg& right)
|
|||
{
|
||||
// Assume failure.
|
||||
result._value = "false";
|
||||
result._category = "bool";
|
||||
result._type = Arg::type_bool;
|
||||
|
||||
bool bool_left = coerce (left, "bool")._value == "true";
|
||||
bool bool_right = coerce (right, "bool")._value == "true";
|
||||
bool bool_left = coerce (left, Arg::type_bool)._value == "true";
|
||||
bool bool_right = coerce (right, Arg::type_bool)._value == "true";
|
||||
|
||||
if ((bool_left && !bool_right) ||
|
||||
(!bool_left && bool_right))
|
||||
{
|
||||
result._value = "true";
|
||||
result._category = "bool";
|
||||
}
|
||||
|
||||
// std::cout << "# " << left << " <operator_xor> " << right << " --> " << result << "\n";
|
||||
|
@ -285,8 +282,8 @@ void E9::operator_lt (Arg& result, Arg& left, Arg& right)
|
|||
else if (left._value == "" && right._value != "") result._value = "true";
|
||||
else result._value = "false";
|
||||
}
|
||||
else if (left._category == "date" ||
|
||||
right._category == "date")
|
||||
else if (left._type == Arg::type_date ||
|
||||
right._type == Arg::type_date)
|
||||
{
|
||||
Date left_date (left._value, _dateformat);
|
||||
Date right_date (right._value, _dateformat);
|
||||
|
@ -302,7 +299,7 @@ void E9::operator_lt (Arg& result, Arg& left, Arg& right)
|
|||
: "false";
|
||||
}
|
||||
|
||||
result._category = "bool";
|
||||
result._type = Arg::type_bool;
|
||||
|
||||
// std::cout << "# " << left << " <operator_lt> " << right << " --> " << result << "\n";
|
||||
}
|
||||
|
@ -318,8 +315,8 @@ void E9::operator_lte (Arg& result, Arg& left, Arg& right)
|
|||
else if (left._value == "" ) result._value = "true";
|
||||
else result._value = "false";
|
||||
}
|
||||
else if (left._category == "date" ||
|
||||
right._category == "date")
|
||||
else if (left._type == Arg::type_date ||
|
||||
right._type == Arg::type_date)
|
||||
{
|
||||
Date left_date (left._value, _dateformat);
|
||||
Date right_date (right._value, _dateformat);
|
||||
|
@ -335,7 +332,7 @@ void E9::operator_lte (Arg& result, Arg& left, Arg& right)
|
|||
: "false";
|
||||
}
|
||||
|
||||
result._category = "bool";
|
||||
result._type = Arg::type_bool;
|
||||
|
||||
// std::cout << "# " << left << " <operator_lte> " << right << " --> " << result << "\n";
|
||||
}
|
||||
|
@ -351,8 +348,8 @@ void E9::operator_gte (Arg& result, Arg& left, Arg& right)
|
|||
else if ( right._value == "" ) result._value = "true";
|
||||
else result._value = "false";
|
||||
}
|
||||
else if (left._category == "date" ||
|
||||
right._category == "date")
|
||||
else if (left._type == Arg::type_date ||
|
||||
right._type == Arg::type_date)
|
||||
{
|
||||
Date left_date (left._value, _dateformat);
|
||||
Date right_date (right._value, _dateformat);
|
||||
|
@ -368,7 +365,7 @@ void E9::operator_gte (Arg& result, Arg& left, Arg& right)
|
|||
: "false";
|
||||
}
|
||||
|
||||
result._category = "bool";
|
||||
result._type = Arg::type_bool;
|
||||
|
||||
// std::cout << "# " << left << " <operator_gte> " << right << " --> " << result << "\n";
|
||||
}
|
||||
|
@ -383,8 +380,8 @@ void E9::operator_gt (Arg& result, Arg& left, Arg& right)
|
|||
else if (left._value != "" && right._value == "") result._value = "true";
|
||||
else result._value = "false";
|
||||
}
|
||||
else if (left._category == "date" ||
|
||||
right._category == "date")
|
||||
else if (left._type == Arg::type_date ||
|
||||
right._type == Arg::type_date)
|
||||
{
|
||||
Date left_date (left._value, _dateformat);
|
||||
Date right_date (right._value, _dateformat);
|
||||
|
@ -400,7 +397,7 @@ void E9::operator_gt (Arg& result, Arg& left, Arg& right)
|
|||
: "false";
|
||||
}
|
||||
|
||||
result._category = "bool";
|
||||
result._type = Arg::type_bool;
|
||||
|
||||
// std::cout << "# " << left << " <operator_gt> " << right << " --> " << result << "\n";
|
||||
}
|
||||
|
@ -429,14 +426,14 @@ void E9::operator_equal (
|
|||
{
|
||||
// Assume failure.
|
||||
result._value = "false";
|
||||
result._category = "bool";
|
||||
result._type = Arg::type_bool;
|
||||
|
||||
// 'project' and 'recur' attributes are matched leftmost.
|
||||
if (left._raw == "project" || left._raw == "recur")
|
||||
{
|
||||
// std::cout << "# project/recur matching\n";
|
||||
coerce (left, "string");
|
||||
coerce (right, "string");
|
||||
coerce (left, Arg::type_string);
|
||||
coerce (right, Arg::type_string);
|
||||
|
||||
if (right._value.length () <= left._value.length () &&
|
||||
compare (right._value,
|
||||
|
@ -444,13 +441,12 @@ void E9::operator_equal (
|
|||
case_sensitive))
|
||||
{
|
||||
result._raw = "true";
|
||||
result._category = "bool";
|
||||
}
|
||||
}
|
||||
|
||||
// Dates.
|
||||
else if (left._category == "date" ||
|
||||
right._category == "date")
|
||||
else if (left._type == Arg::type_date ||
|
||||
right._type == Arg::type_date)
|
||||
{
|
||||
// std::cout << "# date matching\n";
|
||||
Date left_date (left._value, _dateformat);
|
||||
|
@ -472,7 +468,7 @@ void E9::operator_equal (
|
|||
if (left._value == right._value)
|
||||
{
|
||||
result._value = "true";
|
||||
result._category = "bool";
|
||||
result._type = Arg::type_bool;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,7 +482,7 @@ void E9::operator_match (
|
|||
Arg& right,
|
||||
bool case_sensitive)
|
||||
{
|
||||
result._category = "bool";
|
||||
result._type = Arg::type_bool;
|
||||
result._value = eval_match (left, right, case_sensitive)
|
||||
? "true"
|
||||
: "false";
|
||||
|
@ -511,7 +507,7 @@ void E9::operator_nomatch (
|
|||
Arg& right,
|
||||
bool case_sensitive)
|
||||
{
|
||||
result._category = "bool";
|
||||
result._type = Arg::type_bool;
|
||||
result._value = eval_match (left, right, case_sensitive)
|
||||
? "false"
|
||||
: "true";
|
||||
|
@ -544,21 +540,21 @@ void E9::operator_subtract (Arg& result, Arg& left, Arg& right)
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
const Arg E9::coerce (const Arg& input, const std::string& type)
|
||||
const Arg E9::coerce (const Arg& input, const Arg::type type)
|
||||
{
|
||||
Arg result;
|
||||
|
||||
if (type == "bool")
|
||||
if (type == Arg::type_bool)
|
||||
{
|
||||
result._category = "bool";
|
||||
result._type = Arg::type_bool;
|
||||
result._value = get_bool (input) ? "true" : "false";
|
||||
}
|
||||
|
||||
if (type == "string")
|
||||
if (type == Arg::type_string)
|
||||
{
|
||||
// TODO Convert date?
|
||||
result._value = input._value;
|
||||
result._category = "string";
|
||||
result._value = input._value;
|
||||
result._type = Arg::type_string;
|
||||
}
|
||||
|
||||
// TODO Date
|
||||
|
|
2
src/E9.h
2
src/E9.h
|
@ -66,7 +66,7 @@ private:
|
|||
void operator_add (Arg&, Arg&, Arg&);
|
||||
void operator_subtract (Arg&, Arg&, Arg&);
|
||||
|
||||
const Arg coerce (const Arg&, const std::string&);
|
||||
const Arg coerce (const Arg&, const Arg::type);
|
||||
bool get_bool (const Arg&);
|
||||
|
||||
private:
|
||||
|
|
|
@ -411,7 +411,7 @@ void Command::modify_task (
|
|||
{
|
||||
// Attributes are essentially name:value pairs, and correspond directly
|
||||
// to stored attributes.
|
||||
if (arg->_category == "attr")
|
||||
if (arg->_category == Arg::cat_attr)
|
||||
{
|
||||
std::string name;
|
||||
std::string value;
|
||||
|
@ -477,7 +477,7 @@ void Command::modify_task (
|
|||
// Tags need special handling because they are essentially a vector stored
|
||||
// in a single string, therefore Task::{add,remove}Tag must be called as
|
||||
// appropriate.
|
||||
else if (arg->_category == "tag")
|
||||
else if (arg->_category == Arg::cat_tag)
|
||||
{
|
||||
char type;
|
||||
std::string value;
|
||||
|
@ -490,7 +490,7 @@ void Command::modify_task (
|
|||
}
|
||||
|
||||
// Substitutions.
|
||||
else if (arg->_category == "subst")
|
||||
else if (arg->_category == Arg::cat_subst)
|
||||
{
|
||||
std::string from;
|
||||
std::string to;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue