- Updated DOM to use Variant ovjects, which carry a type which improves
  expression evaluation.
This commit is contained in:
Paul Beckingham 2014-06-11 21:53:00 -04:00
parent e8474fc145
commit 456b982ced
5 changed files with 76 additions and 73 deletions

View file

@ -28,6 +28,7 @@
#include <sstream> #include <sstream>
#include <map> #include <map>
#include <stdlib.h> #include <stdlib.h>
#include <Variant.h>
#include <Context.h> #include <Context.h>
#include <Nibbler.h> #include <Nibbler.h>
#include <Date.h> #include <Date.h>
@ -76,7 +77,7 @@ const std::vector <std::string> DOM::get_references () const
// system.version // system.version
// system.os // system.os
// //
bool DOM::get (const std::string& name, std::string& value) bool DOM::get (const std::string& name, Variant& value)
{ {
int len = name.length (); int len = name.length ();
Nibbler n (name); Nibbler n (name);
@ -89,7 +90,7 @@ bool DOM::get (const std::string& name, std::string& value)
std::map <std::string, std::string>::iterator c = context.config.find (key); std::map <std::string, std::string>::iterator c = context.config.find (key);
if (c != context.config.end ()) if (c != context.config.end ())
{ {
value = c->second; value = Variant (c->second);
return true; return true;
} }
@ -102,33 +103,34 @@ bool DOM::get (const std::string& name, std::string& value)
{ {
if (name == "context.program") if (name == "context.program")
{ {
value = context.program; value = Variant (context.program);
return true; return true;
} }
else if (name == "context.args") else if (name == "context.args")
{ {
value = ""; std::string commandLine = "";
std::vector <Tree*>::iterator i; std::vector <Tree*>::iterator i;
for (i = context.parser.tree ()->_branches.begin (); i != context.parser.tree ()->_branches.end (); ++i) for (i = context.parser.tree ()->_branches.begin (); i != context.parser.tree ()->_branches.end (); ++i)
{ {
if (value != "") if (commandLine != "")
value += " "; commandLine += " ";
value += (*i)->attribute ("raw"); commandLine += (*i)->attribute ("raw");
} }
value = Variant (commandLine);
return true; return true;
} }
else if (name == "context.width") else if (name == "context.width")
{ {
value = format (context.terminal_width value = Variant (context.terminal_width
? context.terminal_width ? context.terminal_width
: context.getWidth ()); : context.getWidth ());
return true; return true;
} }
else if (name == "context.height") else if (name == "context.height")
{ {
value = format (context.terminal_height value = Variant (context.terminal_height
? context.terminal_height ? context.terminal_height
: context.getHeight ()); : context.getHeight ());
return true; return true;
@ -146,7 +148,7 @@ bool DOM::get (const std::string& name, std::string& value)
// Taskwarrior version number. // Taskwarrior version number.
if (name == "system.version") if (name == "system.version")
{ {
value = VERSION; value = Variant (VERSION);
return true; return true;
} }
@ -154,27 +156,27 @@ bool DOM::get (const std::string& name, std::string& value)
else if (name == "system.os") else if (name == "system.os")
{ {
#if defined (DARWIN) #if defined (DARWIN)
value = "Darwin"; value = Variant ("Darwin");
#elif defined (SOLARIS) #elif defined (SOLARIS)
value = "Solaris"; value = Variant ("Solaris");
#elif defined (CYGWIN) #elif defined (CYGWIN)
value = "Cygwin"; value = Variant ("Cygwin");
#elif defined (HAIKU) #elif defined (HAIKU)
value = "Haiku"; value = Variant ("Haiku");
#elif defined (OPENBSD) #elif defined (OPENBSD)
value = "OpenBSD"; value = Variant ("OpenBSD");
#elif defined (FREEBSD) #elif defined (FREEBSD)
value = "FreeBSD"; value = Variant ("FreeBSD");
#elif defined (NETBSD) #elif defined (NETBSD)
value = "NetBSD"; value = Variant ("NetBSD");
#elif defined (LINUX) #elif defined (LINUX)
value = "Linux"; value = Variant ("Linux");
#elif defined (KFREEBSD) #elif defined (KFREEBSD)
value = "GNU/kFreeBSD"; value = Variant ("GNU/kFreeBSD");
#elif defined (GNUHURD) #elif defined (GNUHURD)
value = "GNU/Hurd"; value = Variant ("GNU/Hurd");
#else #else
value = STRING_DOM_UNKNOWN; value = Variant (STRING_DOM_UNKNOWN);
#endif #endif
return true; return true;
} }
@ -218,18 +220,18 @@ bool DOM::get (const std::string& name, std::string& value)
// annotations.<N>.entry.second // annotations.<N>.entry.second
// annotations.<N>.description // annotations.<N>.description
// //
bool DOM::get (const std::string& name, const Task& task, std::string& value) bool DOM::get (const std::string& name, const Task& task, Variant& value)
{ {
// <attr> // <attr>
if (task.size () && name == "id") if (task.size () && name == "id")
{ {
value = format (task.id); value = Variant (task.id);
return true; return true;
} }
if (task.size () && name == "urgency") if (task.size () && name == "urgency")
{ {
value = format (task.urgency_c ()); value = Variant (task.urgency_c ());
return true; return true;
} }
@ -242,7 +244,7 @@ bool DOM::get (const std::string& name, const Task& task, std::string& value)
std::string canonical; std::string canonical;
if (task.size () && context.parser.canonicalize (canonical, "attribute", name)) if (task.size () && context.parser.canonicalize (canonical, "attribute", name))
{ {
value = task.get (canonical); value = Variant (task.get (canonical));
return true; return true;
} }
} }
@ -283,12 +285,12 @@ bool DOM::get (const std::string& name, const Task& task, std::string& value)
{ {
if (elements[1] == "id") if (elements[1] == "id")
{ {
value = format (ref.id); value = Variant (ref.id);
return true; return true;
} }
else if (elements[1] == "urgency") else if (elements[1] == "urgency")
{ {
value = format (ref.urgency_c ()); value = Variant (ref.urgency_c ());
return true; return true;
} }
@ -297,7 +299,7 @@ bool DOM::get (const std::string& name, const Task& task, std::string& value)
{ {
if (elements.size () == 2) if (elements.size () == 2)
{ {
value = ref.get (canonical); value = Variant (ref.get (canonical));
return true; return true;
} }
else if (elements.size () == 3) else if (elements.size () == 3)
@ -305,7 +307,7 @@ bool DOM::get (const std::string& name, const Task& task, std::string& value)
// tags.<tag> // tags.<tag>
if (canonical == "tags") if (canonical == "tags")
{ {
value = ref.hasTag (elements[2]) ? elements[2] : ""; value = Variant (ref.hasTag (elements[2]) ? elements[2] : "");
return true; return true;
} }
@ -322,15 +324,15 @@ bool DOM::get (const std::string& name, const Task& task, std::string& value)
// <date>.minute // <date>.minute
// <date>.second // <date>.second
Date date (ref.get_date (canonical)); Date date (ref.get_date (canonical));
if (elements[2] == "year") { value = format (date.year ()); return true; } if (elements[2] == "year") { value = Variant (date.year ()); return true; }
else if (elements[2] == "month") { value = format (date.month ()); return true; } else if (elements[2] == "month") { value = Variant (date.month ()); return true; }
else if (elements[2] == "day") { value = format (date.day ()); return true; } else if (elements[2] == "day") { value = Variant (date.day ()); return true; }
else if (elements[2] == "week") { value = format (date.week ()); return true; } else if (elements[2] == "week") { value = Variant (date.week ()); return true; }
else if (elements[2] == "weekday") { value = format (date.dayOfWeek ()); return true; } else if (elements[2] == "weekday") { value = Variant (date.dayOfWeek ()); return true; }
else if (elements[2] == "julian") { value = format (date.dayOfYear ()); return true; } else if (elements[2] == "julian") { value = Variant (date.dayOfYear ()); return true; }
else if (elements[2] == "hour") { value = format (date.hour ()); return true; } else if (elements[2] == "hour") { value = Variant (date.hour ()); return true; }
else if (elements[2] == "minute") { value = format (date.minute ()); return true; } else if (elements[2] == "minute") { value = Variant (date.minute ()); return true; }
else if (elements[2] == "second") { value = format (date.second ()); return true; } else if (elements[2] == "second") { value = Variant (date.second ()); return true; }
} }
} }
} }
@ -354,12 +356,12 @@ bool DOM::get (const std::string& name, const Task& task, std::string& value)
{ {
// annotation_1234567890 // annotation_1234567890
// 0 ^11 // 0 ^11
value = i->first.substr (11); value = Variant ((time_t) strtol (i->first.substr (11).c_str (), NULL, 10), Variant::type_date);
return true; return true;
} }
else if (elements[3] == "description") else if (elements[3] == "description")
{ {
value = i->second; value = Variant (i->second);
return true; return true;
} }
} }
@ -389,15 +391,15 @@ bool DOM::get (const std::string& name, const Task& task, std::string& value)
// <annotations>.<N>.entry.minute // <annotations>.<N>.entry.minute
// <annotations>.<N>.entry.second // <annotations>.<N>.entry.second
Date date (i->first.substr (11)); Date date (i->first.substr (11));
if (elements[4] == "year") { value = format (date.year ()); return true; } if (elements[4] == "year") { value = Variant (date.year ()); return true; }
else if (elements[4] == "month") { value = format (date.month ()); return true; } else if (elements[4] == "month") { value = Variant (date.month ()); return true; }
else if (elements[4] == "day") { value = format (date.day ()); return true; } else if (elements[4] == "day") { value = Variant (date.day ()); return true; }
else if (elements[4] == "week") { value = format (date.week ()); return true; } else if (elements[4] == "week") { value = Variant (date.week ()); return true; }
else if (elements[4] == "weekday") { value = format (date.dayOfWeek ()); return true; } else if (elements[4] == "weekday") { value = Variant (date.dayOfWeek ()); return true; }
else if (elements[4] == "julian") { value = format (date.dayOfYear ()); return true; } else if (elements[4] == "julian") { value = Variant (date.dayOfYear ()); return true; }
else if (elements[4] == "hour") { value = format (date.hour ()); return true; } else if (elements[4] == "hour") { value = Variant (date.hour ()); return true; }
else if (elements[4] == "minute") { value = format (date.minute ()); return true; } else if (elements[4] == "minute") { value = Variant (date.minute ()); return true; }
else if (elements[4] == "second") { value = format (date.second ()); return true; } else if (elements[4] == "second") { value = Variant (date.second ()); return true; }
} }
} }
} }
@ -410,7 +412,7 @@ bool DOM::get (const std::string& name, const Task& task, std::string& value)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void DOM::set (const std::string& name, const std::string& value) void DOM::set (const std::string& name, const Variant& value)
{ {
int len = name.length (); int len = name.length ();
@ -418,7 +420,7 @@ void DOM::set (const std::string& name, const std::string& value)
if (len > 3 && if (len > 3 &&
name.substr (0, 3) == "rc.") name.substr (0, 3) == "rc.")
{ {
context.config.set (name.substr (3), value); context.config.set (name.substr (3), (std::string) value);
} }
// Unrecognized --> error. // Unrecognized --> error.

View file

@ -28,6 +28,7 @@
#define INCLUDED_DOM #define INCLUDED_DOM
#include <string> #include <string>
#include <Variant.h>
#include <Task.h> #include <Task.h>
#include <time.h> #include <time.h>
@ -38,9 +39,9 @@ public:
~DOM (); ~DOM ();
const std::vector <std::string> get_references () const; const std::vector <std::string> get_references () const;
bool get (const std::string&, std::string&); bool get (const std::string&, Variant&);
bool get (const std::string&, const Task&, std::string&); bool get (const std::string&, const Task&, Variant&);
void set (const std::string&, const std::string&); void set (const std::string&, const Variant&);
private: private:
}; };

View file

@ -44,10 +44,8 @@ Task& contextTask = dummy;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool domSource (const std::string& identifier, Variant& value) bool domSource (const std::string& identifier, Variant& value)
{ {
std::string result; if (context.dom.get (identifier, contextTask, value))
if (context.dom.get (identifier, contextTask, result))
{ {
value = Variant (result);
value.source (identifier); value.source (identifier);
return true; return true;
} }

View file

@ -25,6 +25,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#include <cmake.h> #include <cmake.h>
#include <Variant.h>
#include <Context.h> #include <Context.h>
#include <main.h> #include <main.h>
#include <text.h> #include <text.h>
@ -58,10 +59,10 @@ int CmdGet::execute (std::string& output)
for (word = words.begin (); word != words.end (); ++word) for (word = words.begin (); word != words.end (); ++word)
{ {
Task t; Task t;
std::string result; Variant result;
if (context.dom.get (*word, t, result)) if (context.dom.get (*word, t, result))
{ {
results.push_back (result); results.push_back ((std::string) result);
found = true; found = true;
} }
} }

View file

@ -28,6 +28,7 @@
#include <iostream> #include <iostream>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <DOM.h>
#include <main.h> #include <main.h>
#include <test.h> #include <test.h>
@ -51,36 +52,36 @@ int main (int argc, char** argv)
context.config.set ("name", "value"); context.config.set ("name", "value");
DOM dom; DOM dom;
std::string result; Variant result;
t.ok (dom.get ("system.version", result), "DOM system.version -> true"); t.ok (dom.get ("system.version", result), "DOM system.version -> true");
t.is (result, VERSION, "DOM system.version -> VERSION"); t.is ((std::string) result, VERSION, "DOM system.version -> VERSION");
t.ok (dom.get ("system.os", result), "DOM system.os -> true"); t.ok (dom.get ("system.os", result), "DOM system.os -> true");
t.ok (result != "<unknown>", "DOM system.os -> != Unknown"); t.ok ((std::string) result != "<unknown>", "DOM system.os -> != Unknown");
t.ok (dom.get ("context.program", result), "DOM context.program -> true"); t.ok (dom.get ("context.program", result), "DOM context.program -> true");
t.is (result, "task", "DOM context.program -> 'task'"); t.is ((std::string) result, "task", "DOM context.program -> 'task'");
t.ok (dom.get ("context.args", result), "DOM context.args -> true"); t.ok (dom.get ("context.args", result), "DOM context.args -> true");
t.is (result, "task", "DOM context.args -> 'task'"); t.is ((std::string) result, "task", "DOM context.args -> 'task'");
t.ok (dom.get ("context.width", result), "DOM context.width -> true"); t.ok (dom.get ("context.width", result), "DOM context.width -> true");
t.ok (result != "0", "DOM context.width -> '0'"); t.ok (result.get_integer () != 0, "DOM context.width -> '0'");
t.ok (dom.get ("context.height", result), "DOM context.height -> true"); t.ok (dom.get ("context.height", result), "DOM context.height -> true");
t.ok (result != "0", "DOM context.height -> '0'"); t.ok (result.get_integer () != 0, "DOM context.height -> '0'");
// dom.get rc.name // dom.get rc.name
t.ok (dom.get ("rc.name", result), "DOM rc.name -> true"); t.ok (dom.get ("rc.name", result), "DOM rc.name -> true");
t.is (result, "value", "DOM rc.name -> value"); t.is ((std::string) result, "value", "DOM rc.name -> value");
// dom.get rc.missing // dom.get rc.missing
t.notok (dom.get ("rc.missing", result), "DOM rc.missing -> false"); t.notok (dom.get ("rc.missing", result), "DOM rc.missing -> false");
// dom.set rc.name // dom.set rc.name
dom.set ("rc.new", "value"); dom.set ("rc.new", Variant ("value"));
t.ok (dom.get ("rc.new", result), "DOM rc.new -> true"); t.ok (dom.get ("rc.new", result), "DOM rc.new -> true");
t.is (result, "value", "DOM rc.new -> value"); t.is ((std::string) result, "value", "DOM rc.new -> value");
} }
catch (const std::string& error) catch (const std::string& error)