From a98951a8c33c16759899cc90a9231dadd7192f20 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Mon, 1 Jun 2009 01:25:07 -0400 Subject: [PATCH] Enhancements - Complete Record parsing - Enhanced Record unit tests - Fixed broken Att unit tests - Fixed broken Att --- src/Att.cpp | 13 +++---- src/Record.cpp | 27 +++++---------- src/Record.h | 2 -- src/tests/att.t.cpp | 11 +++--- src/tests/record.t.cpp | 78 ++++++++++++++++++++---------------------- 5 files changed, 54 insertions(+), 77 deletions(-) diff --git a/src/Att.cpp b/src/Att.cpp index 2d5eb9edd..0781d32b0 100644 --- a/src/Att.cpp +++ b/src/Att.cpp @@ -114,19 +114,16 @@ bool Att::parse (Nibbler& n) if (n.skip (':')) { - if (n.getQuoted ('"', mValue)) - return true; - - // This is here to tolerate unquoted values. + // Both quoted and unquoted Att's are accepted. // Consider removing this for a stricter parse. - if (n.getUntil (' ', mValue)) + if (n.getQuoted ('"', mValue) || + n.getUntil (' ', mValue)) { - dequote (mValue); decode (mValue); return true; } - - throw std::string ("Missing attribute value"); + else + throw std::string ("Missing attribute value"); } else throw std::string ("Missing : after attribute name"); diff --git a/src/Record.cpp b/src/Record.cpp index 5c185dad2..27ca8fd94 100644 --- a/src/Record.cpp +++ b/src/Record.cpp @@ -37,25 +37,12 @@ Record::Record () { } -//////////////////////////////////////////////////////////////////////////////// -Record::Record (const Record& other) -{ - throw std::string ("unimplemented Record::Record"); - *this = other; -} - //////////////////////////////////////////////////////////////////////////////// Record::Record (const std::string& input) { parse (input); } -//////////////////////////////////////////////////////////////////////////////// -Record& Record::operator= (const Record& other) -{ - return *this; -} - //////////////////////////////////////////////////////////////////////////////// Record::~Record () { @@ -80,9 +67,9 @@ std::string Record::composeF4 () //////////////////////////////////////////////////////////////////////////////// // -// start --> name --> : --> " --> value --> " --> end -// ^ | -// +------------- \s <--------------+ +// [ --> start --> name --> : --> " --> value --> " --> ] --> end +// ^ | +// +------------- \s <--------------+ // void Record::parse (const std::string& input) { @@ -93,13 +80,15 @@ void Record::parse (const std::string& input) n.skip (']') && n.depleted ()) { - Nibbler nl (line); + if (line.length () == 0) + throw std::string ("Empty FF4 record"); + Nibbler nl (line); Att a; - while (a.parse (nl)) + while (!nl.depleted () && a.parse (nl)) { - nl.skip (' '); (*this)[a.name ()] = a; + nl.skip (' '); } std::string remainder; diff --git a/src/Record.h b/src/Record.h index d8313e595..93b1a85f7 100644 --- a/src/Record.h +++ b/src/Record.h @@ -36,9 +36,7 @@ class Record : public std::map { public: Record (); // Default constructor - Record (const Record&); // Copy constructor Record (const std::string&); // Copy constructor - Record& operator= (const Record&); // Assignment operator virtual ~Record (); // Destructor std::string composeF4 (); diff --git a/src/tests/att.t.cpp b/src/tests/att.t.cpp index 939ed1487..c0bcb8adc 100644 --- a/src/tests/att.t.cpp +++ b/src/tests/att.t.cpp @@ -30,7 +30,7 @@ //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (38); + UnitTest t (37); Att a1 ("name", "value"); t.is (a1.name (), "name", "Att::Att (name, value), Att.name"); @@ -145,22 +145,19 @@ int main (int argc, char** argv) good = true; try {a7.parse (n);} catch (...) {good = false;} t.ok (good, "Att::parse (name:\"value)"); - t.is (a7.composeF4 (), "name:\"value\"", "Att::composeF4 -> name:\"value\""); + t.is (a7.composeF4 (), "name:\""value\"", "Att::composeF4 -> name:\""value\""); n = Nibbler ("name:value\""); good = true; try {a7.parse (n);} catch (...) {good = false;} t.ok (good, "Att::parse (name:value\")"); - t.is (a7.composeF4 (), "name:\"value\"", "Att::composeF4 -> name:\"value\""); + t.is (a7.composeF4 (), "name:\"value"\"", "Att::composeF4 -> name:\"value"\""); n = Nibbler ("name:val\"ue"); good = true; try {a7.parse (n);} catch (...) {good = false;} t.ok (good, "Att::parse (name:val\"ue)"); - t.is (a7.composeF4 (), "name:\"value\"", "Att::composeF4 -> name:\"value\""); - - n = Nibbler ("name:\"\"va\"\"\"\"\"lu\"\"\"e\"\""); - t.is (a7.composeF4 (), "name:\"value\"", "Att::composeF4 (name:\"\"va\"\"\"\"\"lu\"\"\"e\"\")"); + t.is (a7.composeF4 (), "name:\"val"ue\"", "Att::composeF4 -> name:\"val"ue\""); n = Nibbler ("name\""); good = true; diff --git a/src/tests/record.t.cpp b/src/tests/record.t.cpp index 8b238dea1..2f694013f 100644 --- a/src/tests/record.t.cpp +++ b/src/tests/record.t.cpp @@ -29,57 +29,53 @@ #include #include -//////////////////////////////////////////////////////////////////////////////// -Record parseRecord (const std::string& input) -{ - try - { - Record r (input); - return r; - } - - catch (std::string& e) - { - std::cout << "# Exception: " << e << std::endl; - } - - catch (...) - { - std::cout << "# Exception!" << std::endl; - } - - return Record (); -} - //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (4); + UnitTest t (11); // (blank) - Record record = parseRecord (""); - t.is (record.size (), (size_t)0, "Record (blank)"); + bool good = true; + Record record; + + try {record = Record ("");} + catch (std::string& e){t.diag (e); good = false;} + t.notok (good, "Record::Record ('')"); // [] - record = parseRecord ("[]"); - t.is (record.size (), (size_t)0, "Record []"); + good = true; + try {record = Record ("[]");} + catch (std::string& e){t.diag (e); good = false;} + t.notok (good, "Record::Record ('[]')"); + + // [name:value] + good = true; + try {record = Record ("[name:value]");} + catch (std::string& e){t.diag (e); good = false;} + t.ok (good, "Record::Record ('[name:value]')"); + t.is (record.get ("name"), "value", "name=value"); // [name:"value"] - record = parseRecord ("[name:\"value\"]"); - t.is (record.size (), (size_t)1, "Record [name:value]"); - if (record.size () == 1) - { - Att a = record["name"]; - t.is (a.name (), "name", "Record [name:value] -> 'name'"); - } - else - { - t.fail ("Record [name:value] -> 'name'"); - } + good = true; + try {record = Record ("[name:\"value\"]");} + catch (std::string& e){t.diag (e); good = false;} + t.ok (good, "Record::Record ('[name:\"value\"]')"); + t.is (record.get ("name"), "value", "name=value"); - // TODO [name:"value"] - // TODO [name:"one two"] - // TODO [one:two three:four] + // [name:"one two"] + good = true; + try {record = Record ("[name:\"one two\"]");} + catch (std::string& e){t.diag (e); good = false;} + t.ok (good, "Record::Record ('[name:\"one two\"]')"); + t.is (record.get ("name"), "one two", "name=one two"); + + // [one:two three:four] + good = true; + try {record = Record ("[one:\"two\" three:\"four\"]");} + catch (std::string& e){t.diag (e); good = false;} + t.ok (good, "Record::Record ('[one:\"two\" three:\"four\"]')"); + t.is (record.get ("one"), "two", "one=two"); + t.is (record.get ("three"), "four", "three=four"); return 0; }