diff options
-rw-r--r-- | bpkg/manifest-parser | 8 | ||||
-rw-r--r-- | bpkg/manifest-parser.cxx | 24 | ||||
-rw-r--r-- | tests/manifest-parser/driver.cxx | 133 |
3 files changed, 83 insertions, 82 deletions
diff --git a/bpkg/manifest-parser b/bpkg/manifest-parser index 2b1e4a5..070cb77 100644 --- a/bpkg/manifest-parser +++ b/bpkg/manifest-parser @@ -35,8 +35,9 @@ namespace bpkg const std::string& name () const {return name_;} - struct name_value_type + class name_value_type { + public: std::string name; std::string value; @@ -45,6 +46,9 @@ namespace bpkg std::uint64_t value_line; std::uint64_t value_column; + + bool + empty () const {return name.empty () && value.empty ();} }; // The first returned pair is special "start-of-manifest" with @@ -121,7 +125,7 @@ namespace bpkg } private: - enum {start, body, eos} s_ = start; + enum {start, body, end} s_ = start; std::string version_; // Current format version. private: diff --git a/bpkg/manifest-parser.cxx b/bpkg/manifest-parser.cxx index 374de3e..68fd073 100644 --- a/bpkg/manifest-parser.cxx +++ b/bpkg/manifest-parser.cxx @@ -11,12 +11,13 @@ using namespace std; namespace bpkg { + using parsing = manifest_parsing; using name_value = manifest_parser::name_value_type; name_value manifest_parser:: next () { - if (s_ == eos) + if (s_ == end) return name_value {"", "", l_, c_, l_, c_}; xchar c (skip_spaces ()); @@ -53,10 +54,10 @@ namespace bpkg // This is ok as long as the name is empty. // if (!r.name.empty ()) - throw manifest_parsing (name_, c.line (), c.column (), - "':' expected after name"); + throw parsing (name_, c.line (), c.column (), + "':' expected after name"); - s_ = eos; + s_ = end; // The "end" pair. // @@ -66,8 +67,7 @@ namespace bpkg } if (c != ':') - throw manifest_parsing (name_, c.line (), c.column (), - "':' expected after name"); + throw parsing (name_, c.line (), c.column (), "':' expected after name"); skip_spaces (); parse_value (r); @@ -90,8 +90,8 @@ namespace bpkg // special empty name/format version. // if (!r.name.empty ()) - throw manifest_parsing (name_, r.name_line, r.name_column, - "format version pair expected"); + throw parsing (name_, r.name_line, r.name_column, + "format version pair expected"); // The version value is only mandatory for the first manifest in // a sequence. @@ -99,8 +99,8 @@ namespace bpkg if (r.value.empty ()) { if (version_.empty ()) - throw manifest_parsing (name_, r.value_line, r.value_column, - "format version value expected"); + throw parsing (name_, r.value_line, r.value_column, + "format version value expected"); r.value = version_; } else @@ -108,8 +108,8 @@ namespace bpkg version_ = r.value; // Update with the latest. if (version_ != "1") - throw manifest_parsing (name_, r.value_line, r.value_column, - "unsupported format version " + version_); + throw parsing (name_, r.value_line, r.value_column, + "unsupported format version " + version_); } s_ = body; diff --git a/tests/manifest-parser/driver.cxx b/tests/manifest-parser/driver.cxx index b86b806..309106f 100644 --- a/tests/manifest-parser/driver.cxx +++ b/tests/manifest-parser/driver.cxx @@ -17,7 +17,7 @@ using namespace bpkg; using pairs = vector<pair<string, string>>; static bool -parse (const char* manifest, const pairs& expected); +test (const char* manifest, const pairs& expected); static bool fail (const char* manifest); @@ -27,17 +27,17 @@ main () { // Whitespaces and comments. // - assert (parse (" \t", {{"",""}})); - assert (parse (" \t\n \n\n", {{"",""}})); - assert (parse ("# one\n #two", {{"",""}})); + assert (test (" \t", {{"",""}})); + assert (test (" \t\n \n\n", {{"",""}})); + assert (test ("# one\n #two", {{"",""}})); // Test encountering eos at various points. // - assert (parse ("", {{"",""}})); - assert (parse (" ", {{"",""}})); - assert (parse ("\n", {{"",""}})); + assert (test ("", {{"",""}})); + assert (test (" ", {{"",""}})); + assert (test ("\n", {{"",""}})); assert (fail ("a")); - assert (parse (":1\na:", {{"","1"},{"a", ""},{"",""},{"",""}})); + assert (test (":1\na:", {{"","1"},{"a", ""},{"",""},{"",""}})); // Invalid manifests. // @@ -52,87 +52,84 @@ main () // Empty manifest. // - assert (parse (":1", {{"","1"},{"",""},{"",""}})); - assert (parse (" \t :1", {{"","1"},{"",""},{"",""}})); - assert (parse (" \t : 1", {{"","1"},{"",""},{"",""}})); - assert (parse (" \t : 1 ", {{"","1"},{"",""},{"",""}})); - assert (parse (":1\n", {{"","1"},{"",""},{"",""}})); - assert (parse (":1 \n", {{"","1"},{"",""},{"",""}})); + assert (test (":1", {{"","1"},{"",""},{"",""}})); + assert (test (" \t :1", {{"","1"},{"",""},{"",""}})); + assert (test (" \t : 1", {{"","1"},{"",""},{"",""}})); + assert (test (" \t : 1 ", {{"","1"},{"",""},{"",""}})); + assert (test (":1\n", {{"","1"},{"",""},{"",""}})); + assert (test (":1 \n", {{"","1"},{"",""},{"",""}})); // Single manifest. // - assert (parse (":1\na:x", {{"","1"},{"a", "x"},{"",""},{"",""}})); - assert (parse (":1\na:x\n", {{"","1"},{"a","x"},{"",""},{"",""}})); - assert (parse (":1\na:x\nb:y", - {{"","1"},{"a","x"},{"b","y"},{"",""},{"",""}})); - assert (parse (":1\na:x\n\tb : y\n #comment", - {{"","1"},{"a","x"},{"b","y"},{"",""},{"",""}})); + assert (test (":1\na:x", {{"","1"},{"a", "x"},{"",""},{"",""}})); + assert (test (":1\na:x\n", {{"","1"},{"a","x"},{"",""},{"",""}})); + assert (test (":1\na:x\nb:y", + {{"","1"},{"a","x"},{"b","y"},{"",""},{"",""}})); + assert (test (":1\na:x\n\tb : y\n #comment", + {{"","1"},{"a","x"},{"b","y"},{"",""},{"",""}})); // Multiple manifests. // - assert (parse (":1\na:x\n:\nb:y", - {{"","1"},{"a", "x"},{"",""}, - {"","1"},{"b", "y"},{"",""},{"",""}})); - assert (parse (":1\na:x\n:1\nb:y", - {{"","1"},{"a", "x"},{"",""}, - {"","1"},{"b", "y"},{"",""},{"",""}})); - assert (parse (":1\na:x\n:\nb:y\n:\nc:z\n", - {{"","1"},{"a", "x"},{"",""}, - {"","1"},{"b", "y"},{"",""}, - {"","1"},{"c", "z"},{"",""},{"",""}})); + assert (test (":1\na:x\n:\nb:y", + {{"","1"},{"a", "x"},{"",""}, + {"","1"},{"b", "y"},{"",""},{"",""}})); + assert (test (":1\na:x\n:1\nb:y", + {{"","1"},{"a", "x"},{"",""}, + {"","1"},{"b", "y"},{"",""},{"",""}})); + assert (test (":1\na:x\n:\nb:y\n:\nc:z\n", + {{"","1"},{"a", "x"},{"",""}, + {"","1"},{"b", "y"},{"",""}, + {"","1"},{"c", "z"},{"",""},{"",""}})); // Name parsing. // - assert (parse (":1\nabc:", {{"","1"},{"abc",""},{"",""},{"",""}})); - assert (parse (":1\nabc :", {{"","1"},{"abc",""},{"",""},{"",""}})); - assert (parse (":1\nabc\t:", {{"","1"},{"abc",""},{"",""},{"",""}})); + assert (test (":1\nabc:", {{"","1"},{"abc",""},{"",""},{"",""}})); + assert (test (":1\nabc :", {{"","1"},{"abc",""},{"",""},{"",""}})); + assert (test (":1\nabc\t:", {{"","1"},{"abc",""},{"",""},{"",""}})); // Simple value parsing. // - assert (parse (":1\na: \t xyz \t ", {{"","1"},{"a","xyz"},{"",""},{"",""}})); + assert (test (":1\na: \t xyz \t ", {{"","1"},{"a","xyz"},{"",""},{"",""}})); // Simple value escaping. // - assert (parse (":1\na:x\\", {{"","1"},{"a","x"},{"",""},{"",""}})); - assert (parse (":1\na:x\\\ny", {{"","1"},{"a","xy"},{"",""},{"",""}})); - assert (parse (":1\na:x\\\\\nb:", - {{"","1"},{"a","x\\"},{"b",""},{"",""},{"",""}})); - assert (parse (":1\na:x\\\\\\\nb:", - {{"","1"},{"a","x\\\\"},{"b",""},{"",""},{"",""}})); + assert (test (":1\na:x\\", {{"","1"},{"a","x"},{"",""},{"",""}})); + assert (test (":1\na:x\\\ny", {{"","1"},{"a","xy"},{"",""},{"",""}})); + assert (test (":1\na:x\\\\\nb:", + {{"","1"},{"a","x\\"},{"b",""},{"",""},{"",""}})); + assert (test (":1\na:x\\\\\\\nb:", + {{"","1"},{"a","x\\\\"},{"b",""},{"",""},{"",""}})); // Simple value literal newline. // - assert (parse (":1\na:x\\\n\\", - {{"","1"},{"a","x\n"},{"",""},{"",""}})); - assert (parse (":1\na:x\\\n\\\ny", - {{"","1"},{"a","x\ny"},{"",""},{"",""}})); - assert (parse (":1\na:x\\\n\\\ny\\\n\\\nz", - {{"","1"},{"a","x\ny\nz"},{"",""},{"",""}})); + assert (test (":1\na:x\\\n\\", {{"","1"},{"a","x\n"},{"",""},{"",""}})); + assert (test (":1\na:x\\\n\\\ny", {{"","1"},{"a","x\ny"},{"",""},{"",""}})); + assert (test (":1\na:x\\\n\\\ny\\\n\\\nz", + {{"","1"},{"a","x\ny\nz"},{"",""},{"",""}})); // Multi-line value parsing. // - assert (parse (":1\na:\\", {{"","1"},{"a", ""},{"",""},{"",""}})); - assert (parse (":1\na:\\\n", {{"","1"},{"a", ""},{"",""},{"",""}})); - assert (parse (":1\na:\\x", {{"","1"},{"a", "\\x"},{"",""},{"",""}})); - assert (parse (":1\na:\\\n\\", {{"","1"},{"a", ""},{"",""},{"",""}})); - assert (parse (":1\na:\\\n\\\n", {{"","1"},{"a", ""},{"",""},{"",""}})); - assert (parse (":1\na:\\\n\\x\n\\", - {{"","1"},{"a", "\\x"},{"",""},{"",""}})); - assert (parse (":1\na:\\\nx\ny", {{"","1"},{"a", "x\ny"},{"",""},{"",""}})); - assert (parse (":1\na:\\\n \n#\t\n\\", - {{"","1"},{"a", " \n#\t"},{"",""},{"",""}})); - assert (parse (":1\na:\\\n\n\n\\", {{"","1"},{"a", "\n"},{"",""},{"",""}})); + assert (test (":1\na:\\", {{"","1"},{"a", ""},{"",""},{"",""}})); + assert (test (":1\na:\\\n", {{"","1"},{"a", ""},{"",""},{"",""}})); + assert (test (":1\na:\\x", {{"","1"},{"a", "\\x"},{"",""},{"",""}})); + assert (test (":1\na:\\\n\\", {{"","1"},{"a", ""},{"",""},{"",""}})); + assert (test (":1\na:\\\n\\\n", {{"","1"},{"a", ""},{"",""},{"",""}})); + assert (test (":1\na:\\\n\\x\n\\", + {{"","1"},{"a", "\\x"},{"",""},{"",""}})); + assert (test (":1\na:\\\nx\ny", {{"","1"},{"a", "x\ny"},{"",""},{"",""}})); + assert (test (":1\na:\\\n \n#\t\n\\", + {{"","1"},{"a", " \n#\t"},{"",""},{"",""}})); + assert (test (":1\na:\\\n\n\n\\", {{"","1"},{"a", "\n"},{"",""},{"",""}})); // Multi-line value escaping. // - assert (parse (":1\na:\\\nx\\", - {{"","1"},{"a","x"},{"",""},{"",""}})); - assert (parse (":1\na:\\\nx\\\ny\n\\", - {{"","1"},{"a","xy"},{"",""},{"",""}})); - assert (parse (":1\na:\\\nx\\\\\n\\\nb:", - {{"","1"},{"a","x\\"},{"b",""},{"",""},{"",""}})); - assert (parse (":1\na:\\\nx\\\\\\\n\\\nb:", - {{"","1"},{"a","x\\\\"},{"b",""},{"",""},{"",""}})); + assert (test (":1\na:\\\nx\\", {{"","1"},{"a","x"},{"",""},{"",""}})); + assert (test (":1\na:\\\nx\\\ny\n\\", + {{"","1"},{"a","xy"},{"",""},{"",""}})); + assert (test (":1\na:\\\nx\\\\\n\\\nb:", + {{"","1"},{"a","x\\"},{"b",""},{"",""},{"",""}})); + assert (test (":1\na:\\\nx\\\\\\\n\\\nb:", + {{"","1"},{"a","x\\\\"},{"b",""},{"",""},{"",""}})); } static std::ostream& @@ -162,7 +159,7 @@ parse (const char* m) { auto nv (p.next ()); - if (nv.name.empty () && nv.value.empty ()) // End pair. + if (nv.empty ()) // End pair. { eos = eom; eom = true; @@ -177,7 +174,7 @@ parse (const char* m) } static bool -parse (const char* m, const pairs& e) +test (const char* m, const pairs& e) { pairs r (parse (m)); @@ -203,7 +200,7 @@ fail (const char* m) } catch (const manifest_parsing& e) { - cerr << e.what () << endl; + //cerr << e.what () << endl; } return true; |