diff --git a/AUTHORS b/AUTHORS index ffcf9c092..d045cad9b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -3,6 +3,8 @@ Principal Author: Contributing Authors: Damian Glenny + Andy Lester + H. İbrahim Güngör With thanks to: Eugene Kramer @@ -12,7 +14,7 @@ With thanks to: Thomas Engel Nishiishii galvanizd - H. İbrahim Güngör Stas Antons - Andy Lester + Vincent Fleuranceau + T. Charles Yun diff --git a/ChangeLog b/ChangeLog index 606cbf7ac..f924b0d61 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,12 +7,34 @@ represents a feature release, and the Z represents a patch. ------ current release --------------------------- -1.4.1 (7/?/2008) +1.4.2 (9/13/2008) + + "task undo" can now retract a "task done" command, provided no reports + have been run (and therefore TDB::gc run) + + Task now correctly sorts on entire strings, instead of just the first + character (thanks to Andy Lester) + + Task now uses dashes (-----) to column underlines when color is disabled + (thanks to Vincent Fleuranceau) + + Task now allows mixed case attribute names (pri:, PRI:, Pri: ...) and + commands (add, ADD, Add ...) (thanks to Vincent Fleuranceau) + + Task now supports a default project and priority for new tasks, via + the new "default.project" and "default.priority" configuration variables + (thanks to Vincent Fleuranceau) + + Task supports improved word-wrapping to the terminal width + + Task now supports "default.command" configuration variable (for example + it could contain "list due:tomorrow") that is the command that is run + whenever task is invoked with no arguments. + + Bug: Now properly supports relative dates in filters (task list due:eom, + task list due:tomorrow, task list due:23rd ...) + + Bug: Source now properly includes in order to build clean + using gcc 4.3. + +------ old releases ------------------------------ + +1.4.1 (7/18/2008) + Bug: Descriptions can not be altered with "task 123 New description" + Tweak: For "task calendar" month names are now centered over the month + Removed TUTORIAL file contents in favor of online version - ------- old releases ------------------------------ + + Provided Mac .pkg binary 1.4.0 (7/10/2008) + New recurring tasks feature diff --git a/NEWS b/NEWS index de3298f15..18b4251e8 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ Task has been built and tested on the following configurations: - Fedora Core 8 - Fedora Core 9 - Ubuntu 8 Hardy Heron + - Ubuntu 9 Feisty Fawn - Solaris 10 - Cygwin 1.5.25-14 diff --git a/configure.ac b/configure.ac index d9f7bbeb4..9d7bc2d33 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT(task, 1.4.1, bugs@beckingham.net) +AC_INIT(task, 1.4.2, bugs@beckingham.net) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([src/task.cpp]) AC_CONFIG_HEADER([auto.h]) diff --git a/html/advanced.html b/html/advanced.html index feed82b65..3208f2671 100644 --- a/html/advanced.html +++ b/html/advanced.html @@ -43,6 +43,25 @@ lists all these commands.

+

+ However, if the following configuration variable is specified: +

+ +
default.command=list pri:H
+ +

+ Then this command will be run whenever task is run without arguments. + This means that your most common task command can be run simply + with the command: +

+ +
% task
+[task list project:foo]
+
+ID Project Pri Description
+ 1 foo     H   Design the thing
+ 2 foo         Build the thing
+ % task projects

This report generates a list of all the different projects that you diff --git a/html/config.html b/html/config.html index b241b8d92..251766af1 100644 --- a/html/config.html +++ b/html/config.html @@ -210,6 +210,8 @@

color
May be "on" or "off". Determines whether task uses color. + When "off", task will use dashes (-----) to underline column + headings.
@@ -246,6 +248,44 @@
Colors any task where the description contains X.
+ +
default.project
+
+ Provides a default project name for the "task add ..." command. +
+ +
default.priority
+
+ Provides a default priority for the "task add ..." command. +
+ +
default.command
+
+

+ Provides a default command that is run every time task is + invoked with no arguments. For example, if set to: +

+ +
default.command=list project:foo
+ +

+ Then task will run the "list project:foo" command if no + command is specified. This means that by merely typing: +

+ +
% task
+[task list project:foo]
+
+ID Project Pri Description
+ 1 foo     H   Design the thing
+ 2 foo         Build the thing
+ +

+ Note that the value of this variable is simply the command + line that you would ordinarily type, but without the + preceding "task" program name. +

+

diff --git a/html/task.html b/html/task.html index 0dd342053..cec9f6ae7 100644 --- a/html/task.html +++ b/html/task.html @@ -75,27 +75,45 @@ - + - + +
Source:task-1.4.1.tar.gztask-1.4.2.tar.gz
Mac OS X 10.5 (Leopard) Intel-only:task-1.4.1.pkgtask-1.4.2.pkg
-

New in version 1.4.1 (7/18/2008)

+

New in version 1.4.2 (9/13/2008)

diff --git a/html/versions.html b/html/versions.html index 30df5851f..e6e3ffe4f 100644 --- a/html/versions.html +++ b/html/versions.html @@ -35,6 +35,20 @@

+

+

New in version 1.4.1 (7/18/2008)

+ task-1.4.1.tar.gz +
+ Mac OS X 10.5 (Leopard) Intel-only: + task-1.4.1.pkg +

+ +

New in version 1.4.0 (7/10/2008)

Source: task-1.4.0.tar.gz diff --git a/ideas.txt b/ideas.txt index 261044c07..09cea7499 100644 --- a/ideas.txt +++ b/ideas.txt @@ -20,51 +20,3 @@ Test Suite - debug=on to cause all cout to be csv - regression tests for every bug, command, feature -Recurrence - + new T::status recurring (stored as R) - + new user-specifiable attributes - recur: [until:] - + duration: - daily, day, 1d - Nd - weekly, 1w - Nw - biweekly - monthly, 1m - bimonthly - Nm - quarterly, 1q - Nq - biannual, biyearly - annual, yearly, 1y - Na, Ny - + recur: without due: => Error - + until: without recur: => Error - + New file format: supports status R, recur:, until:, base:, range: - - on TDB.gc, adjust base: and compress range: for T::status == recurring - - all recurring tasks are removed from lists by T::*pendingT, and a synthetic - addendum is generated - - when a recurring task is completed, range: is updated, and a synthetic - task is added to completed.data that retains the attributes of the root - - - Scenario: - # Today = 6/22/2008 - % task add Friday due:6/15/2008 recur:weekly until 8/1/2008 - # task must generate a base and range - # base:6/15/2008 - # range:------- - # ^6/15 - # ^6/22 - # ^6/29 - # ^7/6 - # ^7/13 - # ^7/20 - # ^7/27 - % task ls - 1 Friday 6/15/2008 .lte. today (overdue) - 2 Friday 6/22/2008 .lte. today (due) - 3 Friday 6/29/2008 one recurrence - 4 Friday 7/6/2008 (not shown) - 5 Friday 7/13/2008 (not shown) - 6 Friday 7/20/2008 (not shown) - 7 Friday 7/27/2008 (not shown) - diff --git a/src/Date.cpp b/src/Date.cpp index f7378bbb3..67ac7e7c7 100644 --- a/src/Date.cpp +++ b/src/Date.cpp @@ -543,22 +543,35 @@ bool Date::isRelativeDate (const std::string& input) else today += (dow - today.dayOfWeek ()) * 86400; - mT = today.mT; + int m, d, y; + today.toMDY (m, d, y); + Date then (m, d, y); + + mT = then.mT; return true; } else if (found == "today") { - mT = today.mT; + Date then (today.month (), + today.day (), + today.year ()); + mT = then.mT; return true; } else if (found == "tomorrow") { - mT = today.mT + 86400; + Date then (today.month (), + today.day (), + today.year ()); + mT = then.mT + 86400; return true; } else if (found == "yesterday") { - mT = today.mT - 86400; + Date then (today.month (), + today.day (), + today.year ()); + mT = then.mT - 86400; return true; } else if (found == "eom") diff --git a/src/Table.cpp b/src/Table.cpp index 89f65bdf9..6de729b4b 100644 --- a/src/Table.cpp +++ b/src/Table.cpp @@ -54,6 +54,7 @@ Table::Table () : mRows (0) , mIntraPadding (1) + , mDashedUnderline (false) , mTablePadding (0) , mTableWidth (0) , mSuppressWS (false) @@ -103,6 +104,12 @@ void Table::setTableWidth (int width) mTableWidth = width; } +//////////////////////////////////////////////////////////////////////////////// +void Table::setTableDashedUnderline () +{ + mDashedUnderline = true; +} + //////////////////////////////////////////////////////////////////////////////// int Table::addColumn (const std::string& col) { @@ -582,7 +589,57 @@ const std::string Table::formatHeader ( fg, bg, Text::colorize ( decoration, Text::nocolor, - pad + preJust+ data + postJust + pad) + intraPad); + pad + preJust + data + postJust + pad) + intraPad); +} + +//////////////////////////////////////////////////////////////////////////////// +// data One Data to be rendered +// width 8 Max data width for column/specified width +// padding 1 Extra padding around data +// intraPadding 0 Extra padding between columns only +// justification right Alignment withing padding +// +// Returns: +// "------- " +// ------- data +// ^ ^ padding +// ^ intraPadding +// ^^^^^^^^ width +// ^ ^ fg/bg +// +const std::string Table::formatHeaderDashedUnderline ( + int col, + int width, + int padding) +{ + assert (width > 0); + + Text::color fg = getHeaderFg (col); + Text::color bg = getHeaderBg (col); + Text::color decoration = getHeaderUnderline (col); + + std::string data = ""; + for (int i = 0; i < width; ++i) + data += '-'; + + std::string pad = ""; + std::string intraPad = ""; + std::string attrOn = ""; + std::string attrOff = ""; + + for (int i = 0; i < padding; ++i) + pad += " "; + + // Place the value within the available space - justify. + if (col < (signed) mColumns.size () - 1) + for (int i = 0; i < getIntraPadding (); ++i) + intraPad += " "; + + return Text::colorize ( + fg, bg, + Text::colorize ( + decoration, Text::nocolor, + pad + data + pad) + intraPad); } //////////////////////////////////////////////////////////////////////////////// @@ -758,12 +815,12 @@ void Table::sort (std::vector & order) break; case ascendingCharacter: - if ((char)*left > (char)*right) + if ((std::string)*left > (std::string)*right) SWAP break; case descendingCharacter: - if ((char)*left < (char)*right) + if ((std::string)*left < (std::string)*right) SWAP break; @@ -861,13 +918,24 @@ const std::string Table::render () // Print column headers in column order. std::string output; + std::string underline; for (size_t col = 0; col < mColumns.size (); ++col) + { output += formatHeader ( col, mCalculatedWidth[col], mColumnPadding[col]); + if (mDashedUnderline) + underline += formatHeaderDashedUnderline ( + col, + mCalculatedWidth[col], + mColumnPadding[col]); + } + output += "\n"; + if (underline.length ()) + output += underline + "\n"; // Determine row order, according to sort options. std::vector order; diff --git a/src/Table.h b/src/Table.h index 7428453ec..6a793af0c 100644 --- a/src/Table.h +++ b/src/Table.h @@ -51,6 +51,7 @@ public: void setTablePadding (int); void setTableIntraPadding (int); void setTableWidth (int); + void setTableDashedUnderline (); int addColumn (const std::string&); void setColumnColor (int, Text::color, Text::color); @@ -98,6 +99,7 @@ private: just getJustification (const int, const int); just getHeaderJustification (const int); const std::string formatHeader (const int, const int, const int); + const std::string formatHeaderDashedUnderline (const int, const int, const int); void formatCell (const int, const int, const int, const int, std::vector &, std::string&); void optimize (std::string&); void sort (std::vector &); @@ -110,6 +112,7 @@ private: std::map mFg; std::map mBg; std::map mUnderline; + bool mDashedUnderline; // Padding... int mTablePadding; diff --git a/src/command.cpp b/src/command.cpp index 5344a4037..51d5f7f37 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -66,6 +66,20 @@ void handleAdd (const TDB& tdb, T& task, Config& conf) task.setAttribute ("mask", ""); } +/**/ + // Override with default.project, if not specified. + if (task.getAttribute ("project") == "") + task.setAttribute ("project", conf.get ("default.project", "")); + + // Override with default.priority, if not specified. + if (task.getAttribute ("priority") == "") + { + std::string defaultPriority = conf.get ("default.priority", ""); + if (validPriority (defaultPriority)) + task.setAttribute ("priority", defaultPriority); + } +/**/ + if (task.getDescription () == "") throw std::string ("Cannot add a blank task."); @@ -203,6 +217,49 @@ void handleUndelete (TDB& tdb, T& task, Config& conf) << "command is run immediately after the errant delete command." << std::endl; } +//////////////////////////////////////////////////////////////////////////////// +// If a task is done, but is still in the pending file, then it may be undone +// simply by changing it's status. +void handleUndo (TDB& tdb, T& task, Config& conf) +{ + std::vector all; + tdb.allPendingT (all); + + int id = task.getId (); + std::vector ::iterator it; + for (it = all.begin (); it != all.end (); ++it) + { + if (it->getId () == id) + { + if (it->getStatus () == T::completed) + { + if (it->getAttribute ("recur") != "") + { + std::cout << "Task does not support 'undo' for recurring tasks." << std::endl; + return; + } + + T restored (*it); + restored.setStatus (T::pending); + restored.removeAttribute ("end"); + tdb.modifyT (restored); + + std::cout << "Task " << id << " successfully undone." << std::endl; + return; + } + else + { + std::cout << "Task " << id << " is not done - therefore cannot be undone." << std::endl; + return; + } + } + } + + std::cout << "Task " << id + << " not found - tasks can only be reliably undone if the undo" << std::endl + << "command is run immediately after the errant done command." << std::endl; +} + //////////////////////////////////////////////////////////////////////////////// void handleVersion (Config& conf) { @@ -217,6 +274,26 @@ void handleVersion (Config& conf) } #endif + // Create a table for the disclaimer. + Table disclaimer; + disclaimer.setTableWidth (width); + disclaimer.addColumn (" "); + disclaimer.setColumnWidth (0, Table::flexible); + disclaimer.setColumnJustification (0, Table::left); + disclaimer.addCell (disclaimer.addRow (), 0, + "Task comes with ABSOLUTELY NO WARRANTY; for details read the COPYING file " + "included. This is free software, and you are welcome to redistribute it " + "under certain conditions; again, see the COPYING file for details."); + + // Create a table for the URL. + Table link; + link.setTableWidth (width); + link.addColumn (" "); + link.setColumnWidth (0, Table::flexible); + link.setColumnJustification (0, Table::left); + link.addCell (link.addRow (), 0, + "See http://www.beckingham.net/task.html for the latest releases and a full tutorial."); + // Create a table for output. Table table; table.setTableWidth (width); @@ -255,18 +332,10 @@ void handleVersion (Config& conf) << " " << VERSION << std::endl - << std::endl - << "Task comes with ABSOLUTELY NO WARRANTY; for details read the COPYING file" - << std::endl - << "included. This is free software, and you are welcome to redistribute it" - << std::endl - << "under certain conditions; again, see the COPYING file for details." - << std::endl + << disclaimer.render () << std::endl << table.render () - << std::endl - << "See http://www.beckingham.net/task.html for the latest releases and a full tutorial." - << std::endl + << link.render () << std::endl; // Verify installation. This is mentioned in the documentation as the way to diff --git a/src/parse.cpp b/src/parse.cpp index 770c2b2f0..98c376fe2 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -141,6 +141,7 @@ static const char* commands[] = "summary", "tags", "undelete", + "undo", "usage", "version", "", @@ -207,7 +208,7 @@ bool validDate (std::string& date, Config& conf) } //////////////////////////////////////////////////////////////////////////////// -static bool validPriority (const std::string& input) +bool validPriority (const std::string& input) { if (input != "H" && input != "M" && @@ -370,8 +371,8 @@ void parse ( std::string to; // An id is the first argument found that contains all digits. - if (command != "add" && // "add" doesn't require an ID - task.getId () == 0 && + if (lowerCase (command) != "add" && // "add" doesn't require an ID + task.getId () == 0 && validId (arg)) task.setId (::atoi (arg.c_str ())); @@ -388,7 +389,7 @@ void parse ( // value. else if ((colon = arg.find (":")) != std::string::npos) { - std::string name = arg.substr (0, colon); + std::string name = lowerCase (arg.substr (0, colon)); std::string value = arg.substr (colon + 1, std::string::npos); if (validAttribute (name, value, conf)) @@ -412,8 +413,9 @@ void parse ( // Command. else if (command == "") { - if (isCommand (arg) && validCommand (arg)) - command = arg; + std::string l = lowerCase (arg); + if (isCommand (l) && validCommand (l)) + command = l; else descCandidate += arg; // throw std::string ("'") + arg + "' is not a valid command."; diff --git a/src/report.cpp b/src/report.cpp index e0ec8db90..c82abeaac 100644 --- a/src/report.cpp +++ b/src/report.cpp @@ -79,6 +79,7 @@ void filter (std::vector& all, T& task) // Apply attribute filter. matches = 0; foreach (a, attrList) + { if (a->first == "project") { if (a->second.length () <= refTask.getAttribute (a->first).length ()) @@ -87,6 +88,7 @@ void filter (std::vector& all, T& task) } else if (a->second == refTask.getAttribute (a->first)) ++matches; + } if (matches == attrList.size ()) { @@ -143,7 +145,7 @@ void handleList (TDB& tdb, T& task, Config& conf) if (showAge) table.addColumn ("Age"); table.addColumn ("Description"); - if (conf.get ("color", true)) + if (conf.get (std::string ("color"), true)) { table.setColumnUnderline (0); table.setColumnUnderline (1); @@ -153,6 +155,8 @@ void handleList (TDB& tdb, T& task, Config& conf) table.setColumnUnderline (5); if (showAge) table.setColumnUnderline (6); } + else + table.setTableDashedUnderline (); table.setColumnWidth (0, Table::minimum); table.setColumnWidth (1, Table::minimum); @@ -291,6 +295,8 @@ void handleSmallList (TDB& tdb, T& task, Config& conf) table.setColumnUnderline (2); table.setColumnUnderline (3); } + else + table.setTableDashedUnderline (); table.setColumnWidth (0, Table::minimum); table.setColumnWidth (1, Table::minimum); @@ -414,6 +420,8 @@ void handleCompleted (TDB& tdb, T& task, Config& conf) table.setColumnUnderline (1); table.setColumnUnderline (2); } + else + table.setTableDashedUnderline (); table.setColumnWidth (0, Table::minimum); table.setColumnWidth (1, Table::minimum); @@ -493,6 +501,8 @@ void handleInfo (TDB& tdb, T& task, Config& conf) table.setColumnUnderline (0); table.setColumnUnderline (1); } + else + table.setTableDashedUnderline (); table.setColumnWidth (0, Table::minimum); table.setColumnWidth (1, Table::minimum); @@ -710,6 +720,8 @@ void handleLongList (TDB& tdb, T& task, Config& conf) table.setColumnUnderline (7); if (showAge) table.setColumnUnderline (8); } + else + table.setTableDashedUnderline (); table.setColumnWidth (0, Table::minimum); table.setColumnWidth (1, Table::minimum); @@ -913,6 +925,8 @@ void handleReportSummary (TDB& tdb, T& task, Config& conf) table.setColumnUnderline (2); table.setColumnUnderline (3); } + else + table.setTableDashedUnderline (); table.setColumnJustification (1, Table::right); table.setColumnJustification (2, Table::right); @@ -1056,6 +1070,8 @@ void handleReportNext (TDB& tdb, T& task, Config& conf) table.setColumnUnderline (5); if (showAge) table.setColumnUnderline (6); } + else + table.setTableDashedUnderline (); table.setColumnWidth (0, Table::minimum); table.setColumnWidth (1, Table::minimum); @@ -1275,6 +1291,8 @@ void handleReportHistory (TDB& tdb, T& task, Config& conf) table.setColumnUnderline (4); table.setColumnUnderline (5); } + else + table.setTableDashedUnderline (); table.setColumnJustification (2, Table::right); table.setColumnJustification (3, Table::right); @@ -1462,6 +1480,8 @@ void handleReportGHistory (TDB& tdb, T& task, Config& conf) table.setColumnUnderline (0); table.setColumnUnderline (1); } + else + table.setTableDashedUnderline (); // Determine the longest line. int maxLine = 0; @@ -1623,6 +1643,8 @@ void handleReportUsage (const TDB& tdb, T& task, Config& conf) table.setColumnUnderline (0); table.setColumnUnderline (1); } + else + table.setTableDashedUnderline (); table.setColumnJustification (1, Table::right); table.sortOn (1, Table::descendingNumeric); @@ -1681,6 +1703,8 @@ std::string renderMonths ( table.setColumnUnderline (i + 6); table.setColumnUnderline (i + 7); } + else + table.setTableDashedUnderline (); table.setColumnJustification (i + 0, Table::right); table.setColumnJustification (i + 1, Table::right); @@ -1896,6 +1920,8 @@ void handleReportActive (TDB& tdb, T& task, Config& conf) table.setColumnUnderline (3); table.setColumnUnderline (4); } + else + table.setTableDashedUnderline (); table.setColumnWidth (0, Table::minimum); table.setColumnWidth (1, Table::minimum); @@ -2011,6 +2037,8 @@ void handleReportOverdue (TDB& tdb, T& task, Config& conf) table.setColumnUnderline (3); table.setColumnUnderline (4); } + else + table.setTableDashedUnderline (); table.setColumnWidth (0, Table::minimum); table.setColumnWidth (1, Table::minimum); @@ -2126,6 +2154,8 @@ void handleReportOldest (TDB& tdb, T& task, Config& conf) table.setColumnUnderline (5); if (showAge) table.setColumnUnderline (6); } + else + table.setTableDashedUnderline (); table.setColumnWidth (0, Table::minimum); table.setColumnWidth (1, Table::minimum); @@ -2269,6 +2299,8 @@ void handleReportNewest (TDB& tdb, T& task, Config& conf) table.setColumnUnderline (5); if (showAge) table.setColumnUnderline (6); } + else + table.setTableDashedUnderline (); table.setColumnWidth (0, Table::minimum); table.setColumnWidth (1, Table::minimum); diff --git a/src/task.cpp b/src/task.cpp index 0d3f6c7f5..29951dee3 100644 --- a/src/task.cpp +++ b/src/task.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -125,6 +126,10 @@ static void shortUsage (Config& conf) table.addCell (row, 1, "task done ID"); table.addCell (row, 2, "Marks the specified task as completed"); + row = table.addRow (); + table.addCell (row, 1, "task undo ID"); + table.addCell (row, 2, "Marks the specified done task as pending, provided a report has not yet been run"); + row = table.addRow (); table.addCell (row, 1, "task projects"); table.addCell (row, 2, "Shows a list of all project names used, and how many tasks are in each"); @@ -295,10 +300,23 @@ int main (int argc, char** argv) if (conf.get ("command.logging") == "on") tdb.logCommand (argc, argv); - // Parse the command line. + // If argc == 1 and the default.command configuration variable is set, + // then use that, otherwise stick with argc/argv. std::vector args; - for (int i = 1; i < argc; ++i) - args.push_back (argv[i]); + std::string defaultCommand = conf.get ("default.command"); + if (argc == 1 && defaultCommand != "") + { + // Stuff the command line. + split (args, defaultCommand, ' '); + std::cout << "[task " << defaultCommand << "]" << std::endl; + } + else + { + // Parse the command line. + for (int i = 1; i < argc; ++i) + args.push_back (argv[i]); + } + std::string command; T task; parse (args, command, task, conf); @@ -316,6 +334,7 @@ int main (int argc, char** argv) else if (command == "delete") handleDelete (tdb, task, conf); else if (command == "start") handleStart (tdb, task, conf); else if (command == "done") handleDone (tdb, task, conf); + else if (command == "undo") handleUndo (tdb, task, conf); else if (command == "export") handleExport (tdb, task, conf); else if (command == "version") handleVersion ( conf); else if (command == "summary") handleReportSummary (tdb, task, conf); diff --git a/src/task.h b/src/task.h index 4a8dc78fd..7b732f423 100644 --- a/src/task.h +++ b/src/task.h @@ -55,6 +55,7 @@ for (typeof (c) *foreach_p = & (c); \ // parse.cpp void parse (std::vector &, std::string&, T&, Config&); +bool validPriority (const std::string&); bool validDate (std::string&, Config&); // task.cpp @@ -76,6 +77,7 @@ void handleExport (TDB&, T&, Config&); void handleDelete (TDB&, T&, Config&); void handleStart (TDB&, T&, Config&); void handleDone (TDB&, T&, Config&); +void handleUndo (TDB&, T&, Config&); void handleModify (TDB&, T&, Config&); void handleColor (Config&); diff --git a/src/tests/in b/src/tests/in new file mode 100755 index 000000000..761c1f877 --- /dev/null +++ b/src/tests/in @@ -0,0 +1,15 @@ +./task add monday due:monday +./task add tuesday due:tuesday +./task add wednesday due:wednesday +./task add thursday due:thursday +./task add friday due:friday +./task add saturday due:saturday +./task add sunday due:sunday +./task add yesterday due:yesterday +./task add today due:today +./task add tomorrow due:tomorrow +./task add eow due:eow +./task add eom due:eom +./task add eoy due:eoy +./task add 21st due:21st + diff --git a/src/tests/out b/src/tests/out new file mode 100755 index 000000000..c0b81f3b4 --- /dev/null +++ b/src/tests/out @@ -0,0 +1,15 @@ +./task li due:monday +./task li due:tuesday +./task li due:wednesday +./task li due:thursday +./task li due:friday +./task li due:saturday +./task li due:sunday +./task li due:yesterday +./task li due:today +./task li due:tomorrow +./task li due:eow +./task li due:eom +./task li due:eoy +./task li due:21st +