Enhancement - Integration

- Integrated Cmd object.
- Enhanced Context object with dispatch and shadow methods.
- Fixed bug in Context::parse.
- Implemented command parsing.
- Fixed Sequence bug, and unit tests.
This commit is contained in:
Paul Beckingham 2009-06-07 16:00:22 -04:00
parent 190c6b53fc
commit d702ba8f24
7 changed files with 128 additions and 35 deletions

View file

@ -46,7 +46,8 @@ Context::Context ()
, task ()
, tdb ()
, stringtable ()
, command ("")
, program ("")
, cmd ()
{
// Set up randomness.
#ifdef HAVE_SRANDOM
@ -68,8 +69,9 @@ Context::Context (const Context& other)
task = other.task;
tdb = other.tdb;
stringtable = other.stringtable;
program = other.program;
args = other.args;
command = other.command;
cmd = other.cmd;
messages = other.messages;
footnotes = other.footnotes;
}
@ -88,8 +90,9 @@ Context& Context::operator= (const Context& other)
task = other.task;
tdb = other.tdb;
stringtable = other.stringtable;
program = other.program;
args = other.args;
command = other.command;
cmd = other.cmd;
messages = other.messages;
footnotes = other.footnotes;
}
@ -107,7 +110,10 @@ void Context::initialize (int argc, char** argv)
{
// Capture the args.
for (int i = 0; i < argc; ++i)
args.push_back (argv[i]);
if (i == 0)
program = argv[i];
else
args.push_back (argv[i]);
// Load the configuration file from the home directory. If the file cannot
// be found, offer to create a sample one.
@ -148,12 +154,11 @@ int Context::run ()
std::cout << "--- start 1.8.0 ---" << std::endl;
try
{
parse ();
// TODO Dispatch to command handlers.
// TODO Auto shadow update.
// TODO Auto gc.
parse (); // Parse command line.
// TODO tdb.load (Filter);
dispatch (); // Dispatch to command handlers.
// TODO Auto gc.
shadow (); // Auto shadow update.
}
catch (const std::string& error)
@ -181,6 +186,86 @@ int Context::run ()
return 0;
}
////////////////////////////////////////////////////////////////////////////////
void Context::dispatch ()
{
/*
// If argc == 1 and there is a default.command, use it. Otherwise use
// argc/argv.
std::string defaultCommand = context.config.get ("default.command");
if (args.size () == 0 || defaultCommand != "")
{
// Stuff the command line.
args.clear ();
split (args, defaultCommand, ' ');
std::cout << "[task " << defaultCommand << "]" << std::endl;
}
loadCustomReports ();
std::string command;
T task;
parse (args, command, task);
bool gcMod = false; // Change occurred by way of gc.
bool cmdMod = false; // Change occurred by way of command type.
std::string out;
// Read-only commands with no side effects.
if (command == "export") { out = handleExport (tdb, task); }
else if (command == "projects") { out = handleProjects (tdb, task); }
else if (command == "tags") { out = handleTags (tdb, task); }
else if (command == "info") { out = handleInfo (tdb, task); }
else if (command == "stats") { out = handleReportStats (tdb, task); }
else if (command == "history") { out = handleReportHistory (tdb, task); }
else if (command == "ghistory") { out = handleReportGHistory (tdb, task); }
else if (command == "calendar") { out = handleReportCalendar (tdb, task); }
else if (command == "summary") { out = handleReportSummary (tdb, task); }
else if (command == "timesheet") { out = handleReportTimesheet (tdb, task); }
else if (command == "colors") { out = handleColor ( ); }
else if (command == "version") { out = handleVersion ( ); }
else if (command == "help") { out = longUsage ( ); }
// Commands that cause updates.
else if (command == "" && task.getId ()) { cmdMod = true; out = handleModify (tdb, task); }
else if (command == "add") { cmdMod = true; out = handleAdd (tdb, task); }
else if (command == "append") { cmdMod = true; out = handleAppend (tdb, task); }
else if (command == "annotate") { cmdMod = true; out = handleAnnotate (tdb, task); }
else if (command == "done") { cmdMod = true; out = handleDone (tdb, task); }
else if (command == "undelete") { cmdMod = true; out = handleUndelete (tdb, task); }
else if (command == "delete") { cmdMod = true; out = handleDelete (tdb, task); }
else if (command == "start") { cmdMod = true; out = handleStart (tdb, task); }
else if (command == "stop") { cmdMod = true; out = handleStop (tdb, task); }
else if (command == "undo") { cmdMod = true; out = handleUndo (tdb, task); }
else if (command == "import") { cmdMod = true; out = handleImport (tdb, task); }
else if (command == "duplicate") { cmdMod = true; out = handleDuplicate (tdb, task); }
else if (command == "edit") { cmdMod = true; out = handleEdit (tdb, task); }
// Command that display IDs and therefore need TDB::gc first.
else if (command == "completed") { if (gc) gcMod = tdb.gc (); out = handleCompleted (tdb, task); }
else if (command == "next") { if (gc) gcMod = tdb.gc (); out = handleReportNext (tdb, task); }
else if (command == "active") { if (gc) gcMod = tdb.gc (); out = handleReportActive (tdb, task); }
else if (command == "overdue") { if (gc) gcMod = tdb.gc (); out = handleReportOverdue (tdb, task); }
else if (isCustomReport (command)) { if (gc) gcMod = tdb.gc (); out = handleCustomReport (tdb, task, command); }
// If the command is not recognized, display usage.
else { out = shortUsage (); }
// Only update the shadow file if such an update was not suppressed (shadow),
// and if an actual change occurred (gcMod || cmdMod).
if (shadow && (gcMod || cmdMod))
updateShadowFile (tdb);
return out;
*/
}
////////////////////////////////////////////////////////////////////////////////
void Context::shadow ()
{
throw std::string ("unimplemented Context::shadow");
}
////////////////////////////////////////////////////////////////////////////////
void Context::loadCorrectConfigFile ()
{
@ -237,7 +322,6 @@ void Context::loadCorrectConfigFile ()
////////////////////////////////////////////////////////////////////////////////
void Context::parse ()
{
command = "";
std::string descCandidate = "";
bool terminated = false;
bool foundSequence = false;
@ -249,15 +333,18 @@ void Context::parse ()
{
// The '--' argument shuts off all parsing - everything is an argument.
if (*arg == "--")
{
std::cout << "# parse terminator '" << *arg << "'" << std::endl;
terminated = true;
}
// Sequence
// Note: "add" doesn't require an ID
else if (command != "add" &&
sequence.valid (*arg) &&
! foundSomethingAfterSequence)
else if (cmd.command != "add" &&
! foundSomethingAfterSequence &&
sequence.valid (*arg))
{
std::cout << "# found sequence" << std::endl;
std::cout << "# parse sequence '" << *arg << "'" << std::endl;
sequence.parse (*arg);
foundSequence = true;
}
@ -309,30 +396,25 @@ void Context::parse ()
if (foundSequence)
foundSomethingAfterSequence = true;
std::cout << "# found subst" << std::endl;
std::cout << "# parse subst '" << *arg << "'" << std::endl;
subst.parse (*arg);
}
/*
// Command.
else if (command == "")
// It might be a command if one has not already been found.
else if (cmd.command == "" &&
cmd.valid (*arg))
{
std::cout << "# parse cmd '" << *arg << "'" << std::endl;
cmd.parse (*arg);
if (foundSequence)
foundSomethingAfterSequence = true;
std::string l = lowerCase (arg);
if (isCommand (l) && validCommand (l))
command = l;
else
{
if (descCandidate.length ())
descCandidate += " ";
descCandidate += arg;
}
}
*/
// Anything else is just considered description.
else
{
std::cout << "# parse description '" << *arg << "'" << std::endl;
if (foundSequence)
foundSomethingAfterSequence = true;
@ -345,6 +427,7 @@ void Context::parse ()
// terminated, therefore everything subsequently is a description.
else
{
std::cout << "# parse post-termination description '" << *arg << "'" << std::endl;
if (foundSequence)
foundSomethingAfterSequence = true;