From 5d7d0a922d105336650fb35fd037cf7a8d516f8f Mon Sep 17 00:00:00 2001 From: bcoconni Date: Sun, 10 Nov 2013 16:50:59 +0100 Subject: [PATCH] Added the ability to access the file name and position (line, column) from which the XML visitor is getting its data --- simgear/xml/easyxml.cxx | 18 ++++++++++ simgear/xml/easyxml.hxx | 78 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/simgear/xml/easyxml.cxx b/simgear/xml/easyxml.cxx index 08a39fa4..bdb1358b 100644 --- a/simgear/xml/easyxml.cxx +++ b/simgear/xml/easyxml.cxx @@ -136,6 +136,14 @@ XMLAttributesDefault::setValue (const char * name, const char * value) } +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void XMLVisitor::savePosition(void) +{ + column = XML_GetCurrentColumnNumber(parser); + line = XML_GetCurrentLineNumber(parser); +} + //////////////////////////////////////////////////////////////////////// // Attribute list wrapper for Expat. //////////////////////////////////////////////////////////////////////// @@ -177,18 +185,21 @@ ExpatAtts::getValue (const char * name) const static void start_element (void * userData, const char * name, const char ** atts) { + VISITOR.savePosition(); VISITOR.startElement(name, ExpatAtts(atts)); } static void end_element (void * userData, const char * name) { + VISITOR.savePosition(); VISITOR.endElement(name); } static void character_data (void * userData, const char * s, int len) { + VISITOR.savePosition(); VISITOR.data(s, len); } @@ -197,6 +208,7 @@ processing_instruction (void * userData, const char * target, const char * data) { + VISITOR.savePosition(); VISITOR.pi(target, data); } @@ -217,6 +229,8 @@ readXML (istream &input, XMLVisitor &visitor, const string &path) XML_SetCharacterDataHandler(parser, character_data); XML_SetProcessingInstructionHandler(parser, processing_instruction); + visitor.setParser(parser); + visitor.setPath(path); visitor.startXML(); char buf[16384]; @@ -229,6 +243,7 @@ readXML (istream &input, XMLVisitor &visitor, const string &path) XML_GetCurrentLineNumber(parser), XML_GetCurrentColumnNumber(parser)), "SimGear XML Parser"); + visitor.setParser(0); XML_ParserFree(parser); throw ex; } @@ -240,6 +255,7 @@ readXML (istream &input, XMLVisitor &visitor, const string &path) XML_GetCurrentLineNumber(parser), XML_GetCurrentColumnNumber(parser)), "SimGear XML Parser"); + visitor.setParser(0); XML_ParserFree(parser); throw ex; } @@ -253,10 +269,12 @@ readXML (istream &input, XMLVisitor &visitor, const string &path) XML_GetCurrentLineNumber(parser), XML_GetCurrentColumnNumber(parser)), "SimGear XML Parser"); + visitor.setParser(0); XML_ParserFree(parser); throw ex; } + visitor.setParser(0); XML_ParserFree(parser); visitor.endXML(); } diff --git a/simgear/xml/easyxml.hxx b/simgear/xml/easyxml.hxx index 6356901b..92a5c95b 100644 --- a/simgear/xml/easyxml.hxx +++ b/simgear/xml/easyxml.hxx @@ -19,6 +19,7 @@ using std::istream; using std::string; using std::vector; +typedef struct XML_ParserStruct* XML_Parser; /** * Interface for XML attributes. @@ -256,6 +257,8 @@ private: class XMLVisitor { public: + /// Constructor + XMLVisitor() : parser(0), line(-1), column(-1) {} /** * Virtual destructor. @@ -372,6 +375,81 @@ public: * the warning. */ virtual void warning (const char * message, int line, int column) {} + + /** Set the path to the file that is parsed. + * + * This method will be called to store the path to the parsed file. Note that + * the XML parser makes no use of this copy of the path. The intent is + * to be capable of refering to the path to the parsed file if needed. + * + * @param _path The path to the parsed file. + * @see #getPath + */ + void setPath(const string& _path) { path = _path; } + + /** Get the path to the parsed file. + * + * This method will be called if the application needs to access the path to + * the parsed file. This information is typically needed if an error is found + * so the file where it occurred can be retrieved to help the user locate the + * error. + * + * @return the path to the parsed file. + * @see #setPath + */ + const string& getPath(void) const { return path; } + + /** Save the current position in the parsed file. + * + * This method will be called to save the position at which the file is + * currently parsed. Note that the XML parser makes no use of that + * information. The intent is to be capable of refering to the position in + * the parsed file if needed. + * + * @see #getColumn + * @see #getLine + */ + void savePosition(void); + + /** Get the saved column number in the parsed file. + * + * This method will be called if the application needs to get the column + * number that has been saved during the last call to savePosition(). This + * information is typically needed if an error is found so the position at + * which it occurred can be retrieved to help the user locate the error. + * + * @return the save column number. + * @see #savePosition + */ + int getColumn(void) const { return column; } + + /** Get the saved line number in the parsed file. + * + * This method will be called if the application needs to get the line + * number that has been saved during the last call to savePosition(). This + * information is typically needed if an error is found so the position at + * which it occurred can be retrieved to help the user locate the error. + * + * @return the save line number. + * @see #savePosition + */ + int getLine(void) const { return line; } + + /** Set the XML parser. + * + * This method will be called so the #XMLVisitor instance can internally use + * the XML parser for its housekeeping. The intent is that #XMLVisitor will + * only call the reporting functions of the XML parser and will not interfer + * with the XML parser current state. Doing otherwise will result in an + * unpredictable behavior of the XML parser. + * + * @param _parser the XML parser + */ + void setParser(XML_Parser _parser) { parser = _parser; } +private: + XML_Parser parser; + string path; + int line, column; }; -- 2.39.5