From 748300631a45f1f4292ca84a640107a1f192c8d5 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 9 Nov 2008 22:46:12 -0500 Subject: [PATCH] - Now parses the command line and can distinguish regular commands, as well as custom reports. --- src/command.cpp | 1 + src/parse.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++------- src/report.cpp | 19 +++++++++++ src/task.cpp | 63 ++++++++++++++++++----------------- src/task.h | 4 +++ 5 files changed, 133 insertions(+), 41 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index 3030d695c..3308fcd59 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -571,6 +571,7 @@ void handleExport (TDB& tdb, T& task, Config& conf) if (out.good ()) { out << "'id'," + << "'uuid'," << "'status'," << "'tags'," << "'entry'," diff --git a/src/parse.cpp b/src/parse.cpp index 43bc893c4..6bce33139 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -35,6 +35,8 @@ #include "T.h" //////////////////////////////////////////////////////////////////////////////// +// NOTE: These are static arrays only because there is no initializer list for +// std::vector. static const char* colors[] = { "bold", @@ -147,6 +149,9 @@ static const char* commands[] = "", }; +static std::vector customReports; + +//////////////////////////////////////////////////////////////////////////////// void guess (const std::string& type, const char** list, std::string& candidate) { std::vector options; @@ -180,6 +185,36 @@ void guess (const std::string& type, const char** list, std::string& candidate) } } +//////////////////////////////////////////////////////////////////////////////// +void guess (const std::string& type, std::vector& options, std::string& candidate) +{ + std::vector matches; + autoComplete (candidate, options, matches); + if (1 == matches.size ()) + candidate = matches[0]; + + else if (0 == matches.size ()) +// throw std::string ("Unrecognized ") + type + " '" + candidate + "'"; + candidate = ""; + + else + { + std::string error = "Ambiguous "; + error += type; + error += " '"; + error += candidate; + error += "' - could be either of "; + for (size_t i = 0; i < matches.size (); ++i) + { + if (i) + error += ", "; + error += matches[i]; + } + + throw error; + } +} + //////////////////////////////////////////////////////////////////////////////// static bool isCommand (const std::string& candidate) { @@ -190,7 +225,11 @@ static bool isCommand (const std::string& candidate) std::vector matches; autoComplete (candidate, options, matches); if (0 == matches.size ()) - return false; + { + autoComplete (candidate, customReports, matches); + if (0 == matches.size ()) + return false; + } return true; } @@ -284,15 +323,6 @@ static bool validTag (const std::string& input) //////////////////////////////////////////////////////////////////////////////// static bool validDescription (const std::string& input) { -/* - if (input.length () > 0 && - input.find ("\r") == std::string::npos && - input.find ("\f") == std::string::npos && - input.find ("\n") == std::string::npos) - return true; - - return false; -*/ if (input.length () == 0) return false; if (input.find ("\r") != std::string::npos) return false; if (input.find ("\f") != std::string::npos) return false; @@ -307,7 +337,12 @@ static bool validCommand (std::string& input) std::string copy = input; guess ("command", commands, copy); if (copy == "") - return false; + { + copy = input; + guess ("command", customReports, copy); + if (copy == "") + return false; + } input = copy; return true; @@ -450,4 +485,34 @@ void parse ( } //////////////////////////////////////////////////////////////////////////////// +void loadCustomReports (Config& conf) +{ + std::vector all; + conf.all (all); + + foreach (i, all) + { + if (i->substr (0, 7) == "report.") + { + std::string report = i->substr (7, std::string::npos); + unsigned int columns = report.find (".columns"); + if (columns != std::string::npos) + { + report = report.substr (0, columns); + customReports.push_back (report); + } + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +bool isCustomReport (const std::string& report) +{ + foreach (i, customReports) + if (*i == report) + return true; + + return false; +} +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/report.cpp b/src/report.cpp index ac19825a4..50f26257d 100644 --- a/src/report.cpp +++ b/src/report.cpp @@ -2673,3 +2673,22 @@ void gatherNextTasks ( } //////////////////////////////////////////////////////////////////////////////// +std::string handleCustomReport ( + TDB& tdb, + T& task, + Config& conf, + const std::string& report) +{ + std::cout << "# woohoo!" << std::endl; + + std::stringstream out; + + // TODO Load columns. + // TODO Load sort order. + + + + return out.str (); +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/task.cpp b/src/task.cpp index 98489b952..53b8b098e 100644 --- a/src/task.cpp +++ b/src/task.cpp @@ -763,42 +763,45 @@ std::string runTaskCommand ( std::cout << "[task " << defaultCommand << "]" << std::endl; } + loadCustomReports (conf); + std::string command; T task; parse (args, command, task, conf); std::string out = ""; - if (command == "" && task.getId ()) { handleModify (tdb, task, conf); } - else if (command == "add") { handleAdd (tdb, task, conf); } - else if (command == "done") { handleDone (tdb, task, conf); } - else if (command == "export") { handleExport (tdb, task, conf); } - else if (command == "projects") { out = handleProjects (tdb, task, conf); } - else if (command == "tags") { out = handleTags (tdb, task, conf); } - else if (command == "info") { out = handleInfo (tdb, task, conf); } - else if (command == "undelete") { out = handleUndelete (tdb, task, conf); } - else if (command == "delete") { out = handleDelete (tdb, task, conf); } - else if (command == "start") { out = handleStart (tdb, task, conf); } - else if (command == "stop") { out = handleStop (tdb, task, conf); } - else if (command == "undo") { out = handleUndo (tdb, task, conf); } - else if (command == "stats") { out = handleReportStats (tdb, task, conf); } - else if (command == "list") { if (gc) tdb.gc (); out = handleList (tdb, task, conf); } - else if (command == "long") { if (gc) tdb.gc (); out = handleLongList (tdb, task, conf); } - else if (command == "ls") { if (gc) tdb.gc (); out = handleSmallList (tdb, task, conf); } - else if (command == "completed") { if (gc) tdb.gc (); out = handleCompleted (tdb, task, conf); } - else if (command == "summary") { if (gc) tdb.gc (); out = handleReportSummary (tdb, task, conf); } - else if (command == "next") { if (gc) tdb.gc (); out = handleReportNext (tdb, task, conf); } - else if (command == "history") { if (gc) tdb.gc (); out = handleReportHistory (tdb, task, conf); } - else if (command == "ghistory") { if (gc) tdb.gc (); out = handleReportGHistory (tdb, task, conf); } - else if (command == "calendar") { if (gc) tdb.gc (); out = handleReportCalendar (tdb, task, conf); } - else if (command == "active") { if (gc) tdb.gc (); out = handleReportActive (tdb, task, conf); } - else if (command == "overdue") { if (gc) tdb.gc (); out = handleReportOverdue (tdb, task, conf); } - else if (command == "oldest") { if (gc) tdb.gc (); out = handleReportOldest (tdb, task, conf); } - else if (command == "newest") { if (gc) tdb.gc (); out = handleReportNewest (tdb, task, conf); } - else if (command == "colors") { out = handleColor ( conf); } - else if (command == "version") { out = handleVersion ( conf); } - else if (command == "help") { longUsage ( conf); } - else { shortUsage ( conf); } + if (command == "" && task.getId ()) { handleModify (tdb, task, conf ); } + else if (command == "add") { handleAdd (tdb, task, conf ); } + else if (command == "done") { handleDone (tdb, task, conf ); } + else if (command == "export") { handleExport (tdb, task, conf ); } + else if (command == "projects") { out = handleProjects (tdb, task, conf ); } + else if (command == "tags") { out = handleTags (tdb, task, conf ); } + else if (command == "info") { out = handleInfo (tdb, task, conf ); } + else if (command == "undelete") { out = handleUndelete (tdb, task, conf ); } + else if (command == "delete") { out = handleDelete (tdb, task, conf ); } + else if (command == "start") { out = handleStart (tdb, task, conf ); } + else if (command == "stop") { out = handleStop (tdb, task, conf ); } + else if (command == "undo") { out = handleUndo (tdb, task, conf ); } + else if (command == "stats") { out = handleReportStats (tdb, task, conf ); } + else if (command == "list") { if (gc) tdb.gc (); out = handleList (tdb, task, conf ); } // TODO replace with Custom + else if (command == "long") { if (gc) tdb.gc (); out = handleLongList (tdb, task, conf ); } // TODO replace with Custom + else if (command == "ls") { if (gc) tdb.gc (); out = handleSmallList (tdb, task, conf ); } // TODO replace with Custom + else if (command == "completed") { if (gc) tdb.gc (); out = handleCompleted (tdb, task, conf ); } // TODO replace with Custom + else if (command == "summary") { if (gc) tdb.gc (); out = handleReportSummary (tdb, task, conf ); } + else if (command == "next") { if (gc) tdb.gc (); out = handleReportNext (tdb, task, conf ); } // TODO replace with Custom + else if (command == "history") { if (gc) tdb.gc (); out = handleReportHistory (tdb, task, conf ); } + else if (command == "ghistory") { if (gc) tdb.gc (); out = handleReportGHistory (tdb, task, conf ); } + else if (command == "calendar") { if (gc) tdb.gc (); out = handleReportCalendar (tdb, task, conf ); } + else if (command == "active") { if (gc) tdb.gc (); out = handleReportActive (tdb, task, conf ); } // TODO replace with Custom + else if (command == "overdue") { if (gc) tdb.gc (); out = handleReportOverdue (tdb, task, conf ); } // TODO replace with Custom + else if (command == "oldest") { if (gc) tdb.gc (); out = handleReportOldest (tdb, task, conf ); } // TODO replace with Custom + else if (command == "newest") { if (gc) tdb.gc (); out = handleReportNewest (tdb, task, conf ); } // TODO replace with Custom + else if (command == "colors") { out = handleColor ( conf ); } + else if (command == "version") { out = handleVersion ( conf ); } + else if (command == "help") { longUsage ( conf ); } + else if (isCustomReport (command)) { if (gc) tdb.gc (); out = handleCustomReport (tdb, task, conf, command); } // New Custom reports + else { shortUsage ( conf ); } return out; } diff --git a/src/task.h b/src/task.h index b74aa1e6a..79c79ddf9 100644 --- a/src/task.h +++ b/src/task.h @@ -57,6 +57,8 @@ for (typeof (c) *foreach_p = & (c); \ void parse (std::vector &, std::string&, T&, Config&); bool validPriority (const std::string&); bool validDate (std::string&, Config&); +void loadCustomReports (Config&); +bool isCustomReport (const std::string&); // task.cpp void gatherNextTasks (const TDB&, T&, Config&, std::vector &, std::vector &); @@ -103,6 +105,8 @@ std::string handleReportStats (TDB&, T&, Config&); std::string handleReportOldest (TDB&, T&, Config&); std::string handleReportNewest (TDB&, T&, Config&); +std::string handleCustomReport (TDB&, T&, Config&, const std::string&); + // util.cpp bool confirm (const std::string&); void wrapText (std::vector &, const std::string&, const int);