diff --git a/DEVELOPERS b/DEVELOPERS index 6351d0819..e1bda67fe 100644 --- a/DEVELOPERS +++ b/DEVELOPERS @@ -1,22 +1,23 @@ Developers may wish to change task, and here is a high-level guide to the files included. - task.{cpp,h} Implements main, high level processing. - command.cpp Implements all non-report task commands. - report.cpp Implements all task reports. - parse.cpp Parses the command line. - TDB.{cpp,h} The task database, performs all file I/O. - T.{cpp,h} Represents a single task - parses a record from TDB, and also - composes record for TDB. Provides accessors for tasks. - Grid.{cpp,h} Implements a sparse 2D array, provides data storage for the - Table object. - Table.{cpp,h} Implements tabular data rendering, wrapping etc. - Config.{cpp,h} Implements a reader for the .taskrc file. - Date.{cpp,h} General date class for the time_t type. - text.cpp Text manipulation functions. - util.cpp General utility functions. - color.cpp Color support functions. - rules.cpp Auto-colorization rules. + task.{cpp,h} Implements main, high level processing. + command.cpp Implements all non-report task commands. + report.cpp Implements all task reports. + parse.cpp Parses the command line. + TDB.{cpp,h} The task database, performs all file I/O. + T.{cpp,h} Represents a single task - parses a record from TDB, and also + composes record for TDB. Provides accessors for tasks. + Grid.{cpp,h} Implements a sparse 2D array, provides data storage for the + Table object. + Table.{cpp,h} Implements tabular data rendering, wrapping etc. + Config.{cpp,h} Implements a reader for the .taskrc file. + Date.{cpp,h} General date class for the time_t type. + Duration.{cpp,h} General duration class for time deltas. + text.cpp Text manipulation functions. + util.cpp General utility functions. + color.cpp Color support functions. + rules.cpp Auto-colorization rules. Please send bugs, patches to task@beckingham.net diff --git a/src/Table.cpp b/src/Table.cpp index 1d78dfde1..37b9a48e5 100644 --- a/src/Table.cpp +++ b/src/Table.cpp @@ -48,6 +48,7 @@ #include #include #include +#include #include //////////////////////////////////////////////////////////////////////////////// @@ -989,7 +990,7 @@ void Table::sort (std::vector & order) break; else if ((std::string)*left != "" && (std::string)*right == "") SWAP - else if (convertDuration ((std::string)*left) > convertDuration ((std::string)*right)) + else if (Duration ((std::string)*left) > Duration ((std::string)*right)) SWAP break; @@ -998,7 +999,7 @@ void Table::sort (std::vector & order) break; else if ((std::string)*left == "" && (std::string)*right != "") SWAP - else if (convertDuration ((std::string)*left) < convertDuration ((std::string)*right)) + else if (Duration ((std::string)*left) < Duration ((std::string)*right)) SWAP break; } diff --git a/src/parse.cpp b/src/parse.cpp index ae10e2be5..7e5a86f9f 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -31,6 +31,7 @@ #include #include "Date.h" +#include "Duration.h" #include "task.h" #include "T.h" @@ -445,7 +446,9 @@ static bool validSubstitution ( //////////////////////////////////////////////////////////////////////////////// bool validDuration (std::string& input) { - return (convertDuration (input) != 0) ? true : false; + try { Duration (input); } + catch (...) { return false; } + return true; } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/task.cpp b/src/task.cpp index 4d2390154..4984b5a11 100644 --- a/src/task.cpp +++ b/src/task.cpp @@ -38,6 +38,7 @@ #include "Config.h" #include "Date.h" +#include "Duration.h" #include "Table.h" #include "TDB.h" #include "T.h" @@ -717,7 +718,10 @@ Date getNextRecurrence (Date& current, std::string& period) } // If the period is an 'easy' one, add it to current, and we're done. - int days = convertDuration (period); + int days = 0; + try { Duration du (period); days = du; } + catch (...) { days = 0; } + return current + (days * 86400); } diff --git a/src/tests/Makefile b/src/tests/Makefile index a71c8633e..6278cf5e7 100644 --- a/src/tests/Makefile +++ b/src/tests/Makefile @@ -2,7 +2,8 @@ PROJECT = t.t tdb.t date.t duration.t t.benchmark.t text.t autocomplete.t \ parse.t CFLAGS = -I. -I.. -Wall -pedantic -ggdb3 -fno-rtti LFLAGS = -L/usr/local/lib -OBJECTS = ../TDB.o ../T.o ../parse.o ../text.o ../Date.o ../util.o ../Config.o +OBJECTS = ../TDB.o ../T.o ../parse.o ../text.o ../Date.o ../Duration.o \ + ../util.o ../Config.o all: $(PROJECT) diff --git a/src/tests/duration.t.cpp b/src/tests/duration.t.cpp index 77e46a95c..c1c5e2108 100644 --- a/src/tests/duration.t.cpp +++ b/src/tests/duration.t.cpp @@ -25,9 +25,8 @@ // //////////////////////////////////////////////////////////////////////////////// #include -#include +#include #include -#include <../task.h> //////////////////////////////////////////////////////////////////////////////// // daily, day, Nd @@ -36,29 +35,37 @@ // 1st 2nd 3rd 4th .. 31st // quarterly, Nq // biannual, biyearly, annual, semiannual, yearly, Ny + +int convertDuration (const std::string& input) +{ + try { Duration d (input); return (int) d; } + catch (...) {} + return 0; +} + int main (int argc, char** argv) { UnitTest t (17); std::string d; - d = "daily"; t.is (convertDuration (d), 1, "duration daily = 1"); - d = "weekdays"; t.is (convertDuration (d), 1, "duration weekdays = 1"); - d = "day"; t.is (convertDuration (d), 1, "duration day = 1"); - d = "0d"; t.is (convertDuration (d), 0, "duration 0d = 0"); - d = "1d"; t.is (convertDuration (d), 1, "duration 1d = 1"); - d = "7d"; t.is (convertDuration (d), 7, "duration 7d = 7"); - d = "10d"; t.is (convertDuration (d), 10, "duration 10d = 10"); - d = "100d"; t.is (convertDuration (d), 100, "duration 100d = 100"); + t.is (convertDuration ("daily"), 1, "duration daily = 1"); + t.is (convertDuration ("weekdays"), 1, "duration weekdays = 1"); + t.is (convertDuration ("day"), 1, "duration day = 1"); + t.is (convertDuration ("0d"), 0, "duration 0d = 0"); + t.is (convertDuration ("1d"), 1, "duration 1d = 1"); + t.is (convertDuration ("7d"), 7, "duration 7d = 7"); + t.is (convertDuration ("10d"), 10, "duration 10d = 10"); + t.is (convertDuration ("100d"), 100, "duration 100d = 100"); - d = "weekly"; t.is (convertDuration (d), 7, "duration weekly = 7"); - d = "sennight"; t.is (convertDuration (d), 7, "duration sennight = 7"); - d = "biweekly"; t.is (convertDuration (d), 14, "duration biweekly = 14"); - d = "fortnight"; t.is (convertDuration (d), 14, "duration fortnight = 14"); - d = "0w"; t.is (convertDuration (d), 0, "duration 0w = 0"); - d = "1w"; t.is (convertDuration (d), 7, "duration 1w = 7"); - d = "7w"; t.is (convertDuration (d), 49, "duration 7w = 49"); - d = "10w"; t.is (convertDuration (d), 70, "duration 10w = 70"); - d = "100w"; t.is (convertDuration (d), 700, "duration 100w = 700"); + t.is (convertDuration ("weekly"), 7, "duration weekly = 7"); + t.is (convertDuration ("sennight"), 7, "duration sennight = 7"); + t.is (convertDuration ("biweekly"), 14, "duration biweekly = 14"); + t.is (convertDuration ("fortnight"), 14, "duration fortnight = 14"); + t.is (convertDuration ("0w"), 0, "duration 0w = 0"); + t.is (convertDuration ("1w"), 7, "duration 1w = 7"); + t.is (convertDuration ("7w"), 49, "duration 7w = 49"); + t.is (convertDuration ("10w"), 70, "duration 10w = 70"); + t.is (convertDuration ("100w"), 700, "duration 100w = 700"); return 0; } diff --git a/src/util.cpp b/src/util.cpp index 261e7d4af..736f24825 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -280,74 +280,6 @@ const std::string uuid () } #endif -//////////////////////////////////////////////////////////////////////////////// -// Recognize the following constructs, and return the number of days represented -int convertDuration (const std::string& input) -{ - std::string lower_input = lowerCase (input); - Date today; - - std::vector supported; - supported.push_back ("daily"); - supported.push_back ("day"); - supported.push_back ("weekly"); - supported.push_back ("weekdays"); - supported.push_back ("sennight"); - supported.push_back ("biweekly"); - supported.push_back ("fortnight"); - supported.push_back ("monthly"); - supported.push_back ("bimonthly"); - supported.push_back ("quarterly"); - supported.push_back ("biannual"); - supported.push_back ("biyearly"); - supported.push_back ("annual"); - supported.push_back ("semiannual"); - supported.push_back ("yearly"); - - std::vector matches; - if (autoComplete (lower_input, supported, matches) == 1) - { - std::string found = matches[0]; - - if (found == "daily" || found == "day") return 1; - else if (found == "weekdays") return 1; - else if (found == "weekly" || found == "sennight") return 7; - else if (found == "biweekly" || found == "fortnight") return 14; - else if (found == "monthly") return 30; - else if (found == "bimonthly") return 61; - else if (found == "quarterly") return 91; - else if (found == "semiannual") return 183; - else if (found == "yearly" || found == "annual") return 365; - else if (found == "biannual" || found == "biyearly") return 730; - } - - // Support \d+ d|w|m|q|y - else - { - // Verify all digits followed by d, w, m, q, or y. - unsigned int length = lower_input.length (); - for (unsigned int i = 0; i < length; ++i) - { - if (! isdigit (lower_input[i]) && - i == length - 1) - { - int number = ::atoi (lower_input.substr (0, i).c_str ()); - - switch (lower_input[length - 1]) - { - case 'd': return number * 1; break; - case 'w': return number * 7; break; - case 'm': return number * 30; break; - case 'q': return number * 91; break; - case 'y': return number * 365; break; - } - } - } - } - - return 0; // Error. -} - //////////////////////////////////////////////////////////////////////////////// std::string expandPath (const std::string& in) {