1 /*============================================================================
2 CMake - Cross Platform Makefile Generator
3 Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
5 Distributed under the OSI-approved BSD License (the "License");
6 see accompanying file Copyright.txt for details.
8 This software is distributed WITHOUT ANY WARRANTY; without even the
9 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 See the License for more information.
11 ============================================================================*/
12 #include "cmXMLParser.h"
17 //----------------------------------------------------------------------------
18 cmXMLParser::cmXMLParser()
24 //----------------------------------------------------------------------------
25 cmXMLParser::~cmXMLParser()
29 this->CleanupParser();
33 //----------------------------------------------------------------------------
34 int cmXMLParser::Parse(const char* string)
36 return (int)this->InitializeParser() &&
37 this->ParseChunk(string, strlen(string)) &&
38 this->CleanupParser();
41 int cmXMLParser::ParseFile(const char* file)
48 std::ifstream ifs(file);
56 return this->Parse(str.str().c_str());
59 //----------------------------------------------------------------------------
60 int cmXMLParser::InitializeParser()
64 std::cerr << "Parser already initialized" << std::endl;
69 // Create the expat XML parser.
70 this->Parser = XML_ParserCreate(0);
71 XML_SetElementHandler(static_cast<XML_Parser>(this->Parser),
72 &cmXMLParserStartElement,
73 &cmXMLParserEndElement);
74 XML_SetCharacterDataHandler(static_cast<XML_Parser>(this->Parser),
75 &cmXMLParserCharacterDataHandler);
76 XML_SetUserData(static_cast<XML_Parser>(this->Parser), this);
81 //----------------------------------------------------------------------------
82 int cmXMLParser::ParseChunk(const char* inputString,
83 std::string::size_type length)
87 std::cerr << "Parser not initialized" << std::endl;
92 res = this->ParseBuffer(inputString, length);
100 //----------------------------------------------------------------------------
101 int cmXMLParser::CleanupParser()
105 std::cerr << "Parser not initialized" << std::endl;
106 this->ParseError = 1;
109 int result = !this->ParseError;
112 // Tell the expat XML parser about the end-of-input.
113 if(!XML_Parse(static_cast<XML_Parser>(this->Parser), "", 0, 1))
115 this->ReportXmlParseError();
120 // Clean up the parser.
121 XML_ParserFree(static_cast<XML_Parser>(this->Parser));
127 //----------------------------------------------------------------------------
128 int cmXMLParser::ParseBuffer(const char* buffer, std::string::size_type count)
130 // Pass the buffer to the expat XML parser.
131 if(!XML_Parse(static_cast<XML_Parser>(this->Parser), buffer,
132 static_cast<int>(count), 0))
134 this->ReportXmlParseError();
140 //----------------------------------------------------------------------------
141 int cmXMLParser::ParseBuffer(const char* buffer)
143 return this->ParseBuffer(buffer, static_cast<int>(strlen(buffer)));
146 //----------------------------------------------------------------------------
147 int cmXMLParser::ParsingComplete()
149 // Default behavior is to parse to end of stream.
153 //----------------------------------------------------------------------------
154 void cmXMLParser::StartElement(const char * name,
155 const char ** /*atts*/)
157 std::cout << "Start element: " << name << std::endl;
160 //----------------------------------------------------------------------------
161 void cmXMLParser::EndElement(const char * name)
163 std::cout << "End element: " << name << std::endl;
166 //----------------------------------------------------------------------------
167 void cmXMLParser::CharacterDataHandler(const char* /*inData*/,
172 //----------------------------------------------------------------------------
173 int cmXMLParser::IsSpace(char c)
178 //----------------------------------------------------------------------------
179 const char* cmXMLParser::FindAttribute(const char** atts,
180 const char* attribute)
182 if(atts && attribute)
184 for(const char** a = atts; *a && *(a+1); a += 2)
186 if(strcmp(*a, attribute) == 0)
195 //----------------------------------------------------------------------------
196 void cmXMLParserStartElement(void* parser, const char *name,
199 // Begin element handler that is registered with the XML_Parser.
200 // This just casts the user data to a cmXMLParser and calls
202 static_cast<cmXMLParser*>(parser)->StartElement(name, atts);
205 //----------------------------------------------------------------------------
206 void cmXMLParserEndElement(void* parser, const char *name)
208 // End element handler that is registered with the XML_Parser. This
209 // just casts the user data to a cmXMLParser and calls EndElement.
210 static_cast<cmXMLParser*>(parser)->EndElement(name);
213 //----------------------------------------------------------------------------
214 void cmXMLParserCharacterDataHandler(void* parser, const char* data,
217 // Character data handler that is registered with the XML_Parser.
218 // This just casts the user data to a cmXMLParser and calls
219 // CharacterDataHandler.
220 static_cast<cmXMLParser*>(parser)->CharacterDataHandler(data, length);
223 //----------------------------------------------------------------------------
224 void cmXMLParser::ReportXmlParseError()
226 XML_Parser parser = static_cast<XML_Parser>(this->Parser);
227 this->ReportError(XML_GetCurrentLineNumber(parser),
228 XML_GetCurrentColumnNumber(parser),
229 XML_ErrorString(XML_GetErrorCode(parser)));
232 //----------------------------------------------------------------------------
233 void cmXMLParser::ReportError(int line, int, const char* msg)
235 std::cerr << "Error parsing XML in stream at line "
236 << line << ": " << msg << std::endl;