From f14cb010a336d3b6d8824fa33b3c0e3068ab43f6 Mon Sep 17 00:00:00 2001 From: jez Date: Fri, 1 Aug 2008 13:02:41 +0100 Subject: [PATCH] added is_qname function, and tests --- .bzrignore | 1 + include/XML/strings.hpp | 51 ++++++++++--- tests/Utils/test_xml_strings.hpp | 118 ++++++++++++++++++++++++++++--- 3 files changed, 150 insertions(+), 20 deletions(-) diff --git a/.bzrignore b/.bzrignore index a05a9f4d..98a48630 100644 --- a/.bzrignore +++ b/.bzrignore @@ -30,3 +30,4 @@ vs9\*.user lib arabica-2008-july arabica-2008-july.* +vs9/mangle.sln diff --git a/include/XML/strings.hpp b/include/XML/strings.hpp index d964d0a4..58136bba 100755 --- a/include/XML/strings.hpp +++ b/include/XML/strings.hpp @@ -4,35 +4,66 @@ #include #include + // QName + //[7] QName ::= PrefixedName | UnprefixedName + //[8] PrefixedName ::= Prefix ':' LocalPart + //[9] UnprefixedName ::= LocalPart + //[10] Prefix ::= NCName + //[11] LocalPart ::= NCName + + // NCName + // [4] NCName ::= NCNameStartChar NCNameChar* //An XML Name, minus the ":" + // [5] NCNameChar ::= NameChar - ':' + // [6] NCNameStartChar ::= Letter | '_' } // namespace XML + namespace Arabica { namespace XML { + bool is_ncname(const std::string::const_iterator& b, + const std::string::const_iterator& e); - bool is_ncname(const std::string& str) + inline bool is_ncname(const std::string& str) + { + return is_ncname(str.begin(), str.end()); + } // is_ncname + + inline bool is_ncname(const std::string::const_iterator& b, + const std::string::const_iterator& e) { using namespace Arabica::text; - std::string::const_iterator s = str.begin(); + if(b == e) + return false; // zero length + + std::string::const_iterator s = b; if(!(is_letter(*s) || (*s == Unicode::LOW_LINE))) return false; ++s; - for(std::string::const_iterator se = str.end(); s != se; ++s) + for( ; s != e; ++s) { wchar_t c = static_cast(*s); - if(!(is_letter(c) || - is_digit(c) || - (c == Unicode::FULL_STOP) || - (c == Unicode::HYPHEN_MINUS) || - (c == Unicode::LOW_LINE) || - is_combining_char(c) || - is_extender(c))) + if(!is_ncname_char(c)) return false; } return true; } // is_ncname + inline bool is_qname(const std::string& str) + { + using namespace Arabica::text; + + size_t colon_index = str.find(Unicode::COLON); + + if(colon_index == std::string::npos) + return is_ncname(str); + + std::string::const_iterator b = str.begin(); + return is_ncname(b, b+colon_index) && + is_ncname(b+(colon_index+1), str.end()); + } // is_qname + } // namespace XML } // namespace Arabica diff --git a/tests/Utils/test_xml_strings.hpp b/tests/Utils/test_xml_strings.hpp index c5de8ac0..a8fcaa03 100755 --- a/tests/Utils/test_xml_strings.hpp +++ b/tests/Utils/test_xml_strings.hpp @@ -5,13 +5,13 @@ using namespace Arabica::XML; -class XMLStringTest : public TestCase +class NCNameTest : public TestCase { public: - XMLStringTest(std::string name) : + NCNameTest(std::string name) : TestCase(name) { - } // XMLStringTest + } // NCNameTest void test1() { @@ -42,19 +42,117 @@ public: { assertFalse(is_ncname("xsl:foo")); } // test6 +}; // class NCNameTest -}; // class XMLStringTest +TestSuite* NCNameTest_suite() +{ + TestSuite* suiteOfTests = new TestSuite(); + + suiteOfTests->addTest(new TestCaller("test1", &NCNameTest::test1)); + suiteOfTests->addTest(new TestCaller("test2", &NCNameTest::test2)); + suiteOfTests->addTest(new TestCaller("test3", &NCNameTest::test3)); + suiteOfTests->addTest(new TestCaller("test4", &NCNameTest::test4)); + suiteOfTests->addTest(new TestCaller("test5", &NCNameTest::test5)); + suiteOfTests->addTest(new TestCaller("test6", &NCNameTest::test6)); + + return suiteOfTests; +} // NCNameTest_suite + +class QNameTest : public TestCase +{ +public: + QNameTest(std::string name) : + TestCase(name) + { + } // QNameTest + + void test1() + { + assertTrue(is_qname("woo")); + } // test1 + + void test2() + { + assertTrue(is_qname("WOO")); + } // test2 + + void test3() + { + assertFalse(is_qname("???")); + } // test3 + + void test4() + { + assertTrue(is_qname("a_b")); + } // test4 + + void test5() + { + assertTrue(is_qname("a:b")); + } // test5 + + void test6() + { + assertTrue(is_qname("xsl:foo")); + } // test6 + + void test7() + { + assertFalse(is_qname(":foo")); + } // test7 + + void test8() + { + assertFalse(is_qname("foo:")); + } // test7 + + void test9() + { + assertFalse(is_qname("xsl::foo")); + } // test7 + + void test10() + { + assertFalse(is_qname("xsl:foo:")); + } // test7 + + void test11() + { + assertFalse(is_qname("$rr")); + } // test11 + + void test12() + { + assertFalse(is_qname("root/child")); + } // test12 +}; // class QNameTest + +TestSuite* QNameTest_suite() +{ + TestSuite* suiteOfTests = new TestSuite(); + + suiteOfTests->addTest(new TestCaller("test1", &QNameTest::test1)); + suiteOfTests->addTest(new TestCaller("test2", &QNameTest::test2)); + suiteOfTests->addTest(new TestCaller("test3", &QNameTest::test3)); + suiteOfTests->addTest(new TestCaller("test4", &QNameTest::test4)); + suiteOfTests->addTest(new TestCaller("test5", &QNameTest::test5)); + suiteOfTests->addTest(new TestCaller("test6", &QNameTest::test6)); + suiteOfTests->addTest(new TestCaller("test7", &QNameTest::test7)); + suiteOfTests->addTest(new TestCaller("test8", &QNameTest::test8)); + suiteOfTests->addTest(new TestCaller("test9", &QNameTest::test9)); + suiteOfTests->addTest(new TestCaller("test10", &QNameTest::test10)); + suiteOfTests->addTest(new TestCaller("test11", &QNameTest::test11)); + suiteOfTests->addTest(new TestCaller("test12", &QNameTest::test12)); + + return suiteOfTests; +} // QNameTest_suite TestSuite* XMLStringTest_suite() { TestSuite* suiteOfTests = new TestSuite(); - suiteOfTests->addTest(new TestCaller("test1", &XMLStringTest::test1)); - suiteOfTests->addTest(new TestCaller("test2", &XMLStringTest::test2)); - suiteOfTests->addTest(new TestCaller("test3", &XMLStringTest::test3)); - suiteOfTests->addTest(new TestCaller("test4", &XMLStringTest::test4)); - suiteOfTests->addTest(new TestCaller("test5", &XMLStringTest::test5)); - suiteOfTests->addTest(new TestCaller("test6", &XMLStringTest::test6)); + suiteOfTests->addTest(NCNameTest_suite()); + suiteOfTests->addTest(QNameTest_suite()); return suiteOfTests; } // XMLStringTest_suite