Enhancement - Subst parsing

- Corrected Subst parsing.
- Added more unit tests.
This commit is contained in:
Paul Beckingham 2009-06-07 00:28:21 -04:00
parent 9b78631e6f
commit a2a9fa7f35
4 changed files with 84 additions and 46 deletions

View file

@ -245,14 +245,6 @@ void Context::parse ()
{ {
if (!terminated) if (!terminated)
{ {
/*
size_t colon; // Pointer to colon in argument.
std::string from;
std::string to;
bool global;
std::vector <int> sequence;
*/
// The '--' argument shuts off all parsing - everything is an argument. // The '--' argument shuts off all parsing - everything is an argument.
if (*arg == "--") if (*arg == "--")
terminated = true; terminated = true;

View file

@ -69,7 +69,25 @@ Subst::~Subst ()
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
bool Subst::parse (const std::string& input) bool Subst::valid (const std::string& input) const
{
std::string ignored;
Nibbler n (input);
if (n.skip ('/') &&
n.getUntil ('/', ignored) &&
n.skip ('/') &&
n.getUntil ('/', ignored) &&
n.skip ('/'))
{
n.skip ('g');
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////////////////
void Subst::parse (const std::string& input)
{ {
Nibbler n (input); Nibbler n (input);
if (n.skip ('/') && if (n.skip ('/') &&
@ -79,18 +97,21 @@ bool Subst::parse (const std::string& input)
n.skip ('/')) n.skip ('/'))
{ {
mGlobal = n.skip ('g'); mGlobal = n.skip ('g');
return true;
}
return false; if (mFrom == "")
throw std::string ("Cannot substitute an empty string");
if (!n.depleted ())
throw std::string ("Unrecognized character(s) at end of substitution");
}
else
throw std::string ("Malformed substitution");
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void Subst::apply ( void Subst::apply (
std::string& description, std::string& description,
std::vector <Att>& annotations) const std::vector <Att>& annotations) const
{
if (mFrom != "")
{ {
std::string::size_type pattern; std::string::size_type pattern;
@ -134,6 +155,5 @@ void Subst::apply (
} }
} }
} }
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View file

@ -39,7 +39,8 @@ public:
Subst& operator= (const Subst&); // Assignment operator Subst& operator= (const Subst&); // Assignment operator
~Subst (); // Destructor ~Subst (); // Destructor
bool parse (const std::string&); bool valid (const std::string&) const;
void parse (const std::string&);
void apply (std::string&, std::vector <Att>&) const; void apply (std::string&, std::vector <Att>&) const;
public: public:

View file

@ -34,13 +34,32 @@ Context context;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
int main (int argc, char** argv) int main (int argc, char** argv)
{ {
UnitTest t (3); UnitTest t (15);
T2 task; T2 task;
task.set ("description", "one two three four"); task.set ("description", "one two three four");
Subst s; Subst s;
if (s.parse ("/two/TWO/")) t.ok (s.valid ("/a/b/x"), "valid /a/b/x");
t.ok (s.valid ("/a/b/"), "valid /a/b/");
t.ok (s.valid ("/two/TWO/"), "valid /two/TWO/");
t.ok (s.valid ("/e /E /g"), "valid /e /E /g");
t.ok (s.valid ("/from/to/g"), "valid /from/to/g");
t.ok (s.valid ("/long string//"), "valid /long string//");
t.ok (s.valid ("//fail/"), "valid //fail/");
bool good = true;
try { s.parse ("/a/b/x"); } catch (...) { good = false; }
t.notok (good, "failed /a/b/x");
good = true;
try { s.parse ("//to/"); } catch (...) { good = false; }
t.notok (good, "failed //to/");
good = true;
try { s.parse ("/two/TWO/"); } catch (...) { good = false; }
t.ok (good, "parsed /two/TWO/");
if (good)
{ {
std::string description = task.get ("description"); std::string description = task.get ("description");
std::vector <Att> annotations; std::vector <Att> annotations;
@ -54,7 +73,10 @@ int main (int argc, char** argv)
t.fail ("failed to parse '/two/TWO/'"); t.fail ("failed to parse '/two/TWO/'");
} }
if (s.parse ("/e /E /g")) good = true;
try { s.parse ("/e /E /g"); } catch (...) { good = false; }
t.ok (good, "parsed /e /E /g");
if (good)
{ {
std::string description = task.get ("description"); std::string description = task.get ("description");
std::vector <Att> annotations; std::vector <Att> annotations;
@ -68,7 +90,10 @@ int main (int argc, char** argv)
t.fail ("failed to parse '/e /E /g'"); t.fail ("failed to parse '/e /E /g'");
} }
if (s.parse ("/from/to/g")) good = true;
try { s.parse ("/from/to/g"); } catch (...) { good = false; }
t.ok (good, "parsed /from/to/g");
if (good)
{ {
std::string description = task.get ("description"); std::string description = task.get ("description");
std::vector <Att> annotations; std::vector <Att> annotations;