Enhancement - Command Line Parsing

- Fixed problem where a blank ID was considered valid.  For example,
  the command "task 1 -2" should use -2 as the description, but instead
  considered this to be the sequence 1,0,2.
- Replaced old validId calls with the new validSequence calls.
- A sequence has been redefined to be the first set of consecutive
  arguments that look like sequences.  Once broken by a non-sequence
  argument, all remaining args, even if they look like a sequence,
  are not considered part of the sequence.  This allows commands like
  "task append 1,3-5 Write 10 emails", where 10 is not part of the
  sequence because of the intervening "Write".
- Unit tests (parse.t.cpp) that exercise the parsing of sequences.
  Should probably be expanded to cover more.
This commit is contained in:
Paul Beckingham
2009-05-07 00:24:30 -04:00
parent 2975b9244a
commit 98391a0c24
4 changed files with 167 additions and 18 deletions

View File

@@ -299,6 +299,9 @@ static bool validAttribute (
////////////////////////////////////////////////////////////////////////////////
static bool validId (const std::string& input)
{
if (input.length () == 0)
return false;
for (size_t i = 0; i < input.length (); ++i)
if (!::isdigit (input[i]))
return false;
@@ -329,7 +332,6 @@ static bool validSequence (
int id = ::atoi (range[0].c_str ());
ids.push_back (id);
// std::cout << "# seq: " << id << std::endl;
break;
case 2:
@@ -344,10 +346,7 @@ static bool validSequence (
return false;
for (int i = low; i <= high; ++i)
// {
ids.push_back (i);
// std::cout << "# seq: " << i << std::endl;
// }
}
break;
@@ -357,7 +356,7 @@ static bool validSequence (
}
}
return ids.size () > 1 ? true : false;
return ids.size () ? true : false;
}
////////////////////////////////////////////////////////////////////////////////
@@ -448,8 +447,6 @@ bool validDuration (std::string& input)
// ------- ----------------------------------
// command first non-id recognized argument
//
// id ::= \d+
//
// substitution ::= "/" from "/" to "/g"
// | "/" from "/" to "/" ;
//
@@ -459,8 +456,8 @@ bool validDuration (std::string& input)
// attributes ::= word ":" value
// | word ":"
//
// sequence ::= id "," sequence
// | id "-" id ;
// sequence ::= \d+ "," sequence
// | \d+ "-" \d+ ;
//
// description (whatever isn't one of the above)
void parse (
@@ -471,6 +468,9 @@ void parse (
{
command = "";
bool foundSequence = false;
bool foundSomethingAfterSequence = false;
std::string descCandidate = "";
for (size_t i = 0; i < args.size (); ++i)
{
@@ -488,22 +488,20 @@ void parse (
// An id is the first argument found that contains all digits.
if (lowerCase (command) != "add" && // "add" doesn't require an ID
validSequence (arg, sequence))
validSequence (arg, sequence) &&
! foundSomethingAfterSequence)
{
foundSequence = true;
foreach (id, sequence)
task.addId (*id);
}
else if (lowerCase (command) != "add" && // "add" doesn't require an ID
task.getId () == 0 &&
validId (arg))
{
task.setId (::atoi (arg.c_str ()));
}
// Tags begin with + or - and contain arbitrary text.
else if (validTag (arg))
{
if (foundSequence)
foundSomethingAfterSequence = true;
if (arg[0] == '+')
task.addTag (arg.substr (1, std::string::npos));
else if (arg[0] == '-')
@@ -514,6 +512,9 @@ void parse (
// value.
else if ((colon = arg.find (":")) != std::string::npos)
{
if (foundSequence)
foundSomethingAfterSequence = true;
std::string name = lowerCase (arg.substr (0, colon));
std::string value = arg.substr (colon + 1, std::string::npos);
@@ -536,12 +537,18 @@ void parse (
// Substitution of description text.
else if (validSubstitution (arg, from, to, global))
{
if (foundSequence)
foundSomethingAfterSequence = true;
task.setSubstitution (from, to, global);
}
// Command.
else if (command == "")
{
if (foundSequence)
foundSomethingAfterSequence = true;
std::string l = lowerCase (arg);
if (isCommand (l) && validCommand (l))
command = l;
@@ -556,6 +563,9 @@ void parse (
// Anything else is just considered description.
else
{
if (foundSequence)
foundSomethingAfterSequence = true;
if (descCandidate.length ())
descCandidate += " ";
descCandidate += arg;