mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
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:
parent
190c6b53fc
commit
d702ba8f24
7 changed files with 128 additions and 35 deletions
|
@ -134,7 +134,7 @@ void Cmd::loadCommands ()
|
|||
commands.push_back (context.stringtable.get (CMD_OVERDUE, "overdue"));
|
||||
commands.push_back (context.stringtable.get (CMD_PROJECTS, "projects"));
|
||||
commands.push_back (context.stringtable.get (CMD_START, "start"));
|
||||
commands.push_back (context.stringtable.get (CMD_STATS, "statistics"));
|
||||
commands.push_back (context.stringtable.get (CMD_STATS, "stats"));
|
||||
commands.push_back (context.stringtable.get (CMD_STOP, "stop"));
|
||||
commands.push_back (context.stringtable.get (CMD_SUMMARY, "summary"));
|
||||
commands.push_back (context.stringtable.get (CMD_TAGS, "tags"));
|
||||
|
|
139
src/Context.cpp
139
src/Context.cpp
|
@ -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,6 +110,9 @@ void Context::initialize (int argc, char** argv)
|
|||
{
|
||||
// Capture the args.
|
||||
for (int i = 0; i < argc; ++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
|
||||
|
@ -148,12 +154,11 @@ int Context::run ()
|
|||
std::cout << "[1;32m--- start 1.8.0 ---[0m" << 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;
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "Config.h"
|
||||
#include "Sequence.h"
|
||||
#include "Subst.h"
|
||||
#include "Cmd.h"
|
||||
#include "T2.h"
|
||||
#include "TDB2.h"
|
||||
#include "StringTable.h"
|
||||
|
@ -47,6 +48,8 @@ public:
|
|||
void initialize (int, char**); // all startup
|
||||
int run (); // task classic
|
||||
int interactive (); // task interactive (not implemented)
|
||||
void dispatch (); // command handler dispatch
|
||||
void shadow (); // shadow file update
|
||||
|
||||
void message (const std::string&); // Message sink
|
||||
void footnote (const std::string&); // Footnote sink
|
||||
|
@ -64,8 +67,9 @@ public:
|
|||
T2 task;
|
||||
TDB2 tdb;
|
||||
StringTable stringtable;
|
||||
std::string program;
|
||||
std::vector <std::string> args;
|
||||
std::string command;
|
||||
Cmd cmd;
|
||||
|
||||
private:
|
||||
std::vector <std::string> messages;
|
||||
|
|
|
@ -68,6 +68,12 @@ bool Sequence::valid (const std::string& input) const
|
|||
if (range.size () < 1 ||
|
||||
range.size () > 2)
|
||||
return false;
|
||||
|
||||
if (range.size () == 1 && !validId (range[0]))
|
||||
return false;
|
||||
|
||||
if (range.size () == 2 && !validId (range[1]))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -5,7 +5,7 @@ LIBS =
|
|||
OBJECTS = main.o ../Context.o ../TDB2.o ../T2.o ../Sequence.o ../Filter.o \
|
||||
../Att.o ../Keymap.o ../Record.o ../StringTable.o ../Location.o \
|
||||
../util.o ../text.o ../Date.o ../Config.o ../Subst.o ../Nibbler.o \
|
||||
../parse.o ../Duration.o ../T.o
|
||||
../parse.o ../Duration.o ../T.o ../Cmd.o
|
||||
|
||||
all: $(PROJECT)
|
||||
|
||||
|
|
|
@ -304,7 +304,7 @@ int main (int argc, char** argv)
|
|||
try
|
||||
{
|
||||
context.initialize (argc, argv);
|
||||
if (context.args[0].find ("itask") != std::string::npos)
|
||||
if (context.program.find ("itask") != std::string::npos)
|
||||
status = context.interactive ();
|
||||
else
|
||||
status = context.run ();
|
||||
|
|
|
@ -48,6 +48,8 @@ int main (int argc, char** argv)
|
|||
t.notok (seq.valid ("1--2"), "not valid 1--2");
|
||||
t.notok (seq.valid ("1-2-3"), "not valid 1-2-3");
|
||||
t.notok (seq.valid ("-1-2"), "not valid -1-2");
|
||||
t.notok (seq.valid ("1-two"), "not valid 1-two");
|
||||
t.notok (seq.valid ("one-2"), "not valid one-2");
|
||||
|
||||
t.ok (seq.valid ("1"), "valid 1");
|
||||
t.ok (seq.valid ("1,3"), "valid 1,3");
|
||||
|
@ -55,8 +57,6 @@ int main (int argc, char** argv)
|
|||
t.ok (seq.valid ("1,3-5,7"), "valid 1,3-5,7");
|
||||
t.ok (seq.valid ("1-1000"), "valid 1-1000");
|
||||
t.ok (seq.valid ("1-1001"), "valid 1-1001");
|
||||
t.ok (seq.valid ("1-two"), "valid 1-two");
|
||||
t.ok (seq.valid ("one-2"), "valid one-2");
|
||||
t.ok (seq.valid ("1-5,3-7"), "valid 1-5,3-7");
|
||||
|
||||
// 1
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue