Integration - Context::parse
- Integrated Att parsing. - Unit tests are broken right now. - Stubbed Context::shadow. - Implemented Duration::valid. - Task is broken right now.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 <std::string> 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))
|
||||
|
||||
109
src/Duration.cpp
109
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 <std::string> 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 <std::string> 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 <std::string> 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 <std::string> 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
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
operator int ();
|
||||
operator time_t ();
|
||||
|
||||
bool valid (const std::string&) const;
|
||||
void parse (const std::string&);
|
||||
|
||||
private:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user