1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: cmXMLParser.cxx,v $
6 Date: $Date: 2009-02-24 20:43:49 $
7 Version: $Revision: 1.10 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
17 #include "cmXMLParser.h"
22 //----------------------------------------------------------------------------
23 cmXMLParser::cmXMLParser()
29 //----------------------------------------------------------------------------
30 cmXMLParser::~cmXMLParser()
34 this->CleanupParser();
38 //----------------------------------------------------------------------------
39 int cmXMLParser::Parse(const char* string
)
41 return (int)this->InitializeParser() &&
42 this->ParseChunk(string
, strlen(string
)) &&
43 this->CleanupParser();
46 int cmXMLParser::ParseFile(const char* file
)
53 std::ifstream
ifs(file
);
61 return this->Parse(str
.str().c_str());
64 //----------------------------------------------------------------------------
65 int cmXMLParser::InitializeParser()
69 std::cerr
<< "Parser already initialized" << std::endl
;
74 // Create the expat XML parser.
75 this->Parser
= XML_ParserCreate(0);
76 XML_SetElementHandler(static_cast<XML_Parser
>(this->Parser
),
77 &cmXMLParserStartElement
,
78 &cmXMLParserEndElement
);
79 XML_SetCharacterDataHandler(static_cast<XML_Parser
>(this->Parser
),
80 &cmXMLParserCharacterDataHandler
);
81 XML_SetUserData(static_cast<XML_Parser
>(this->Parser
), this);
86 //----------------------------------------------------------------------------
87 int cmXMLParser::ParseChunk(const char* inputString
,
88 std::string::size_type length
)
92 std::cerr
<< "Parser not initialized" << std::endl
;
97 res
= this->ParseBuffer(inputString
, length
);
100 this->ParseError
= 1;
105 //----------------------------------------------------------------------------
106 int cmXMLParser::CleanupParser()
110 std::cerr
<< "Parser not initialized" << std::endl
;
111 this->ParseError
= 1;
114 int result
= !this->ParseError
;
117 // Tell the expat XML parser about the end-of-input.
118 if(!XML_Parse(static_cast<XML_Parser
>(this->Parser
), "", 0, 1))
120 this->ReportXmlParseError();
125 // Clean up the parser.
126 XML_ParserFree(static_cast<XML_Parser
>(this->Parser
));
132 //----------------------------------------------------------------------------
133 int cmXMLParser::ParseBuffer(const char* buffer
, std::string::size_type count
)
135 // Pass the buffer to the expat XML parser.
136 if(!XML_Parse(static_cast<XML_Parser
>(this->Parser
), buffer
,
137 static_cast<int>(count
), 0))
139 this->ReportXmlParseError();
145 //----------------------------------------------------------------------------
146 int cmXMLParser::ParseBuffer(const char* buffer
)
148 return this->ParseBuffer(buffer
, static_cast<int>(strlen(buffer
)));
151 //----------------------------------------------------------------------------
152 int cmXMLParser::ParsingComplete()
154 // Default behavior is to parse to end of stream.
158 //----------------------------------------------------------------------------
159 void cmXMLParser::StartElement(const char * name
,
160 const char ** /*atts*/)
162 std::cout
<< "Start element: " << name
<< std::endl
;
165 //----------------------------------------------------------------------------
166 void cmXMLParser::EndElement(const char * name
)
168 std::cout
<< "End element: " << name
<< std::endl
;
171 //----------------------------------------------------------------------------
172 void cmXMLParser::CharacterDataHandler(const char* /*inData*/,
177 //----------------------------------------------------------------------------
178 int cmXMLParser::IsSpace(char c
)
183 //----------------------------------------------------------------------------
184 const char* cmXMLParser::FindAttribute(const char** atts
,
185 const char* attribute
)
187 if(atts
&& attribute
)
189 for(const char** a
= atts
; *a
&& *(a
+1); a
+= 2)
191 if(strcmp(*a
, attribute
) == 0)
200 //----------------------------------------------------------------------------
201 void cmXMLParserStartElement(void* parser
, const char *name
,
204 // Begin element handler that is registered with the XML_Parser.
205 // This just casts the user data to a cmXMLParser and calls
207 static_cast<cmXMLParser
*>(parser
)->StartElement(name
, atts
);
210 //----------------------------------------------------------------------------
211 void cmXMLParserEndElement(void* parser
, const char *name
)
213 // End element handler that is registered with the XML_Parser. This
214 // just casts the user data to a cmXMLParser and calls EndElement.
215 static_cast<cmXMLParser
*>(parser
)->EndElement(name
);
218 //----------------------------------------------------------------------------
219 void cmXMLParserCharacterDataHandler(void* parser
, const char* data
,
222 // Character data handler that is registered with the XML_Parser.
223 // This just casts the user data to a cmXMLParser and calls
224 // CharacterDataHandler.
225 static_cast<cmXMLParser
*>(parser
)->CharacterDataHandler(data
, length
);
228 //----------------------------------------------------------------------------
229 void cmXMLParser::ReportXmlParseError()
231 XML_Parser
* parser
= static_cast<XML_Parser
*>(this->Parser
);
232 this->ReportError(XML_GetCurrentLineNumber(parser
),
233 XML_GetCurrentColumnNumber(parser
),
234 XML_ErrorString(XML_GetErrorCode(parser
)));
237 //----------------------------------------------------------------------------
238 void cmXMLParser::ReportError(int line
, int, const char* msg
)
240 std::cerr
<< "Error parsing XML in stream at line "
241 << line
<< ": " << msg
<< std::endl
;