diff --git a/src/basic_xml_grammar.ipp b/src/basic_xml_grammar.ipp index 231c5ccc..312cd526 100644 --- a/src/basic_xml_grammar.ipp +++ b/src/basic_xml_grammar.ipp @@ -21,19 +21,10 @@ # pragma warning(disable : 4511 4512) #endif -// #include -// #include -// #include - -#include -#include -#include -#include -#include - -#include -#include -#include +// spirit stuff +#include +#include +#include #ifdef BOOST_MSVC #pragma warning(pop) @@ -59,9 +50,132 @@ namespace archive { /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8 // template code for basic_xml_grammar of both wchar_t and char types +namespace xml { // anonymous + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable : 4511 4512) +#endif + +template +struct assign_impl { + T & t; + void operator()(const T t_) const { + t = t_; + } + assign_impl(T & t_) + : t(t_) + {} +}; + +template<> +struct assign_impl { + std::string & t; + void operator()( + std::string::const_iterator b, + std::string::const_iterator e + ) const { + t.resize(0); + while(b != e){ + t += * b; + ++b; + } + } + assign_impl & operator=( + assign_impl & rhs + ); + assign_impl(std::string & t_) + : t(t_) + {} +}; + +#ifndef BOOST_NO_STD_WSTRING +template<> +struct assign_impl { + std::wstring & t; + void operator()( + std::wstring::const_iterator b, + std::wstring::const_iterator e + ) const { + t.resize(0); + while(b != e){ + t += * b; + ++b; + } + } + assign_impl(std::wstring & t_) + : t(t_) + {} +}; +#endif + +template +assign_impl assign_object(T &t){ + return assign_impl(t); +} + +struct assign_level { + tracking_type & tracking_level; + void operator()(const unsigned int tracking_level_) const { + tracking_level = (0 == tracking_level_) ? false : true; + } + assign_level(tracking_type & tracking_level_) + : tracking_level(tracking_level_) + {} +}; + +template +struct append_string { + String & contents; + void operator()(Iterator start, Iterator end) const { + #if 0 + typedef boost::archive::iterators::xml_unescape translator; + contents.append( + translator(BOOST_MAKE_PFTO_WRAPPER(start)), + translator(BOOST_MAKE_PFTO_WRAPPER(end)) + ); + #endif + contents.append(start, end); + } + append_string(String & contents_) + : contents(contents_) + {} +}; + +template +struct append_char { + String & contents; + void operator()(const unsigned int char_value) const { + const BOOST_DEDUCED_TYPENAME String::value_type z = char_value; + contents += z; + } + append_char(String & contents_) + : contents(contents_) + {} +}; + +template +struct append_lit { + String & contents; + template + void operator()(const X & /*x*/, const Y & /*y*/) const { + const BOOST_DEDUCED_TYPENAME String::value_type z = c; + contents += z; + } + append_lit(String & contents_) + : contents(contents_) + {} +}; + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +} // namespace anonymous + template bool basic_xml_grammar::my_parse( - IStream & is, + BOOST_DEDUCED_TYPENAME basic_xml_grammar::IStream & is, const rule_t & rule_, CharType delimiter ) const { @@ -92,17 +206,21 @@ bool basic_xml_grammar::my_parse( // is terminated. This will permit the archive to be used for debug // and transaction data logging in the standard way. - return qi::parse(arg.begin(), arg.end(), rule_); + parse_info::iterator> + result = boost::spirit::parse(arg.begin(), arg.end(), rule_); + return result.hit; } template -bool basic_xml_grammar::parse_start_tag(IStream & is){ +bool basic_xml_grammar::parse_start_tag( + BOOST_DEDUCED_TYPENAME basic_xml_grammar::IStream & is +){ rv.class_name.resize(0); return my_parse(is, STag); } template -bool basic_xml_grammar::parse_end_tag(IStream & is) { +bool basic_xml_grammar::parse_end_tag(IStream & is) const { return my_parse(is, ETag); } @@ -112,7 +230,7 @@ bool basic_xml_grammar::parse_string(IStream & is, StringType & s){ bool result = my_parse(is, content, '<'); // note: unget caused a problem with dinkumware. replace with // is.unget(); - // putback another delimiter instead + // putback another dilimiter instead is.putback('<'); if(result) s = rv.contents; @@ -123,164 +241,202 @@ template basic_xml_grammar::basic_xml_grammar(){ init_chset(); - /* [1] S ::= Sch+ */ - S = +(Sch); - - /* [2] Eq ::= !S '=' !S */ - Eq = !S >> '=' >> !S; - - /* [3] AttributeList ::= (S Attribute)* */ - AttributeList = *(S >> Attribute); - - /* [4] STag ::= S? '<' Name AttributeLIst !S '>' */ - STag = -S >> '<' >> Name >> AttributeList >> !S >> '>'; - - /* [5] ETag ::= S? "' */ - ETag = -S >> "> Name >> !S >> '>'; - - /* [6] CharData ::= (AnyChar - ("&" | "<"))+ */ - CharData = +(AnyChar - (qi::lit('&') | '<')) - [phoenix::ref(rv.contents) += qi::_1] + S = + +(Sch) ; - /* [7] CharRef ::= ("&#" Digit* ';') | ("&#x" HexDigit* ';') */ - CharRef - = (qi::lit("&#") >> *Digit[phoenix::ref(rv.contents) += qi::_1] >> ';') - | ("&#x" >> *HexDigit[phoenix::ref(rv.contents) += qi::_1] >> ';') + // refactoring to workaround template depth on darwin + NameHead = (Letter | '_' | ':'); + NameTail = *NameChar ; + Name = + NameHead >> NameTail ; - /* [8] AmpRef ::= "&" * - * [9] LTRef ::= "<" * - * [a] GTRef ::= ">" * - * [b] AposRef ::= "'" * - * [c] QuoteRef ::= """ */ - AmpRef = qi::lit("&") [phoenix::ref(rv.contents) += '&']; - LTRef = qi::lit("<") [phoenix::ref(rv.contents) += '<']; - GTRef = qi::lit(">") [phoenix::ref(rv.contents) += '>']; - AposRef = qi::lit("'")[phoenix::ref(rv.contents) += '\'']; - QuoteRef = qi::lit(""")[phoenix::ref(rv.contents) += '"']; + Eq = + !S >> '=' >> !S + ; + + AttributeList = + *(S >> Attribute) + ; - /* [d] AmpName ::= "&" * - * [e] LTName ::= "<" * - * [f] GTName ::= ">" */ - AmpName = qi::lit("&")[phoenix::ref(rv.class_name) += '&']; - LTName = qi::lit("<") [phoenix::ref(rv.class_name) += '<']; - GTName = qi::lit(">") [phoenix::ref(rv.class_name) += '>']; - - /* [10] Reference ::= AmpRef LTRef GTRef AposRef QuoteRef CharRef */ - Reference - = AmpRef - | LTRef - | GTRef - | AposRef - | QuoteRef - | CharRef + STag = + !S + >> '<' + >> Name [xml::assign_object(rv.object_name)] + >> AttributeList + >> !S + >> '>' ; - /* [11] content ::= '<' | (Reference | CharData)+ '<' */ - content = qi::lit('<') | +(Reference | CharData) >> qi::lit('<'); - - ClassIDAttribute - = qi::lit(BOOST_ARCHIVE_XML_CLASS_ID()) - >> *NameChar - >> Eq - >> '"' - >> qi::short_[phoenix::ref(rv.class_id) = qi::_1] - >> '"' + ETag = + !S + >> "> Name [xml::assign_object(rv.object_name)] + >> !S + >> '>' ; - ObjectIDAttribute - = ( qi::lit(BOOST_ARCHIVE_XML_OBJECT_ID()) - | qi::lit(BOOST_ARCHIVE_XML_OBJECT_REFERENCE()) + // refactoring to workaround template depth on darwin + CharDataChars = +(anychar_p - chset_p(L"&<")); + CharData = + CharDataChars [ + xml::append_string< + StringType, + BOOST_DEDUCED_TYPENAME std::basic_string::const_iterator + >(rv.contents) + ] + ; + + // slight factoring works around ICE in msvc 6.0 + CharRef1 = + str_p(L"&#") >> uint_p [xml::append_char(rv.contents)] >> L';' + ; + CharRef2 = + str_p(L"&#x") >> hex_p [xml::append_char(rv.contents)] >> L';' + ; + CharRef = CharRef1 | CharRef2 ; + + AmpRef = str_p(L"&")[xml::append_lit(rv.contents)]; + LTRef = str_p(L"<")[xml::append_lit(rv.contents)]; + GTRef = str_p(L">")[xml::append_lit'>(rv.contents)]; + AposRef = str_p(L"'")[xml::append_lit(rv.contents)]; + QuoteRef = str_p(L""")[xml::append_lit(rv.contents)]; + + Reference = + AmpRef + | LTRef + | GTRef + | AposRef + | QuoteRef + | CharRef + ; + + content = + L"<" // should be end_p + | +(Reference | CharData) >> L"<" + ; + + ClassIDAttribute = + str_p(BOOST_ARCHIVE_XML_CLASS_ID()) >> NameTail + >> Eq + >> L'"' + >> int_p [xml::assign_object(rv.class_id)] + >> L'"' + ; + + ObjectIDAttribute = ( + str_p(BOOST_ARCHIVE_XML_OBJECT_ID()) + | + str_p(BOOST_ARCHIVE_XML_OBJECT_REFERENCE()) ) - >> *NameChar - >> Eq - >> '"' - >> qi::lit('_') - >> qi::uint_[phoenix::ref(rv.object_id) = qi::_1] - >> '"' + >> NameTail + >> Eq + >> L'"' + >> L'_' + >> uint_p [xml::assign_object(rv.object_id)] + >> L'"' ; - ClassNameChar - = AmpName - | LTName - | GTName - | (qi::char_ - '"')[phoenix::ref(rv.class_name) += qi::_1] + AmpName = str_p(L"&")[xml::append_lit(rv.class_name)]; + LTName = str_p(L"<")[xml::append_lit(rv.class_name)]; + GTName = str_p(L">")[xml::append_lit'>(rv.class_name)]; + ClassNameChar = + AmpName + | LTName + | GTName + | (anychar_p - chset_p(L"\"")) [xml::append_char(rv.class_name)] ; - ClassName = *ClassNameChar; + ClassName = + * ClassNameChar + ; - ClassNameAttribute - = qi::lit(BOOST_ARCHIVE_XML_CLASS_NAME()) - >> Eq - >> '"' - >> ClassName - >> '"' + ClassNameAttribute = + str_p(BOOST_ARCHIVE_XML_CLASS_NAME()) + >> Eq + >> L'"' + >> ClassName + >> L'"' ; - TrackingAttribute - = qi::lit(BOOST_ARCHIVE_XML_TRACKING()) - >> Eq - >> '"' - >> qi::uint_[phoenix::ref(rv.tracking_level) = qi::_1] - >> '"' + TrackingAttribute = + str_p(BOOST_ARCHIVE_XML_TRACKING()) + >> Eq + >> L'"' + >> uint_p [xml::assign_level(rv.tracking_level)] + >> L'"' ; - VersionAttribute - = qi::lit(BOOST_ARCHIVE_XML_VERSION()) - >> Eq - >> '"' - >> qi::uint_[phoenix::ref(rv.version) = qi::_1] - >> '"' + VersionAttribute = + str_p(BOOST_ARCHIVE_XML_VERSION()) + >> Eq + >> L'"' + >> uint_p [xml::assign_object(rv.version)] + >> L'"' ; - UnusedAttribute - = Name - >> Eq - >> '"' - >> !CharData - >> '"' + UnusedAttribute = + Name + >> Eq + >> L'"' + >> !CharData + >> L'"' ; - Attribute - = ClassIDAttribute - | ObjectIDAttribute - | ClassNameAttribute - | TrackingAttribute - | VersionAttribute - | UnusedAttribute + Attribute = + ClassIDAttribute + | ObjectIDAttribute + | ClassNameAttribute + | TrackingAttribute + | VersionAttribute + | UnusedAttribute ; - XMLDecl - = -S - >> "> S - >> "version" - >> Eq - >> "\"1.0\"" - >> XMLDeclChars - >> !S - >> "?>" + XMLDeclChars = *(anychar_p - chset_p(L"?>")); + XMLDecl = + !S + >> str_p(L"> S + >> str_p(L"version") + >> Eq + >> str_p(L"\"1.0\"") + >> XMLDeclChars + >> !S + >> str_p(L"?>") ; - DocTypeDecl = -S >> "> DocTypeDeclChars >> '>'; + DocTypeDeclChars = *(anychar_p - chset_p(L">")); + DocTypeDecl = + !S + >> str_p(L"> DocTypeDeclChars + >> L'>' + ; - SignatureAttribute = qi::lit("signature") >> Eq >> '"' >> Name >> '"'; + SignatureAttribute = + str_p(L"signature") + >> Eq + >> L'"' + >> Name [xml::assign_object(rv.class_name)] + >> L'"' + ; - SerializationWrapper - = -S - >> "> S - >> SignatureAttribute - >> S - >> VersionAttribute - >> !S - >> '>' + SerializationWrapper = + !S + >> str_p(L"> S + >> SignatureAttribute + >> S + >> VersionAttribute + >> !S + >> L'>' ; } template void basic_xml_grammar::init(IStream & is){ + init_chset(); if(! my_parse(is, XMLDecl)) boost::serialization::throw_exception( xml_archive_exception(xml_archive_exception::xml_archive_parsing_error) diff --git a/src/xml_grammar.cpp b/src/xml_grammar.cpp index d8e4e158..4f2c37c6 100644 --- a/src/xml_grammar.cpp +++ b/src/xml_grammar.cpp @@ -15,14 +15,6 @@ #define BOOST_ARCHIVE_SOURCE #include -#include -#include -#include - -#include -#include -#include - using namespace boost::spirit; #include @@ -57,26 +49,12 @@ typedef basic_xml_grammar xml_grammar; template<> void xml_grammar::init_chset(){ - Char = standard::char_("\x9\xA\xD\x20-\x7f\x80\x81-\xFF"); - Letter = standard::char_("\x41-\x5A\x61-\x7A\xC0-\xD6\xD8-\xF6\xF8-\xFF"); - Digit = standard::digit; - HexDigit = standard::xdigit; - Extender = standard::char_('\xB7'); - Sch = standard::char_("\x20\x9\xD\xA"); - NameChar = Letter | Digit | standard::char_("._:-") | Extender ; - AnyChar = standard::char_; - - DocTypeDeclChars = *(standard::char_ - qi::lit('>')); - XMLDeclChars = *(standard::char_ - qi::lit("?>")); - - Name = - ( - (Letter | standard::char_('_') | standard::char_(':'))[ - phoenix::ref(rv.object_name) = qi::_1 - ] >> - *NameChar[phoenix::ref(rv.object_name) += qi::_1] - ) - ; + Char = chset_t("\x9\xA\xD\x20-\x7f\x80\x81-\xFF"); + Letter = chset_t("\x41-\x5A\x61-\x7A\xC0-\xD6\xD8-\xF6\xF8-\xFF"); + Digit = chset_t("0-9"); + Extender = chset_t('\xB7'); + Sch = chset_t("\x20\x9\xD\xA"); + NameChar = Letter | Digit | chset_p("._:-") | Extender ; } } // namespace archive diff --git a/src/xml_wgrammar.cpp b/src/xml_wgrammar.cpp index eb1b0781..cbd3c7b1 100644 --- a/src/xml_wgrammar.cpp +++ b/src/xml_wgrammar.cpp @@ -17,14 +17,6 @@ #define BOOST_WARCHIVE_SOURCE #include -#include -#include -#include - -#include -#include -#include - using namespace boost::spirit; // fixup for RogueWave @@ -57,7 +49,7 @@ typedef basic_xml_grammar xml_wgrammar; template<> void xml_wgrammar::init_chset(){ - Char = standard_wide::char_( + Char = chset_t( #if defined(__GNUC__) && defined(linux) L"\x9\xA\xD\x20-\xD7FF\xE000-\xFFFD\x10000-\x10FFFF" #else @@ -65,9 +57,9 @@ void xml_wgrammar::init_chset(){ #endif ); - Sch = standard_wide::char_(L"\x20\x9\xD\xA"); + Sch = chset_t(L"\x20\x9\xD\xA"); - BaseChar = standard_wide::char_( + BaseChar = chset_t( L"\x41-\x5A\x61-\x7A\xC0-\xD6\xD8-\xF6\xF8-\xFF\x100-\x131\x134-\x13E" L"\x141-\x148\x14A-\x17E\x180-\x1C3\x1CD-\x1F0\x1F4-\x1F5\x1FA-\x217" L"\x250-\x2A8\x2BB-\x2C1\x386\x388-\x38A\x38C\x38E-\x3A1\x3A3-\x3CE" @@ -102,11 +94,11 @@ void xml_wgrammar::init_chset(){ L"\x3041-\x3094\x30A1-\x30FA\x3105-\x312C\xAC00-\xD7A3" ); - Ideographic = standard_wide::char_(L"\x4E00-\x9FA5\x3007\x3021-\x3029"); + Ideographic = chset_t(L"\x4E00-\x9FA5\x3007\x3021-\x3029"); Letter = BaseChar | Ideographic; - CombiningChar = standard_wide::char_( + CombiningChar = chset_t( L"\x0300-\x0345\x0360-\x0361\x0483-\x0486\x0591-\x05A1\x05A3-\x05B9" L"\x05BB-\x05BD\x05BF\x05C1-\x05C2\x05C4\x064B-\x0652\x0670" L"\x06D6-\x06DC\x06DD-\x06DF\x06E0-\x06E4\x06E7-\x06E8\x06EA-\x06ED" @@ -126,35 +118,27 @@ void xml_wgrammar::init_chset(){ L"\x20D0-\x20DC\x20E1\x302A-\x302F\x3099\x309A" ); - Digit = standard_wide::digit; - HexDigit = standard_wide::xdigit; - - Extender = standard_wide::char_( + Digit = chset_t( + L"\x0030-\x0039\x0660-\x0669\x06F0-\x06F9\x0966-\x096F\x09E6-\x09EF" + L"\x0A66-\x0A6F\x0AE6-\x0AEF\x0B66-\x0B6F\x0BE7-\x0BEF\x0C66-\x0C6F" + L"\x0CE6-\x0CEF\x0D66-\x0D6F\x0E50-\x0E59\x0ED0-\x0ED9\x0F20-\x0F29" + ); + + Extender = chset_t( L"\x00B7\x02D0\x02D1\x0387\x0640\x0E46\x0EC6\x3005\x3031-\x3035" L"\x309D-\x309E\x30FC-\x30FE" ); - NameChar - = Letter + NameChar = + Letter | Digit - | standard_wide::char_(L"[._:-") + | L'.' + | L'-' + | L'_' + | L':' | CombiningChar | Extender ; - - AnyChar = standard_wide::char_; - - DocTypeDeclChars = *(standard_wide::char_ - qi::lit(L'>')); - XMLDeclChars = *(standard_wide::char_ - qi::lit(L"?>")); - - Name = - ( - (Letter | standard_wide::char_(L'_') | standard_wide::char_(L':'))[ - phoenix::ref(rv.object_name) = qi::_1 - ] >> - *NameChar[phoenix::ref(rv.object_name) += qi::_1] - ) - ; } } // namespace archive } // namespace boost