From ed39b88719944aee8c673921b001221a361e6a93 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 7 Jun 2009 17:07:49 -0400 Subject: [PATCH] Integration - Context::parse - Integrated Att parsing. - Unit tests are broken right now. - Stubbed Context::shadow. - Implemented Duration::valid. - Task is broken right now. --- src/Att.cpp | 6 +++ src/Att.h | 1 + src/Context.cpp | 76 +++++++++++++++++++++++---------- src/Duration.cpp | 109 +++++++++++++++++++++++++++++++++-------------- src/Duration.h | 1 + src/T2.cpp | 3 +- src/T2.h | 2 +- 7 files changed, 143 insertions(+), 55 deletions(-) diff --git a/src/Att.cpp b/src/Att.cpp index 11b72209b..760c69f4f 100644 --- a/src/Att.cpp +++ b/src/Att.cpp @@ -119,6 +119,12 @@ bool Att::valid (const std::string& input) const // ^ | // |__________| // +void Att::parse (const std::string& input) +{ + Nibbler n (input); + parse (n); +} + void Att::parse (Nibbler& n) { // Ensure a clean object first. diff --git a/src/Att.h b/src/Att.h index fab2ad32d..1d736a0a3 100644 --- a/src/Att.h +++ b/src/Att.h @@ -42,6 +42,7 @@ public: ~Att (); // Destructor bool valid (const std::string&) const; + void parse (const std::string&); void parse (Nibbler&); bool validMod (const std::string&) const; bool match (const Att&) const; diff --git a/src/Context.cpp b/src/Context.cpp index daf4a4b0f..68590846a 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -220,6 +220,54 @@ void Context::dispatch () //////////////////////////////////////////////////////////////////////////////// void Context::shadow () { +/* + try + { + // Determine if shadow file is enabled. + std::string shadowFile = expandPath (context.config.get ("shadow.file")); + if (shadowFile != "") + { + std::string oldCurses = context.config.get ("curses"); + std::string oldColor = context.config.get ("color"); + context.config.set ("curses", "off"); + context.config.set ("color", "off"); + + // Run report. Use shadow.command, using default.command as a fallback + // with "list" as a default. + std::string command = context.config.get ("shadow.command", + context.config.get ("default.command", "list")); + std::vector args; + split (args, command, ' '); + std::string result = runTaskCommand (args, tdb); + + std::ofstream out (shadowFile.c_str ()); + if (out.good ()) + { + out << result; + out.close (); + } + else + throw std::string ("Could not write file '") + shadowFile + "'"; + + context.config.set ("curses", oldCurses); + context.config.set ("color", oldColor); + } + + // Optionally display a notification that the shadow file was updated. + if (context.config.get (std::string ("shadow.notify"), false)) + std::cout << "[Shadow file '" << shadowFile << "' updated]" << std::endl; + } + + catch (std::string& error) + { + std::cerr << error << std::endl; + } + + catch (...) + { + std::cerr << "Unknown error." << std::endl; + } +*/ throw std::string ("unimplemented Context::shadow"); } @@ -279,6 +327,7 @@ void Context::loadCorrectConfigFile () //////////////////////////////////////////////////////////////////////////////// void Context::parse () { + Att attribute; std::string descCandidate = ""; bool terminated = false; bool foundSequence = false; @@ -319,33 +368,16 @@ std::cout << "# parse sequence '" << *arg << "'" << std::endl; task.addRemoveTag (arg->substr (1, std::string::npos)); } */ -/* - // Attributes contain a constant string followed by a colon, followed by a - // value. - else if ((colon = arg->find (":")) != std::string::npos) + + else if (attribute.valid (*arg)) { +std::cout << "# parse attribute '" << *arg << "'" << std::endl; if (foundSequence) foundSomethingAfterSequence = true; - std::string name = lowerCase (arg->substr (0, colon)); - std::string value = arg->substr (colon + 1, std::string::npos); - - if (validAttribute (name, value)) - { - if (name != "recur" || validDuration (value)) - task.setAttribute (name, value); - } - - // If it is not a valid attribute, then allow the argument as part of - // the description. - else - { - if (descCandidate.length ()) - descCandidate += " "; - descCandidate += arg; - } + attribute.parse (*arg); + task[attribute.name ()] = attribute; } -*/ // Substitution of description and/or annotation text. else if (subst.valid (*arg)) diff --git a/src/Duration.cpp b/src/Duration.cpp index 442fa1fef..7d6c5116c 100644 --- a/src/Duration.cpp +++ b/src/Duration.cpp @@ -72,43 +72,90 @@ Duration::~Duration () { } +//////////////////////////////////////////////////////////////////////////////// +bool Duration::valid (const std::string& input) const +{ + std::string lower_input = lowerCase (input); + + std::vector supported; + supported.push_back ("daily"); // TODO i18n + supported.push_back ("day"); // TODO i18n + supported.push_back ("weekly"); // TODO i18n + supported.push_back ("weekdays"); // TODO i18n + supported.push_back ("sennight"); // TODO i18n + supported.push_back ("biweekly"); // TODO i18n + supported.push_back ("fortnight"); // TODO i18n + supported.push_back ("monthly"); // TODO i18n + supported.push_back ("bimonthly"); // TODO i18n + supported.push_back ("quarterly"); // TODO i18n + supported.push_back ("biannual"); // TODO i18n + supported.push_back ("biyearly"); // TODO i18n + supported.push_back ("annual"); // TODO i18n + supported.push_back ("semiannual"); // TODO i18n + supported.push_back ("yearly"); // TODO i18n + + std::vector matches; + if (autoComplete (lower_input, supported, matches) == 1) + return true; + + // Support \d+ d|w|m|q|y + // 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) + { + std::string type = lower_input.substr (length - 1, std::string::npos); + if (type == "d" || // TODO i18n + type == "w" || // TODO i18n + type == "m" || // TODO i18n + type == "q" || // TODO i18n + type == "y") // TODO i18n + return true; + } + } + + return false; +} + //////////////////////////////////////////////////////////////////////////////// void Duration::parse (const std::string& input) { std::string lower_input = lowerCase (input); 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"); + supported.push_back ("daily"); // TODO i18n + supported.push_back ("day"); // TODO i18n + supported.push_back ("weekly"); // TODO i18n + supported.push_back ("weekdays"); // TODO i18n + supported.push_back ("sennight"); // TODO i18n + supported.push_back ("biweekly"); // TODO i18n + supported.push_back ("fortnight"); // TODO i18n + supported.push_back ("monthly"); // TODO i18n + supported.push_back ("bimonthly"); // TODO i18n + supported.push_back ("quarterly"); // TODO i18n + supported.push_back ("biannual"); // TODO i18n + supported.push_back ("biyearly"); // TODO i18n + supported.push_back ("annual"); // TODO i18n + supported.push_back ("semiannual"); // TODO i18n + supported.push_back ("yearly"); // TODO i18n std::vector matches; if (autoComplete (lower_input, supported, matches) == 1) { std::string found = matches[0]; - if (found == "daily" || found == "day") mDays = 1; - else if (found == "weekdays") mDays = 1; - else if (found == "weekly" || found == "sennight") mDays = 7; - else if (found == "biweekly" || found == "fortnight") mDays = 14; - else if (found == "monthly") mDays = 30; - else if (found == "bimonthly") mDays = 61; - else if (found == "quarterly") mDays = 91; - else if (found == "semiannual") mDays = 183; - else if (found == "yearly" || found == "annual") mDays = 365; - else if (found == "biannual" || found == "biyearly") mDays = 730; + if (found == "daily" || found == "day") mDays = 1; // TODO i18n + else if (found == "weekdays") mDays = 1; // TODO i18n + else if (found == "weekly" || found == "sennight") mDays = 7; // TODO i18n + else if (found == "biweekly" || found == "fortnight") mDays = 14; // TODO i18n + else if (found == "monthly") mDays = 30; // TODO i18n + else if (found == "bimonthly") mDays = 61; // TODO i18n + else if (found == "quarterly") mDays = 91; // TODO i18n + else if (found == "semiannual") mDays = 183; // TODO i18n + else if (found == "yearly" || found == "annual") mDays = 365; // TODO i18n + else if (found == "biannual" || found == "biyearly") mDays = 730; // TODO i18n } // Support \d+ d|w|m|q|y @@ -125,18 +172,18 @@ void Duration::parse (const std::string& input) switch (lower_input[length - 1]) { - case 'd': mDays = number * 1; break; - case 'w': mDays = number * 7; break; - case 'm': mDays = number * 30; break; - case 'q': mDays = number * 91; break; - case 'y': mDays = number * 365; break; + case 'd': mDays = number * 1; break; // TODO i18n + case 'w': mDays = number * 7; break; // TODO i18n + case 'm': mDays = number * 30; break; // TODO i18n + case 'q': mDays = number * 91; break; // TODO i18n + case 'y': mDays = number * 365; break; // TODO i18n } } } } if (mDays == 0) - throw std::string ("The duration '") + input + "' was not recognized."; + throw std::string ("The duration '") + input + "' was not recognized."; // TODO i18n } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/Duration.h b/src/Duration.h index d804e318c..133ede0f7 100644 --- a/src/Duration.h +++ b/src/Duration.h @@ -42,6 +42,7 @@ public: operator int (); operator time_t (); + bool valid (const std::string&) const; void parse (const std::string&); private: diff --git a/src/T2.cpp b/src/T2.cpp index 57f90ee4f..02790c0ab 100644 --- a/src/T2.cpp +++ b/src/T2.cpp @@ -326,10 +326,11 @@ void T2::removeTag (const std::string& tag) } //////////////////////////////////////////////////////////////////////////////// -bool T2::validate () const +bool T2::valid () const { // TODO Verify until > due // TODO Verify entry < until, due, start, end + // TODO If name == "recur", then Duration::valid (value). return true; } diff --git a/src/T2.h b/src/T2.h index 476bb3911..d4e6b4100 100644 --- a/src/T2.h +++ b/src/T2.h @@ -76,7 +76,7 @@ public: void setAnnotations (const std::vector &); void addAnnotation (const std::string&); - bool validate () const; + bool valid () const; private: int determineVersion (const std::string&);