summaryrefslogtreecommitdiff
path: root/Source/cmXMLParser.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/cmXMLParser.cxx')
-rw-r--r--Source/cmXMLParser.cxx237
1 files changed, 237 insertions, 0 deletions
diff --git a/Source/cmXMLParser.cxx b/Source/cmXMLParser.cxx
new file mode 100644
index 000000000..46a1ca4aa
--- /dev/null
+++ b/Source/cmXMLParser.cxx
@@ -0,0 +1,237 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmXMLParser.h"
+
+#include <cm_expat.h>
+#include <ctype.h>
+
+//----------------------------------------------------------------------------
+cmXMLParser::cmXMLParser()
+{
+ this->Parser = 0;
+ this->ParseError = 0;
+}
+
+//----------------------------------------------------------------------------
+cmXMLParser::~cmXMLParser()
+{
+ if ( this->Parser )
+ {
+ this->CleanupParser();
+ }
+}
+
+//----------------------------------------------------------------------------
+int cmXMLParser::Parse(const char* string)
+{
+ return (int)this->InitializeParser() &&
+ this->ParseChunk(string, strlen(string)) &&
+ this->CleanupParser();
+}
+
+int cmXMLParser::ParseFile(const char* file)
+{
+ if ( !file )
+ {
+ return 0;
+ }
+
+ std::ifstream ifs(file);
+ if ( !ifs )
+ {
+ return 0;
+ }
+
+ cmOStringStream str;
+ str << ifs.rdbuf();
+ return this->Parse(str.str().c_str());
+}
+
+//----------------------------------------------------------------------------
+int cmXMLParser::InitializeParser()
+{
+ if ( this->Parser )
+ {
+ std::cerr << "Parser already initialized" << std::endl;
+ this->ParseError = 1;
+ return 0;
+ }
+
+ // Create the expat XML parser.
+ this->Parser = XML_ParserCreate(0);
+ XML_SetElementHandler(static_cast<XML_Parser>(this->Parser),
+ &cmXMLParserStartElement,
+ &cmXMLParserEndElement);
+ XML_SetCharacterDataHandler(static_cast<XML_Parser>(this->Parser),
+ &cmXMLParserCharacterDataHandler);
+ XML_SetUserData(static_cast<XML_Parser>(this->Parser), this);
+ this->ParseError = 0;
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+int cmXMLParser::ParseChunk(const char* inputString,
+ std::string::size_type length)
+{
+ if ( !this->Parser )
+ {
+ std::cerr << "Parser not initialized" << std::endl;
+ this->ParseError = 1;
+ return 0;
+ }
+ int res;
+ res = this->ParseBuffer(inputString, length);
+ if ( res == 0 )
+ {
+ this->ParseError = 1;
+ }
+ return res;
+}
+
+//----------------------------------------------------------------------------
+int cmXMLParser::CleanupParser()
+{
+ if ( !this->Parser )
+ {
+ std::cerr << "Parser not initialized" << std::endl;
+ this->ParseError = 1;
+ return 0;
+ }
+ int result = !this->ParseError;
+ if(result)
+ {
+ // Tell the expat XML parser about the end-of-input.
+ if(!XML_Parse(static_cast<XML_Parser>(this->Parser), "", 0, 1))
+ {
+ this->ReportXmlParseError();
+ result = 0;
+ }
+ }
+
+ // Clean up the parser.
+ XML_ParserFree(static_cast<XML_Parser>(this->Parser));
+ this->Parser = 0;
+
+ return result;
+}
+
+//----------------------------------------------------------------------------
+int cmXMLParser::ParseBuffer(const char* buffer, std::string::size_type count)
+{
+ // Pass the buffer to the expat XML parser.
+ if(!XML_Parse(static_cast<XML_Parser>(this->Parser), buffer,
+ static_cast<int>(count), 0))
+ {
+ this->ReportXmlParseError();
+ return 0;
+ }
+ return 1;
+}
+
+//----------------------------------------------------------------------------
+int cmXMLParser::ParseBuffer(const char* buffer)
+{
+ return this->ParseBuffer(buffer, static_cast<int>(strlen(buffer)));
+}
+
+//----------------------------------------------------------------------------
+int cmXMLParser::ParsingComplete()
+{
+ // Default behavior is to parse to end of stream.
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+void cmXMLParser::StartElement(const char * name,
+ const char ** /*atts*/)
+{
+ std::cout << "Start element: " << name << std::endl;
+}
+
+//----------------------------------------------------------------------------
+void cmXMLParser::EndElement(const char * name)
+{
+ std::cout << "End element: " << name << std::endl;
+}
+
+//----------------------------------------------------------------------------
+void cmXMLParser::CharacterDataHandler(const char* /*inData*/,
+ int /*inLength*/)
+{
+}
+
+//----------------------------------------------------------------------------
+int cmXMLParser::IsSpace(char c)
+{
+ return isspace(c);
+}
+
+//----------------------------------------------------------------------------
+const char* cmXMLParser::FindAttribute(const char** atts,
+ const char* attribute)
+{
+ if(atts && attribute)
+ {
+ for(const char** a = atts; *a && *(a+1); a += 2)
+ {
+ if(strcmp(*a, attribute) == 0)
+ {
+ return *(a+1);
+ }
+ }
+ }
+ return 0;
+}
+
+//----------------------------------------------------------------------------
+void cmXMLParserStartElement(void* parser, const char *name,
+ const char **atts)
+{
+ // Begin element handler that is registered with the XML_Parser.
+ // This just casts the user data to a cmXMLParser and calls
+ // StartElement.
+ static_cast<cmXMLParser*>(parser)->StartElement(name, atts);
+}
+
+//----------------------------------------------------------------------------
+void cmXMLParserEndElement(void* parser, const char *name)
+{
+ // End element handler that is registered with the XML_Parser. This
+ // just casts the user data to a cmXMLParser and calls EndElement.
+ static_cast<cmXMLParser*>(parser)->EndElement(name);
+}
+
+//----------------------------------------------------------------------------
+void cmXMLParserCharacterDataHandler(void* parser, const char* data,
+ int length)
+{
+ // Character data handler that is registered with the XML_Parser.
+ // This just casts the user data to a cmXMLParser and calls
+ // CharacterDataHandler.
+ static_cast<cmXMLParser*>(parser)->CharacterDataHandler(data, length);
+}
+
+//----------------------------------------------------------------------------
+void cmXMLParser::ReportXmlParseError()
+{
+ XML_Parser parser = static_cast<XML_Parser>(this->Parser);
+ this->ReportError(XML_GetCurrentLineNumber(parser),
+ XML_GetCurrentColumnNumber(parser),
+ XML_ErrorString(XML_GetErrorCode(parser)));
+}
+
+//----------------------------------------------------------------------------
+void cmXMLParser::ReportError(int line, int, const char* msg)
+{
+ std::cerr << "Error parsing XML in stream at line "
+ << line << ": " << msg << std::endl;
+}