diff --git a/include/wx/xml/xml.h b/include/wx/xml/xml.h index 9ed8e617f9..67fe18bf7c 100644 --- a/include/wx/xml/xml.h +++ b/include/wx/xml/xml.h @@ -20,6 +20,7 @@ #include "wx/list.h" #include "wx/textbuf.h" #include "wx/versioninfo.h" +#include "wx/filefn.h" #include @@ -222,6 +223,15 @@ enum wxXmlDocumentLoadFlag wxXMLDOC_KEEP_WHITESPACE_NODES = 1 }; +// Create an instance of this and pass it to wxXmlDocument::Load() +// to get detailed error information in case of failure. +struct wxXmlParseError +{ + wxString message; + int line = 0; + int column = 0; + wxFileOffset offset = 0; +}; // This class holds XML data/document as parsed by XML parser. @@ -238,8 +248,8 @@ public: // Parses .xml file and loads data. Returns TRUE on success, FALSE // otherwise. - bool Load(const wxString& filename, int flags = wxXMLDOC_NONE); - bool Load(wxInputStream& stream, int flags = wxXMLDOC_NONE); + bool Load(const wxString& filename, int flags = wxXMLDOC_NONE, wxXmlParseError* err = nullptr); + bool Load(wxInputStream& stream, int flags = wxXMLDOC_NONE, wxXmlParseError* err = nullptr); // Saves document as .xml file. virtual bool Save(const wxString& filename, int indentstep = 2) const; diff --git a/interface/wx/xml/xml.h b/interface/wx/xml/xml.h index 88c66712a4..6477391cc9 100644 --- a/interface/wx/xml/xml.h +++ b/interface/wx/xml/xml.h @@ -557,6 +557,20 @@ enum wxXmlDocumentLoadFlag }; +/** + Pass this structure to wxXmlDocument::Load() to get more information + if an error occurred during XML parsing. + + @since 3.3.0 + */ +struct wxXmlParseError +{ + wxString message; ///< Error description + int line; ///< Line number where error occurred + int column; ///< Column number where error occurred + int byte_offset; ///< Byte offset where error occurred +}; + /** @class wxXmlDocument @@ -827,15 +841,21 @@ public: less memory however makes impossible to recreate exactly the loaded text with a Save() call later. Read the initial description of this class for more info. + Create an wxXmlParseError object and pass it to this function to get more + information if an error occurred during XML parsing (this parameter is + only available since wxWidgets 3.3.0). + Returns true on success, false otherwise. */ - bool Load(const wxString& filename, int flags = wxXMLDOC_NONE); + bool Load(const wxString& filename, int flags = wxXMLDOC_NONE, + wxXmlParseError* err = nullptr); /** Like Load(const wxString&, int) but takes the data from given input stream. */ - bool Load(wxInputStream& stream, int flags = wxXMLDOC_NONE); + bool Load(wxInputStream& stream, int flags = wxXMLDOC_NONE, + wxXmlParseError* err = nullptr); /** Saves XML tree creating a file named with given string. diff --git a/src/xml/xml.cpp b/src/xml/xml.cpp index 9076bf1f3c..bd1c64526b 100644 --- a/src/xml/xml.cpp +++ b/src/xml/xml.cpp @@ -482,12 +482,13 @@ void wxXmlDocument::DoCopy(const wxXmlDocument& doc) m_docNode.reset(); } -bool wxXmlDocument::Load(const wxString& filename, int flags) +bool wxXmlDocument::Load(const wxString& filename, int flags, + wxXmlParseError* err) { wxFileInputStream stream(filename); if (!stream.IsOk()) return false; - return Load(stream, flags); + return Load(stream, flags, err); } bool wxXmlDocument::Save(const wxString& filename, int indentstep) const @@ -820,7 +821,8 @@ static int UnknownEncodingHnd(void * WXUNUSED(encodingHandlerData), } // extern "C" -bool wxXmlDocument::Load(wxInputStream& stream, int flags) +bool wxXmlDocument::Load(wxInputStream& stream, int flags, + wxXmlParseError* err) { const size_t BUFSIZE = 16384; char buf[BUFSIZE]; @@ -852,11 +854,21 @@ bool wxXmlDocument::Load(wxInputStream& stream, int flags) done = (len < BUFSIZE); if (!XML_Parse(parser, buf, len, done)) { - wxString error(XML_ErrorString(XML_GetErrorCode(parser)), - *wxConvCurrent); - wxLogError(_("XML parsing error: '%s' at line %d"), - error.c_str(), - (int)XML_GetCurrentLineNumber(parser)); + if (err) + { + err->message = XML_ErrorString(XML_GetErrorCode(parser)); + err->line = (int)XML_GetCurrentLineNumber(parser); + err->column = (int)XML_GetCurrentColumnNumber(parser); + err->offset = XML_GetCurrentByteIndex(parser); + } + else + { + wxString error(XML_ErrorString(XML_GetErrorCode(parser)), + *wxConvCurrent); + wxLogError(_("XML parsing error: '%s' at line %d"), + error.c_str(), + (int)XML_GetCurrentLineNumber(parser)); + } ok = false; break; }