Expression Refactor

- Refactoring complete.  Arg objects now uses enumerations for _type
  and _category, which should help with performance.
This commit is contained in:
Paul Beckingham 2011-08-21 01:06:50 -04:00
parent 9086f51d29
commit 7aa4efef8d
6 changed files with 331 additions and 247 deletions

View file

@ -160,8 +160,8 @@ void A3::capture_first (const std::string& arg)
// immediately after the program and command arguments. // immediately after the program and command arguments.
std::vector <Arg>::iterator position; std::vector <Arg>::iterator position;
for (position = this->begin (); position != this->end (); ++position) for (position = this->begin (); position != this->end (); ++position)
if (position->_category != "program" && if (position->_category != Arg::cat_program &&
position->_category != "command") position->_category != Arg::cat_command)
break; break;
this->insert (position, series.begin (), series.end ()); this->insert (position, series.begin (), series.end ());
@ -194,13 +194,13 @@ void A3::categorize ()
if (arg->_raw == "--") if (arg->_raw == "--")
{ {
terminated = true; terminated = true;
arg->_category = "terminator"; arg->_category = Arg::cat_terminator;
} }
// program // program
else if (arg == this->begin ()) else if (arg == this->begin ())
{ {
arg->_category = "program"; arg->_category = Arg::cat_program;
if ((arg->_raw.length () >= 3 && if ((arg->_raw.length () >= 3 &&
arg->_raw.substr (arg->_raw.length () - 3) == "cal") || 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.substr (arg->_raw.length () - 8) == "calendar"))
{ {
arg->_raw = "calendar"; arg->_raw = "calendar";
arg->_category = "command"; arg->_category = Arg::cat_command;
found_command = true; found_command = true;
} }
} }
@ -218,26 +218,26 @@ void A3::categorize ()
is_command (keywords, arg->_raw)) is_command (keywords, arg->_raw))
{ {
found_command = true; found_command = true;
arg->_category = "command"; arg->_category = Arg::cat_command;
_read_only_command = context.commands[arg->_raw]->read_only (); _read_only_command = context.commands[arg->_raw]->read_only ();
} }
// rc:<file> // rc:<file>
// Note: This doesn't break a sequence chain. // Note: This doesn't break a sequence chain.
else if (arg->_raw.substr (0, 3) == "rc:") else if (arg->_raw.substr (0, 3) == "rc:")
arg->_category = "rc"; arg->_category = Arg::cat_rc;
// rc.<name>:<value> // rc.<name>:<value>
// Note: This doesn't break a sequence chain. // Note: This doesn't break a sequence chain.
else if (arg->_raw.substr (0, 3) == "rc.") 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. // If the type is not known, it is treated as a generic word.
} }
// All post-termination arguments are simply words. // All post-termination arguments are simply words.
else else
arg->_category = "literal"; arg->_category = Arg::cat_literal;
} }
} }
@ -295,7 +295,7 @@ void A3::rc_override (
std::vector <Arg>::iterator arg; std::vector <Arg>::iterator arg;
for (arg = this->begin (); arg != this->end (); ++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)); rc = File (arg->_raw.substr (3));
home = rc; home = rc;
@ -325,7 +325,7 @@ void A3::get_data_location (std::string& data)
std::vector <Arg>::iterator arg; std::vector <Arg>::iterator arg;
for (arg = this->begin (); arg != this->end (); ++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" && if (arg->_raw.substr (0, 16) == "rc.data.location" &&
(arg->_raw[16] == ':' || arg->_raw[16] == '=')) (arg->_raw[16] == ':' || arg->_raw[16] == '='))
@ -404,7 +404,7 @@ void A3::apply_overrides ()
std::vector <Arg>::iterator arg; std::vector <Arg>::iterator arg;
for (arg = this->begin (); arg != this->end (); ++arg) for (arg = this->begin (); arg != this->end (); ++arg)
{ {
if (arg->_category == "override") if (arg->_category == Arg::cat_override)
{ {
std::string name; std::string name;
std::string value; std::string value;
@ -436,18 +436,18 @@ void A3::inject_defaults ()
std::vector <Arg>::iterator arg; std::vector <Arg>::iterator arg;
for (arg = this->begin (); arg != this->end (); ++arg) for (arg = this->begin (); arg != this->end (); ++arg)
{ {
if (arg->_category == "command") if (arg->_category == Arg::cat_command)
found_command = true; found_command = true;
/* TODO no "id" or "uuid" categories exist at this time. Hmm. /* TODO no "id" or "uuid" categories exist at this time. Hmm.
else if (arg->_category == "id" || else if (arg->_category == Arg::cat_id ||
arg->_category == "uuid") arg->_category == Arg::cat_uuid)
found_sequence = true; found_sequence = true;
*/ */
else if (arg->_category != "program" && else if (arg->_category != Arg::cat_program &&
arg->_category != "override" && arg->_category != Arg::cat_override &&
arg->_category != "rc") arg->_category != Arg::cat_rc)
found_other = true; found_other = true;
} }
@ -522,7 +522,7 @@ bool A3::find_command (std::string& command) const
std::vector <Arg>::const_iterator arg; std::vector <Arg>::const_iterator arg;
for (arg = this->begin (); arg != this->end (); ++arg) for (arg = this->begin (); arg != this->end (); ++arg)
{ {
if (arg->_category == "command") if (arg->_category == Arg::cat_command)
{ {
command = arg->_raw; command = arg->_raw;
return true; return true;
@ -556,14 +556,14 @@ const A3 A3::extract_filter () const
std::vector <Arg>::const_iterator arg; std::vector <Arg>::const_iterator arg;
for (arg = this->begin (); arg != this->end (); ++arg) for (arg = this->begin (); arg != this->end (); ++arg)
{ {
if (arg->_category == "command") if (arg->_category == Arg::cat_command)
before_command = false; before_command = false;
if (arg->_category == "program" || if (arg->_category == Arg::cat_program ||
arg->_category == "rc" || arg->_category == Arg::cat_rc ||
arg->_category == "override" || arg->_category == Arg::cat_override ||
arg->_category == "command" || arg->_category == Arg::cat_command ||
arg->_category == "terminator") arg->_category == Arg::cat_terminator)
; ;
else if (before_command || _read_only_command) else if (before_command || _read_only_command)
@ -585,14 +585,14 @@ const A3 A3::extract_modifications () const
std::vector <Arg>::const_iterator arg; std::vector <Arg>::const_iterator arg;
for (arg = this->begin (); arg != this->end (); ++arg) for (arg = this->begin (); arg != this->end (); ++arg)
{ {
if (arg->_category == "command") if (arg->_category == Arg::cat_command)
before_command = false; before_command = false;
else if (! before_command) else if (! before_command)
{ {
// "rc" and "override" categories are not included. // rc and override categories are not included.
if (arg->_category == "rc" || if (arg->_category == Arg::cat_rc ||
arg->_category == "override") 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: // lines that do not otherwise include an id, such as:
// //
// task add Read the article on page 2 // task add Read the article on page 2
else if (arg->_category == "id" || else if (arg->_category == Arg::cat_id ||
arg->_category == "uuid") arg->_category == Arg::cat_uuid)
{ {
Arg downgrade (*arg); Arg downgrade (*arg);
downgrade._type = "string"; downgrade._type = Arg::type_string;
downgrade._category = "literal"; downgrade._category = Arg::cat_literal;
mods.push_back (downgrade); mods.push_back (downgrade);
} }
@ -630,11 +630,11 @@ const std::vector <std::string> A3::extract_words () const
std::vector <Arg>::const_iterator arg; std::vector <Arg>::const_iterator arg;
for (arg = this->begin (); arg != this->end (); ++arg) for (arg = this->begin (); arg != this->end (); ++arg)
{ {
if (arg->_category == "program" || if (arg->_category == Arg::cat_program ||
arg->_category == "rc" || arg->_category == Arg::cat_rc ||
arg->_category == "override" || arg->_category == Arg::cat_override ||
arg->_category == "command" || arg->_category == Arg::cat_command ||
arg->_category == "terminator") arg->_category == Arg::cat_terminator)
; ;
else else
@ -690,28 +690,28 @@ const A3 A3::tokenize (const A3& input) const
else if (n.getQuoted ('"', s, true) || else if (n.getQuoted ('"', s, true) ||
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) if (found_sequence)
found_something_after_sequence = true; found_something_after_sequence = true;
} }
else if (is_subst (n, s)) else if (is_subst (n, s))
{ {
output.push_back (Arg (s, "subst")); output.push_back (Arg (s, Arg::cat_subst));
if (found_sequence) if (found_sequence)
found_something_after_sequence = true; found_something_after_sequence = true;
} }
else if (is_pattern (n, s)) else if (is_pattern (n, s))
{ {
output.push_back (Arg (s, "", "pattern")); output.push_back (Arg (s, Arg::cat_pattern));
if (found_sequence) if (found_sequence)
found_something_after_sequence = true; found_something_after_sequence = true;
} }
else if (is_tag (n, s)) else if (is_tag (n, s))
{ {
output.push_back (Arg (s, "", "tag")); output.push_back (Arg (s, Arg::cat_tag));
if (found_sequence) if (found_sequence)
found_something_after_sequence = true; found_something_after_sequence = true;
} }
@ -720,7 +720,7 @@ const A3 A3::tokenize (const A3& input) const
// Must be higher than operator. // Must be higher than operator.
else if (n.getDate (date_format, t)) 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) if (found_sequence)
found_something_after_sequence = true; found_something_after_sequence = true;
} }
@ -729,14 +729,14 @@ const A3 A3::tokenize (const A3& input) const
// Must be higher than operator. // Must be higher than operator.
else if (is_duration (n, s)) 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) if (found_sequence)
found_something_after_sequence = true; found_something_after_sequence = true;
} }
else if (n.getOneOf (operators, s)) else if (n.getOneOf (operators, s))
{ {
output.push_back (Arg (s, "op")); output.push_back (Arg (s, Arg::cat_op));
if (found_sequence) if (found_sequence)
found_something_after_sequence = true; found_something_after_sequence = true;
} }
@ -773,7 +773,7 @@ const A3 A3::tokenize (const A3& input) const
else if (n.getDateISO (t)) 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) if (found_sequence)
found_something_after_sequence = true; found_something_after_sequence = true;
} }
@ -782,11 +782,11 @@ const A3 A3::tokenize (const A3& input) const
{ {
if (found_something_after_sequence) if (found_something_after_sequence)
{ {
output.push_back (Arg (s, "number", "literal")); output.push_back (Arg (s, Arg::type_number, Arg::cat_literal));
} }
else else
{ {
output.push_back (Arg (s, "number", "id")); output.push_back (Arg (s, Arg::type_number, Arg::cat_id));
found_sequence = true; found_sequence = true;
} }
} }
@ -795,25 +795,25 @@ const A3 A3::tokenize (const A3& input) const
{ {
if (found_something_after_sequence) if (found_something_after_sequence)
{ {
output.push_back (Arg (s, "string", "literal")); output.push_back (Arg (s, Arg::type_string, Arg::cat_literal));
} }
else else
{ {
output.push_back (Arg (s, "string", "uuid")); output.push_back (Arg (s, Arg::type_string, Arg::cat_uuid));
found_sequence = true; found_sequence = true;
} }
} }
else if (is_number (n, d)) 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) if (found_sequence)
found_something_after_sequence = true; found_something_after_sequence = true;
} }
else if (is_integer (n, i)) 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) if (found_sequence)
found_something_after_sequence = true; found_something_after_sequence = true;
} }
@ -822,9 +822,9 @@ const A3 A3::tokenize (const A3& input) const
n.getWord (s)) n.getWord (s))
{ {
if (Date::valid (s)) if (Date::valid (s))
output.push_back (Arg (s, "date", "literal")); output.push_back (Arg (s, Arg::type_date, Arg::cat_literal));
else else
output.push_back (Arg (s, "string", "literal")); output.push_back (Arg (s, Arg::type_string, Arg::cat_literal));
if (found_sequence) if (found_sequence)
found_something_after_sequence = true; found_something_after_sequence = true;
@ -835,7 +835,7 @@ const A3 A3::tokenize (const A3& input) const
if (! n.getUntilWS (s)) if (! n.getUntilWS (s))
n.getUntilEOS (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) if (found_sequence)
found_something_after_sequence = true; found_something_after_sequence = true;
} }
@ -844,7 +844,7 @@ const A3 A3::tokenize (const A3& input) const
{ {
if (n.getUntilEOS (s)) 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) if (found_sequence)
found_something_after_sequence = true; 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 const A3 A3::infix (const A3& input) const
{ {
Arg previous ("?", "op"); Arg previous ("?", Arg::cat_op);
A3 modified; A3 modified;
modified._limit = input._limit; modified._limit = input._limit;
@ -876,10 +876,10 @@ const A3 A3::infix (const A3& input) const
for (arg = input.begin (); arg != input.end (); ++arg) for (arg = input.begin (); arg != input.end (); ++arg)
{ {
// Old-style filters need 'and' conjunctions. // Old-style filters need 'and' conjunctions.
if ((previous._category != "op" || previous._raw == ")") && if ((previous._category != Arg::cat_op || previous._raw == ")") &&
(arg->_category != "op" || arg->_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. // 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) for (arg = input.begin (); arg != input.end (); ++arg)
{ {
// name:value --> name = value // name:value --> name = value
if (arg->_category == "attr") if (arg->_category == Arg::cat_attr)
{ {
std::string name; std::string name;
std::string value; std::string value;
A3::extract_attr (arg->_raw, name, value); A3::extract_attr (arg->_raw, name, value);
expanded.push_back (Arg (name, "string", "dom")); expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
expanded.push_back (Arg ("=", "op")); expanded.push_back (Arg ("=", Arg::cat_op));
expanded.push_back (Arg (value, "string", "literal")); expanded.push_back (Arg (value, Arg::type_string, Arg::cat_literal));
} }
// name.mod:value --> name <op sub mod> value // 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 name;
std::string mod; std::string mod;
@ -925,133 +925,133 @@ const A3 A3::expand (const A3& input) const
// name.before:value --> name < value // name.before:value --> name < value
if (mod == "before" || mod == "under" || mod == "below") if (mod == "before" || mod == "under" || mod == "below")
{ {
expanded.push_back (Arg (name, "string", "dom")); expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
expanded.push_back (Arg ("<", "op")); expanded.push_back (Arg ("<", Arg::cat_op));
expanded.push_back (Arg (value, "string", "literal")); expanded.push_back (Arg (value, Arg::type_string, Arg::cat_literal));
} }
// name.after:value --> name > value // name.after:value --> name > value
else if (mod == "after" || mod == "over" || mod == "above") else if (mod == "after" || mod == "over" || mod == "above")
{ {
expanded.push_back (Arg (name, "string", "dom")); expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
expanded.push_back (Arg (">", "op")); expanded.push_back (Arg (">", Arg::cat_op));
expanded.push_back (Arg (value, "string", "literal")); expanded.push_back (Arg (value, Arg::type_string, Arg::cat_literal));
} }
// name.none: --> name == "" // name.none: --> name == ""
else if (mod == "none") else if (mod == "none")
{ {
expanded.push_back (Arg (name, "string", "dom")); expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
expanded.push_back (Arg ("=", "op")); expanded.push_back (Arg ("=", Arg::cat_op));
expanded.push_back (Arg ("", "string", "")); expanded.push_back (Arg ("", Arg::type_string, Arg::cat_none));
} }
// name.any: --> name != "" // name.any: --> name != ""
else if (mod == "any") else if (mod == "any")
{ {
expanded.push_back (Arg (name, "string", "dom")); expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
expanded.push_back (Arg ("!=", "op")); expanded.push_back (Arg ("!=", Arg::cat_op));
expanded.push_back (Arg ("", "string", "")); expanded.push_back (Arg ("", Arg::type_string, Arg::cat_none));
} }
// name.is:value --> name = value // name.is:value --> name = value
else if (mod == "is" || mod == "equals") else if (mod == "is" || mod == "equals")
{ {
expanded.push_back (Arg (name, "string", "dom")); expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
expanded.push_back (Arg ("=", "op")); expanded.push_back (Arg ("=", Arg::cat_op));
expanded.push_back (Arg (value, "string", "")); expanded.push_back (Arg (value, Arg::type_string, Arg::cat_none));
} }
// name.isnt:value --> name != value // name.isnt:value --> name != value
else if (mod == "isnt" || mod == "not") else if (mod == "isnt" || mod == "not")
{ {
expanded.push_back (Arg (name, "string", "dom")); expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
expanded.push_back (Arg ("!=", "op")); expanded.push_back (Arg ("!=", Arg::cat_op));
expanded.push_back (Arg (value, "string", "")); expanded.push_back (Arg (value, Arg::type_string, Arg::cat_none));
} }
// name.has:value --> name ~ value // name.has:value --> name ~ value
else if (mod == "has" || mod == "contains") else if (mod == "has" || mod == "contains")
{ {
expanded.push_back (Arg (name, "string", "dom")); expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
expanded.push_back (Arg ("~", "op")); expanded.push_back (Arg ("~", Arg::cat_op));
expanded.push_back (Arg (value, "string", "rx")); expanded.push_back (Arg (value, Arg::type_string, Arg::cat_rx));
} }
// name.hasnt:value --> name !~ value // name.hasnt:value --> name !~ value
else if (mod == "hasnt") else if (mod == "hasnt")
{ {
expanded.push_back (Arg (name, "string", "dom")); expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
expanded.push_back (Arg ("!~", "op")); expanded.push_back (Arg ("!~", Arg::cat_op));
expanded.push_back (Arg (value, "string", "rx")); expanded.push_back (Arg (value, Arg::type_string, Arg::cat_rx));
} }
// name.startswith:value --> name ~ ^value // name.startswith:value --> name ~ ^value
else if (mod == "startswith" || mod == "left") else if (mod == "startswith" || mod == "left")
{ {
expanded.push_back (Arg (name, "string", "dom")); expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
expanded.push_back (Arg ("~", "op")); expanded.push_back (Arg ("~", Arg::cat_op));
expanded.push_back (Arg ("^" + value, "string", "rx")); expanded.push_back (Arg ("^" + value, Arg::type_string, Arg::cat_rx));
} }
// name.endswith:value --> name ~ value$ // name.endswith:value --> name ~ value$
else if (mod == "endswith" || mod == "right") else if (mod == "endswith" || mod == "right")
{ {
expanded.push_back (Arg (name, "string", "dom")); expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
expanded.push_back (Arg ("~", "op")); expanded.push_back (Arg ("~", Arg::cat_op));
expanded.push_back (Arg (value + "$", "string", "rx")); expanded.push_back (Arg (value + "$", Arg::type_string, Arg::cat_rx));
} }
// name.word:value --> name ~ \bvalue\b // name.word:value --> name ~ \bvalue\b
else if (mod == "word") else if (mod == "word")
{ {
expanded.push_back (Arg (name, "string", "dom")); expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
expanded.push_back (Arg ("~", "op")); expanded.push_back (Arg ("~", Arg::cat_op));
expanded.push_back (Arg ("\\b" + value + "\\b", "string", "rx")); expanded.push_back (Arg ("\\b" + value + "\\b", Arg::type_string, Arg::cat_rx));
} }
// name.noword:value --> name !~ \bvalue\n // name.noword:value --> name !~ \bvalue\n
else if (mod == "noword") else if (mod == "noword")
{ {
expanded.push_back (Arg (name, "string", "dom")); expanded.push_back (Arg (name, Arg::type_string, Arg::cat_dom));
expanded.push_back (Arg ("!~", "op")); expanded.push_back (Arg ("!~", Arg::cat_op));
expanded.push_back (Arg ("\\b" + value + "\\b", "string", "rx")); expanded.push_back (Arg ("\\b" + value + "\\b", Arg::type_string, Arg::cat_rx));
} }
else else
throw std::string ("Error: unrecognized attribute modifier '") + mod + "'."; throw std::string ("Error: unrecognized attribute modifier '") + mod + "'.";
} }
// [+-]value --> tags ~/!~ value // [+-]value --> tags ~/!~ value
else if (arg->_category == "tag") else if (arg->_category == Arg::cat_tag)
{ {
char type; char type;
std::string value; std::string value;
extract_tag (arg->_raw, type, value); extract_tag (arg->_raw, type, value);
expanded.push_back (Arg ("tags", "string", "dom")); expanded.push_back (Arg ("tags", Arg::type_string, Arg::cat_dom));
expanded.push_back (Arg (type == '+' ? "~" : "!~", "op")); expanded.push_back (Arg (type == '+' ? "~" : "!~", Arg::cat_op));
expanded.push_back (Arg (value, "string", "literal")); expanded.push_back (Arg (value, Arg::type_string, Arg::cat_literal));
} }
// word --> description ~ word // word --> description ~ word
// Note: use of previous prevents desc~foo --> desc~desc~foo // Note: use of previous prevents desc~foo --> desc~desc~foo
else if (arg->_category == "literal" && else if (arg->_category == Arg::cat_literal &&
previous->_category != "op") previous->_category != Arg::cat_op)
{ {
expanded.push_back (Arg ("description", "string", "dom")); expanded.push_back (Arg ("description", Arg::type_string, Arg::cat_dom));
expanded.push_back (Arg ("~", "op")); expanded.push_back (Arg ("~", Arg::cat_op));
expanded.push_back (Arg (arg->_raw, "string", "literal")); expanded.push_back (Arg (arg->_raw, Arg::type_string, Arg::cat_literal));
} }
// /pattern/ --> description ~ pattern // /pattern/ --> description ~ pattern
else if (arg->_category == "pattern") else if (arg->_category == Arg::cat_pattern)
{ {
std::string value; std::string value;
extract_pattern (arg->_raw, value); extract_pattern (arg->_raw, value);
expanded.push_back (Arg ("description", "string", "dom")); expanded.push_back (Arg ("description", Arg::type_string, Arg::cat_dom));
expanded.push_back (Arg ("~", "op")); expanded.push_back (Arg ("~", Arg::cat_op));
expanded.push_back (Arg (value, "string", "rx")); expanded.push_back (Arg (value, Arg::type_string, Arg::cat_rx));
} }
// Default --> preserve // Default --> preserve
@ -1079,10 +1079,10 @@ const A3 A3::sequence (const A3& input) const
std::vector <Arg>::const_iterator arg; std::vector <Arg>::const_iterator arg;
for (arg = input.begin (); arg != input.end (); ++arg) for (arg = input.begin (); arg != input.end (); ++arg)
{ {
if (arg->_category == "id") if (arg->_category == Arg::cat_id)
extract_id (arg->_raw, ids); extract_id (arg->_raw, ids);
else if (arg->_category == "uuid") else if (arg->_category == Arg::cat_uuid)
extract_uuid (arg->_raw, uuids); 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. // Copy everything up to the first id/uuid.
for (arg = input.begin (); arg != input.end (); ++arg) 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; break;
sequenced.push_back (*arg); sequenced.push_back (*arg);
} }
// Insert the algebraic form. // 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) for (unsigned int i = 0; i < ids.size (); ++i)
{ {
if (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 ("id", Arg::type_number, Arg::cat_dom));
sequenced.push_back (Arg ("=", "op")); sequenced.push_back (Arg ("=", Arg::cat_op));
sequenced.push_back (Arg (format(ids[i]), "number", "literal")); sequenced.push_back (Arg (format(ids[i]), Arg::type_number, Arg::cat_literal));
} }
for (unsigned int i = 0; i < uuids.size (); ++i) for (unsigned int i = 0; i < uuids.size (); ++i)
{ {
if (ids.size ()) 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 ("uuid", Arg::type_string, Arg::cat_dom));
sequenced.push_back (Arg ("=", "op")); sequenced.push_back (Arg ("=", Arg::cat_op));
sequenced.push_back (Arg (uuids[i], "string", "literal")); 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. // Now copy everything after the last id/uuid.
bool found_id = false; bool found_id = false;
for (arg = input.begin (); arg != input.end (); ++arg) 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; found_id = true;
else if (found_id) else if (found_id)
@ -1271,16 +1271,16 @@ bool A3::is_attr (Nibbler& n, Arg& arg)
*/ */
arg._raw = name + ':' + value; arg._raw = name + ':' + value;
arg._category = "attr"; arg._category = Arg::cat_attr;
// Most attributes are standard, some are pseudo-attributes, such as // Most attributes are standard, some are pseudo-attributes, such as
// 'limit:page', which is not represented by a column object, and // 'limit:page', which is not represented by a column object, and
// therefore not stored. // therefore not stored.
Column* col = context.columns[name]; Column* col = context.columns[name];
if (col) if (col)
arg._type = col->type (); arg._type = Arg::type_id (col->type ());
else else
arg._type = "pseudo"; arg._type = Arg::type_pseudo;
return true; return true;
} }
@ -1340,8 +1340,8 @@ bool A3::is_attmod (Nibbler& n, Arg& arg)
*/ */
arg._raw = name + '.' + modifier + ':' + value; arg._raw = name + '.' + modifier + ':' + value;
arg._type = context.columns[name]->type (); arg._type = Arg::type_id (context.columns[name]->type ());
arg._category = "attmod"; arg._category = Arg::cat_attmod;
return true; return true;
} }
} }
@ -1437,7 +1437,7 @@ bool A3::is_dom (Nibbler& n, Arg& arg)
} }
arg._raw = result; arg._raw = result;
arg._category = "dom"; arg._category = Arg::cat_dom;
return true; return true;
} }
@ -1452,8 +1452,8 @@ bool A3::is_dom (Nibbler& n, Arg& arg)
{ {
result = format (id) + '.' + name; result = format (id) + '.' + name;
arg._raw = result; arg._raw = result;
arg._type = context.columns[name]->type (); arg._type = Arg::type_id (context.columns[name]->type ());
arg._category = "dom"; arg._category = Arg::cat_dom;
return true; return true;
} }
@ -1467,8 +1467,8 @@ bool A3::is_dom (Nibbler& n, Arg& arg)
is_attribute (name, name)) is_attribute (name, name))
{ {
arg._raw = uuid + '.' + name; arg._raw = uuid + '.' + name;
arg._type = context.columns[name]->type (); arg._type = Arg::type_id (context.columns[name]->type ());
arg._category = "dom"; arg._category = Arg::cat_dom;
return true; return true;
} }
@ -1480,8 +1480,8 @@ bool A3::is_dom (Nibbler& n, Arg& arg)
is_attribute (name, name)) is_attribute (name, name))
{ {
arg._raw = name; arg._raw = name;
arg._type = context.columns[name]->type (); arg._type = Arg::type_id (context.columns[name]->type ());
arg._category = "dom"; arg._category = Arg::cat_dom;
return true; return true;
} }
@ -1990,30 +1990,30 @@ bool A3::is_operator (
void A3::dump (const std::string& label) void A3::dump (const std::string& label)
{ {
// Set up a color mapping. // Set up a color mapping.
std::map <std::string, Color> color_map; std::map <int, Color> color_map;
color_map["program"] = Color ("bold blue on blue"); color_map[Arg::cat_program] = Color ("bold blue on blue");
color_map["command"] = Color ("bold cyan on cyan"); color_map[Arg::cat_command] = Color ("bold cyan on cyan");
color_map["rc"] = Color ("bold red on red"); color_map[Arg::cat_rc] = Color ("bold red on red");
color_map["override"] = Color ("bold red on red"); color_map[Arg::cat_override] = Color ("bold red on red");
color_map["terminator"] = Color ("bold yellow on yellow"); color_map[Arg::cat_terminator] = Color ("bold yellow on yellow");
color_map["literal"] = Color ("white on gray4"); color_map[Arg::cat_literal] = Color ("white on gray4");
// Filter colors. // Filter colors.
color_map["attr"] = Color ("bold red on gray4"); color_map[Arg::cat_attr] = Color ("bold red on gray4");
color_map["attmod"] = Color ("bold red on gray4"); color_map[Arg::cat_attmod] = Color ("bold red on gray4");
color_map["pattern"] = Color ("cyan on gray4"); color_map[Arg::cat_pattern] = Color ("cyan on gray4");
color_map["subst"] = Color ("bold cyan on gray4"); color_map[Arg::cat_subst] = Color ("bold cyan on gray4");
color_map["op"] = Color ("green on gray4"); color_map[Arg::cat_op] = Color ("green on gray4");
color_map["string"] = Color ("bold yellow on gray4"); color_map[Arg::type_string] = Color ("bold yellow on gray4");
color_map["rx"] = Color ("bold yellow on gray4"); color_map[Arg::cat_rx] = Color ("bold yellow on gray4");
color_map["date"] = Color ("bold yellow on gray4"); color_map[Arg::type_date] = Color ("bold yellow on gray4");
color_map["dom"] = Color ("bold white on gray4"); color_map[Arg::cat_dom] = Color ("bold white on gray4");
color_map["duration"] = Color ("magenta on gray4"); color_map[Arg::type_duration] = Color ("magenta on gray4");
color_map["id"] = Color ("white on gray4"); color_map[Arg::cat_id] = Color ("white on gray4");
color_map["uuid"] = Color ("white on gray4"); color_map[Arg::cat_uuid] = Color ("white on gray4");
// Default. // 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")); Color color_debug (context.config.get ("color.debug"));
std::stringstream out; std::stringstream out;
@ -2033,21 +2033,21 @@ void A3::dump (const std::string& label)
for (unsigned int i = 0; i < this->size (); ++i) for (unsigned int i = 0; i < this->size (); ++i)
{ {
std::string value = (*this)[i]._value; std::string value = (*this)[i]._value;
std::string raw = (*this)[i]._raw; std::string raw = (*this)[i]._raw;
std::string type = (*this)[i]._type; Arg::type type = (*this)[i]._type;
std::string category = (*this)[i]._category; Arg::category category = (*this)[i]._category;
Color c; Color c;
if (color_map[category].nontrivial ()) if (color_map[category].nontrivial ())
c = color_map[category]; c = color_map[category];
else else
c = color_map["none"]; c = color_map[Arg::cat_none];
view.set (0, i, value, c); view.set (0, i, value, c);
view.set (1, i, raw, c); view.set (1, i, raw, c);
view.set (2, i, type, c); view.set (2, i, Arg::type_name (type), c);
view.set (3, i, category, c); view.set (3, i, Arg::category_name (category), c);
} }
out << view.render (); out << view.render ();

View file

@ -34,8 +34,8 @@ extern Context context;
Arg::Arg () Arg::Arg ()
: _value ("") : _value ("")
, _raw ("") , _raw ("")
, _type ("") , _type (type_none)
, _category ("") , _category (cat_none)
{ {
} }
@ -43,31 +43,31 @@ Arg::Arg ()
Arg::Arg (const std::string& raw) Arg::Arg (const std::string& raw)
: _value ("") : _value ("")
, _raw (raw) , _raw (raw)
, _type ("") , _type (type_none)
, _category ("") , _category (cat_none)
{ {
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Arg::Arg ( Arg::Arg (
const std::string& raw, const std::string& raw,
const std::string& category) const category c)
: _value ("") : _value ("")
, _raw (raw) , _raw (raw)
, _type ("") , _type (type_none)
, _category (category) , _category (c)
{ {
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Arg::Arg ( Arg::Arg (
const std::string& raw, const std::string& raw,
const std::string& type, const type t,
const std::string& category) const category c)
: _value ("") : _value ("")
, _raw (raw) , _raw (raw)
, _type (type) , _type (t)
, _category (category) , _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";
}
///////////////////////////////////////////////////////////////////////////////

View file

@ -35,19 +35,28 @@
class Arg class Arg
{ {
public: 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 ();
Arg (const std::string&); Arg (const std::string&);
Arg (const std::string&, const std::string&); Arg (const std::string&, const category);
Arg (const std::string&, const std::string&, const std::string&); Arg (const std::string&, const type, const category);
Arg (const Arg&); Arg (const Arg&);
Arg& operator= (const Arg&); Arg& operator= (const Arg&);
bool operator== (const Arg&) const; 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: public:
std::string _value; // Interpreted value std::string _value; // Interpreted value
std::string _raw; // Raw input token, never modified std::string _raw; // Raw input token, never modified
std::string _type; // Data type type _type; // Data type
std::string _category; // Categorized argument category _category; // Categorized argument
}; };
#endif #endif

View file

@ -36,10 +36,10 @@ extern Context context;
std::ostream& operator<< (std::ostream& out, const Arg& term) std::ostream& operator<< (std::ostream& out, const Arg& term)
{ {
out << term._value << "|" out << term._value << "|"
<< term._raw << "|" << term._raw << "|"
<< term._type << "|" << Arg::type_name (term._type) << "|"
<< term._category; << Arg::category_name (term._category);
return out; return out;
} }
@ -70,7 +70,7 @@ bool E9::evalFilter (const Task& task)
// Coerce result to Boolean. // Coerce result to Boolean.
Arg result = value_stack.back (); Arg result = value_stack.back ();
value_stack.pop_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; std::vector <Arg>::const_iterator arg;
for (arg = _terms.begin (); arg != _terms.end (); ++arg) for (arg = _terms.begin (); arg != _terms.end (); ++arg)
{ {
if (arg->_category == "op") if (arg->_category == Arg::cat_op)
{ {
Arg result; Arg result;
@ -156,22 +156,22 @@ void E9::eval (const Task& task, std::vector <Arg>& value_stack)
Arg operand (*arg); Arg operand (*arg);
// Expand the value if possible. // 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._value = context.dom.get (operand._raw, task);
operand._category = "literal"; operand._category = Arg::cat_literal;
} }
else if (operand._type == "date" && else if (operand._type == Arg::type_date &&
operand._category == "literal") operand._category == Arg::cat_literal)
{ {
operand._value = Date (operand._raw, _dateformat).toEpochString (); operand._value = Date (operand._raw, _dateformat).toEpochString ();
operand._category = "literal"; operand._category = Arg::cat_literal;
} }
else if (operand._type == "duration" && else if (operand._type == Arg::type_duration &&
operand._category == "literal") operand._category == Arg::cat_literal)
{ {
operand._value = (std::string)Duration (operand._raw); operand._value = (std::string)Duration (operand._raw);
operand._category = "literal"; operand._category = Arg::cat_literal;
} }
else else
operand._value = operand._raw; 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) 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"); left = coerce (left, Arg::type_string);
right = coerce (right, "string"); right = coerce (right, Arg::type_string);
// Create a cached entry, if it does not already exist. // Create a cached entry, if it does not already exist.
if (_regexes.find (right._value) == _regexes.end ()) if (_regexes.find (right._value) == _regexes.end ())
@ -203,8 +203,8 @@ bool E9::eval_match (Arg& left, Arg& right, bool case_sensitive)
} }
else else
{ {
left = coerce (left, "string"); left = coerce (left, Arg::type_string);
right = coerce (right, "string"); right = coerce (right, Arg::type_string);
if (find (left._value, right._value, (bool) case_sensitive) != std::string::npos) if (find (left._value, right._value, (bool) case_sensitive) != std::string::npos)
return true; 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) void E9::operator_not (Arg& result, Arg& right)
{ {
// TODO This is not 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"; // std::cout << "# <operator_not> " << right << " --> " << result << "\n";
} }
@ -226,13 +226,12 @@ void E9::operator_and (Arg& result, Arg& left, Arg& right)
{ {
// Assume failure. // Assume failure.
result._value = "false"; result._value = "false";
result._category = "bool"; result._type = Arg::type_bool;
if (coerce (left, "bool")._value == "true" && if (coerce (left, Arg::type_bool)._value == "true" &&
coerce (right, "bool")._value == "true" ) coerce (right, Arg::type_bool)._value == "true" )
{ {
result._value = "true"; result._value = "true";
result._category = "bool";
} }
// std::cout << "# " << left << " <operator_and> " << right << " --> " << result << "\n"; // std::cout << "# " << left << " <operator_and> " << right << " --> " << result << "\n";
@ -243,13 +242,12 @@ void E9::operator_or (Arg& result, Arg& left, Arg& right)
{ {
// Assume failure. // Assume failure.
result._value = "false"; result._value = "false";
result._category = "bool"; result._type = Arg::type_bool;
if (coerce (left, "bool")._value == "true" || if (coerce (left, Arg::type_bool)._value == "true" ||
coerce (right, "bool")._value == "true" ) coerce (right, Arg::type_bool)._value == "true" )
{ {
result._value = "true"; result._value = "true";
result._category = "bool";
} }
// std::cout << "# " << left << " <operator_or> " << right << " --> " << result << "\n"; // std::cout << "# " << left << " <operator_or> " << right << " --> " << result << "\n";
@ -260,16 +258,15 @@ void E9::operator_xor (Arg& result, Arg& left, Arg& right)
{ {
// Assume failure. // Assume failure.
result._value = "false"; result._value = "false";
result._category = "bool"; result._type = Arg::type_bool;
bool bool_left = coerce (left, "bool")._value == "true"; bool bool_left = coerce (left, Arg::type_bool)._value == "true";
bool bool_right = coerce (right, "bool")._value == "true"; bool bool_right = coerce (right, Arg::type_bool)._value == "true";
if ((bool_left && !bool_right) || if ((bool_left && !bool_right) ||
(!bool_left && bool_right)) (!bool_left && bool_right))
{ {
result._value = "true"; result._value = "true";
result._category = "bool";
} }
// std::cout << "# " << left << " <operator_xor> " << right << " --> " << result << "\n"; // 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 if (left._value == "" && right._value != "") result._value = "true";
else result._value = "false"; else result._value = "false";
} }
else if (left._category == "date" || else if (left._type == Arg::type_date ||
right._category == "date") right._type == Arg::type_date)
{ {
Date left_date (left._value, _dateformat); Date left_date (left._value, _dateformat);
Date right_date (right._value, _dateformat); Date right_date (right._value, _dateformat);
@ -302,7 +299,7 @@ void E9::operator_lt (Arg& result, Arg& left, Arg& right)
: "false"; : "false";
} }
result._category = "bool"; result._type = Arg::type_bool;
// std::cout << "# " << left << " <operator_lt> " << right << " --> " << result << "\n"; // 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 if (left._value == "" ) result._value = "true";
else result._value = "false"; else result._value = "false";
} }
else if (left._category == "date" || else if (left._type == Arg::type_date ||
right._category == "date") right._type == Arg::type_date)
{ {
Date left_date (left._value, _dateformat); Date left_date (left._value, _dateformat);
Date right_date (right._value, _dateformat); Date right_date (right._value, _dateformat);
@ -335,7 +332,7 @@ void E9::operator_lte (Arg& result, Arg& left, Arg& right)
: "false"; : "false";
} }
result._category = "bool"; result._type = Arg::type_bool;
// std::cout << "# " << left << " <operator_lte> " << right << " --> " << result << "\n"; // 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 if ( right._value == "" ) result._value = "true";
else result._value = "false"; else result._value = "false";
} }
else if (left._category == "date" || else if (left._type == Arg::type_date ||
right._category == "date") right._type == Arg::type_date)
{ {
Date left_date (left._value, _dateformat); Date left_date (left._value, _dateformat);
Date right_date (right._value, _dateformat); Date right_date (right._value, _dateformat);
@ -368,7 +365,7 @@ void E9::operator_gte (Arg& result, Arg& left, Arg& right)
: "false"; : "false";
} }
result._category = "bool"; result._type = Arg::type_bool;
// std::cout << "# " << left << " <operator_gte> " << right << " --> " << result << "\n"; // 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 if (left._value != "" && right._value == "") result._value = "true";
else result._value = "false"; else result._value = "false";
} }
else if (left._category == "date" || else if (left._type == Arg::type_date ||
right._category == "date") right._type == Arg::type_date)
{ {
Date left_date (left._value, _dateformat); Date left_date (left._value, _dateformat);
Date right_date (right._value, _dateformat); Date right_date (right._value, _dateformat);
@ -400,7 +397,7 @@ void E9::operator_gt (Arg& result, Arg& left, Arg& right)
: "false"; : "false";
} }
result._category = "bool"; result._type = Arg::type_bool;
// std::cout << "# " << left << " <operator_gt> " << right << " --> " << result << "\n"; // std::cout << "# " << left << " <operator_gt> " << right << " --> " << result << "\n";
} }
@ -429,14 +426,14 @@ void E9::operator_equal (
{ {
// Assume failure. // Assume failure.
result._value = "false"; result._value = "false";
result._category = "bool"; result._type = Arg::type_bool;
// 'project' and 'recur' attributes are matched leftmost. // 'project' and 'recur' attributes are matched leftmost.
if (left._raw == "project" || left._raw == "recur") if (left._raw == "project" || left._raw == "recur")
{ {
// std::cout << "# project/recur matching\n"; // std::cout << "# project/recur matching\n";
coerce (left, "string"); coerce (left, Arg::type_string);
coerce (right, "string"); coerce (right, Arg::type_string);
if (right._value.length () <= left._value.length () && if (right._value.length () <= left._value.length () &&
compare (right._value, compare (right._value,
@ -444,13 +441,12 @@ void E9::operator_equal (
case_sensitive)) case_sensitive))
{ {
result._raw = "true"; result._raw = "true";
result._category = "bool";
} }
} }
// Dates. // Dates.
else if (left._category == "date" || else if (left._type == Arg::type_date ||
right._category == "date") right._type == Arg::type_date)
{ {
// std::cout << "# date matching\n"; // std::cout << "# date matching\n";
Date left_date (left._value, _dateformat); Date left_date (left._value, _dateformat);
@ -472,7 +468,7 @@ void E9::operator_equal (
if (left._value == right._value) if (left._value == right._value)
{ {
result._value = "true"; result._value = "true";
result._category = "bool"; result._type = Arg::type_bool;
} }
} }
@ -486,7 +482,7 @@ void E9::operator_match (
Arg& right, Arg& right,
bool case_sensitive) bool case_sensitive)
{ {
result._category = "bool"; result._type = Arg::type_bool;
result._value = eval_match (left, right, case_sensitive) result._value = eval_match (left, right, case_sensitive)
? "true" ? "true"
: "false"; : "false";
@ -511,7 +507,7 @@ void E9::operator_nomatch (
Arg& right, Arg& right,
bool case_sensitive) bool case_sensitive)
{ {
result._category = "bool"; result._type = Arg::type_bool;
result._value = eval_match (left, right, case_sensitive) result._value = eval_match (left, right, case_sensitive)
? "false" ? "false"
: "true"; : "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; 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"; result._value = get_bool (input) ? "true" : "false";
} }
if (type == "string") if (type == Arg::type_string)
{ {
// TODO Convert date? // TODO Convert date?
result._value = input._value; result._value = input._value;
result._category = "string"; result._type = Arg::type_string;
} }
// TODO Date // TODO Date

View file

@ -66,7 +66,7 @@ private:
void operator_add (Arg&, Arg&, Arg&); void operator_add (Arg&, Arg&, Arg&);
void operator_subtract (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&); bool get_bool (const Arg&);
private: private:

View file

@ -411,7 +411,7 @@ void Command::modify_task (
{ {
// Attributes are essentially name:value pairs, and correspond directly // Attributes are essentially name:value pairs, and correspond directly
// to stored attributes. // to stored attributes.
if (arg->_category == "attr") if (arg->_category == Arg::cat_attr)
{ {
std::string name; std::string name;
std::string value; std::string value;
@ -477,7 +477,7 @@ void Command::modify_task (
// Tags need special handling because they are essentially a vector stored // Tags need special handling because they are essentially a vector stored
// in a single string, therefore Task::{add,remove}Tag must be called as // in a single string, therefore Task::{add,remove}Tag must be called as
// appropriate. // appropriate.
else if (arg->_category == "tag") else if (arg->_category == Arg::cat_tag)
{ {
char type; char type;
std::string value; std::string value;
@ -490,7 +490,7 @@ void Command::modify_task (
} }
// Substitutions. // Substitutions.
else if (arg->_category == "subst") else if (arg->_category == Arg::cat_subst)
{ {
std::string from; std::string from;
std::string to; std::string to;