| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- /*============================================================================
- 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 <cmsys/FStream.hxx>
- #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;
- }
- cmsys::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 std::string& name,
- const char ** /*atts*/)
- {
- std::cout << "Start element: " << name << std::endl;
- }
- //----------------------------------------------------------------------------
- void cmXMLParser::EndElement(const std::string& 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;
- }
|