X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/56d2f75071fc2a29ec10abe97c5a908bb35f30f4..6afafc42fcf42ce84c9e1c0a7c00d3a0376d1aef:/contrib/src/xml/xmlpars.cpp?ds=inline diff --git a/contrib/src/xml/xmlpars.cpp b/contrib/src/xml/xmlpars.cpp index 797c76d0a9..978dab5fb1 100644 --- a/contrib/src/xml/xmlpars.cpp +++ b/contrib/src/xml/xmlpars.cpp @@ -26,6 +26,44 @@ #include "wx/xml/xmlio.h" #include +#include + + +// wxWindows SAX handlers for bugs reporting: + +static void wxXmlParserError(void *ctx, const char *msg, ...) +{ + wxString text; + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; + if (ctxt->input) + text.Printf( _("XML parser error at line %d: "), ctxt->input->line ); + va_list args; + wxString tmp; + va_start(args, msg); + tmp.PrintfV( msg, args ); + va_end(args); + text += tmp; + wxLogError( text.c_str() ); +} + +static void wxXmlParserWarning(void *ctx, const char *msg, ...) +{ + wxString text; + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; + if (ctxt->input) + text.Printf( _("XML parser warning at line %d: "), ctxt->input->line ); + va_list args; + wxString tmp; + va_start(args, msg); + tmp.PrintfV( msg, args ); + va_end(args); + text += tmp; + wxLogWarning( text.c_str() ); +} + +static xmlSAXHandler gs_wxXmlSAXHandler; + + // dynamically loaded functions from libxml: typedef xmlParserCtxtPtr (*type_xmlCreatePushParserCtxt) @@ -43,6 +81,11 @@ typedef xmlNodePtr (*type_xmlNewChild)(xmlNodePtr, xmlNsPtr, const xmlChar *, co typedef xmlChar * (*type_xmlNodeListGetString)(xmlDocPtr, xmlNodePtr, int); typedef xmlNodePtr (*type_xmlDocGetRootElement)(xmlDocPtr); typedef xmlNodePtr (*type_xmlDocSetRootElement)(xmlDocPtr doc, xmlNodePtr root); +typedef void (*(*type_xmlFree))(void *); +typedef int (*type_xmlKeepBlanksDefault)(int); +typedef void (*type_xmlInitParser)(void); +typedef void (*type_xmlCleanupParser)(void); +typedef xmlSAXHandler *type_xmlDefaultSAXHandler; static struct { @@ -62,6 +105,11 @@ static struct type_xmlNodeListGetString xmlNodeListGetString; type_xmlDocGetRootElement xmlDocGetRootElement; type_xmlDocSetRootElement xmlDocSetRootElement; + type_xmlFree xmlFree; + type_xmlKeepBlanksDefault xmlKeepBlanksDefault; + type_xmlInitParser xmlInitParser; + type_xmlCleanupParser xmlCleanupParser; + type_xmlDefaultSAXHandler xmlDefaultSAXHandler; } gs_libxmlDLL; static bool gs_libxmlLoaded = FALSE; @@ -73,7 +121,7 @@ static void ReleaseLibxml() { if (gs_libxmlLoaded) { - wxLogDebug("Releasing libxml.so.2"); + gs_libxmlDLL.xmlCleanupParser(); wxDllLoader::UnloadLibrary(gs_libxmlDLL.Handle); } gs_libxmlLoaded = FALSE; @@ -87,18 +135,37 @@ static bool LoadLibxml() if (gs_libxmlLoadFailed) return FALSE; gs_libxmlLoadFailed = TRUE; - wxLogDebug("Loading libxml.so.2..."); + { + wxLogNull lg; #ifdef __UNIX__ gs_libxmlDLL.Handle = + wxDllLoader::LoadLibrary(_T("wxlibxml.so.2"), &gs_libxmlLoaded); + if (!gs_libxmlLoaded) gs_libxmlDLL.Handle = wxDllLoader::LoadLibrary(_T("libxml.so.2"), &gs_libxmlLoaded); #endif +#ifdef __WXMSW__ + gs_libxmlDLL.Handle = + wxDllLoader::LoadLibrary(_T("wxlibxml2.dll"), &gs_libxmlLoaded); + if (!gs_libxmlLoaded) gs_libxmlDLL.Handle = + wxDllLoader::LoadLibrary(_T("libxml2.dll"), &gs_libxmlLoaded); +#endif + } - if (!gs_libxmlLoaded) return FALSE; + if (!gs_libxmlLoaded) + { + wxLogError(_("Failed to load libxml shared library.")); + return FALSE; + } #define LOAD_SYMBOL(sym) \ gs_libxmlDLL.sym = \ (type_##sym)wxDllLoader::GetSymbol(gs_libxmlDLL.Handle, _T(#sym)); \ - if (!gs_libxmlDLL.sym) { ReleaseLibxml(); return FALSE; } + if (!gs_libxmlDLL.sym) \ + { \ + ReleaseLibxml(); \ + wxLogError(_("Failed to load libxml shared library.")); \ + return FALSE; \ + } LOAD_SYMBOL(xmlCreatePushParserCtxt) LOAD_SYMBOL(xmlNewText) @@ -114,12 +181,23 @@ static bool LoadLibxml() LOAD_SYMBOL(xmlNodeListGetString) LOAD_SYMBOL(xmlDocGetRootElement) LOAD_SYMBOL(xmlDocSetRootElement) + LOAD_SYMBOL(xmlFree) + LOAD_SYMBOL(xmlKeepBlanksDefault) + LOAD_SYMBOL(xmlInitParser) + LOAD_SYMBOL(xmlCleanupParser) + LOAD_SYMBOL(xmlDefaultSAXHandler) #undef LOAD_SYMBOL gs_libxmlLoadFailed = FALSE; + + gs_libxmlDLL.xmlInitParser(); + memcpy(&gs_wxXmlSAXHandler, gs_libxmlDLL.xmlDefaultSAXHandler, + sizeof(xmlSAXHandler)); + gs_wxXmlSAXHandler.error = wxXmlParserError; + gs_wxXmlSAXHandler.fatalError = wxXmlParserError; + gs_wxXmlSAXHandler.warning = wxXmlParserWarning; - wxLogDebug("...succeed"); return TRUE; } @@ -153,7 +231,7 @@ static wxXmlProperty *CreateWXProperty(xmlDocPtr doc, xmlAttrPtr attr) gs_libxmlDLL.xmlNodeListGetString(doc, attr->children, 1); wxXmlProperty *prop = new wxXmlProperty(attr->name, val, CreateWXProperty(doc, attr->next)); - free(val); + (*gs_libxmlDLL.xmlFree)(val); return prop; } @@ -187,8 +265,9 @@ bool wxXmlIOHandlerLibxml::Load(wxInputStream& stream, wxXmlDocument& doc) if (res > 0) { bool okay = TRUE; - ctxt = gs_libxmlDLL.xmlCreatePushParserCtxt(NULL, NULL, - buffer, res, ""/*docname*/); + gs_libxmlDLL.xmlKeepBlanksDefault(0); + ctxt = gs_libxmlDLL.xmlCreatePushParserCtxt(&gs_wxXmlSAXHandler, + NULL, buffer, res, ""/*docname*/); while ((res = stream.Read(buffer, 1024).LastRead()) > 0) if (gs_libxmlDLL.xmlParseChunk(ctxt, buffer, res, 0) != 0) okay = FALSE; @@ -249,6 +328,7 @@ bool wxXmlIOHandlerLibxml::Save(wxOutputStream& stream, const wxXmlDocument& doc wxASSERT_MSG(doc.GetRoot() != NULL, _("Trying to save empty document!")); + gs_libxmlDLL.xmlKeepBlanksDefault(0); dc = gs_libxmlDLL.xmlNewDoc((xmlChar*)doc.GetVersion().mb_str()); gs_libxmlDLL.xmlDocSetRootElement(dc, @@ -262,7 +342,7 @@ bool wxXmlIOHandlerLibxml::Save(wxOutputStream& stream, const wxXmlDocument& doc gs_libxmlDLL.xmlDocDumpMemory(dc, &buffer, &size); gs_libxmlDLL.xmlFreeDoc(dc); stream.Write(buffer, size); - free(buffer); + (*gs_libxmlDLL.xmlFree)(buffer); return stream.LastWrite() == (unsigned)size; }