1
0

cmXMLParser.cxx 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #include "cmXMLParser.h"
  14. #include <cmexpat/expat.h>
  15. //----------------------------------------------------------------------------
  16. cmXMLParser::cmXMLParser()
  17. {
  18. this->Parser = 0;
  19. this->ParseError = 0;
  20. }
  21. //----------------------------------------------------------------------------
  22. cmXMLParser::~cmXMLParser()
  23. {
  24. if ( this->Parser )
  25. {
  26. this->CleanupParser();
  27. }
  28. }
  29. //----------------------------------------------------------------------------
  30. int cmXMLParser::Parse(const char* string)
  31. {
  32. return this->InitializeParser() &&
  33. this->ParseChunk(string, strlen(string)) &&
  34. this->CleanupParser();
  35. }
  36. int cmXMLParser::ParseFile(const char* file)
  37. {
  38. if ( !file )
  39. {
  40. return 0;
  41. }
  42. std::ifstream ifs(file);
  43. if ( !ifs )
  44. {
  45. return 0;
  46. }
  47. ostringstream str;
  48. str << ifs.rdbuf();
  49. return this->Parse(str.str().c_str());
  50. }
  51. //----------------------------------------------------------------------------
  52. int cmXMLParser::InitializeParser()
  53. {
  54. if ( this->Parser )
  55. {
  56. std::cerr << "Parser already initialized" << std::endl;
  57. this->ParseError = 1;
  58. return 0;
  59. }
  60. // Create the expat XML parser.
  61. this->Parser = XML_ParserCreate(0);
  62. XML_SetElementHandler(static_cast<XML_Parser>(this->Parser),
  63. &cmXMLParserStartElement,
  64. &cmXMLParserEndElement);
  65. XML_SetCharacterDataHandler(static_cast<XML_Parser>(this->Parser),
  66. &cmXMLParserCharacterDataHandler);
  67. XML_SetUserData(static_cast<XML_Parser>(this->Parser), this);
  68. this->ParseError = 0;
  69. return 1;
  70. }
  71. //----------------------------------------------------------------------------
  72. int cmXMLParser::ParseChunk(const char* inputString, unsigned int length)
  73. {
  74. if ( !this->Parser )
  75. {
  76. std::cerr << "Parser not initialized" << std::endl;
  77. this->ParseError = 1;
  78. return 0;
  79. }
  80. int res;
  81. res = this->ParseBuffer(inputString, length);
  82. if ( res == 0 )
  83. {
  84. this->ParseError = 1;
  85. }
  86. return res;
  87. }
  88. //----------------------------------------------------------------------------
  89. int cmXMLParser::CleanupParser()
  90. {
  91. if ( !this->Parser )
  92. {
  93. std::cerr << "Parser not initialized" << std::endl;
  94. this->ParseError = 1;
  95. return 0;
  96. }
  97. int result = !this->ParseError;
  98. if(result)
  99. {
  100. // Tell the expat XML parser about the end-of-input.
  101. if(!XML_Parse(static_cast<XML_Parser>(this->Parser), "", 0, 1))
  102. {
  103. this->ReportXmlParseError();
  104. result = 0;
  105. }
  106. }
  107. // Clean up the parser.
  108. XML_ParserFree(static_cast<XML_Parser>(this->Parser));
  109. this->Parser = 0;
  110. return result;
  111. }
  112. //----------------------------------------------------------------------------
  113. int cmXMLParser::ParseBuffer(const char* buffer, unsigned int count)
  114. {
  115. // Pass the buffer to the expat XML parser.
  116. if(!XML_Parse(static_cast<XML_Parser>(this->Parser), buffer, count, 0))
  117. {
  118. this->ReportXmlParseError();
  119. return 0;
  120. }
  121. return 1;
  122. }
  123. //----------------------------------------------------------------------------
  124. int cmXMLParser::ParseBuffer(const char* buffer)
  125. {
  126. return this->ParseBuffer(buffer, static_cast<int>(strlen(buffer)));
  127. }
  128. //----------------------------------------------------------------------------
  129. int cmXMLParser::ParsingComplete()
  130. {
  131. // Default behavior is to parse to end of stream.
  132. return 0;
  133. }
  134. //----------------------------------------------------------------------------
  135. void cmXMLParser::StartElement(const char * name,
  136. const char ** /*atts*/)
  137. {
  138. std::cout << "Start element: " << name << std::endl;
  139. }
  140. //----------------------------------------------------------------------------
  141. void cmXMLParser::EndElement(const char * name)
  142. {
  143. std::cout << "End element: " << name << std::endl;
  144. }
  145. //----------------------------------------------------------------------------
  146. void cmXMLParser::CharacterDataHandler(const char* /*inData*/,
  147. int /*inLength*/)
  148. {
  149. }
  150. //----------------------------------------------------------------------------
  151. int cmXMLParser::IsSpace(char c)
  152. {
  153. return isspace(c);
  154. }
  155. //----------------------------------------------------------------------------
  156. void cmXMLParserStartElement(void* parser, const char *name,
  157. const char **atts)
  158. {
  159. // Begin element handler that is registered with the XML_Parser.
  160. // This just casts the user data to a cmXMLParser and calls
  161. // StartElement.
  162. static_cast<cmXMLParser*>(parser)->StartElement(name, atts);
  163. }
  164. //----------------------------------------------------------------------------
  165. void cmXMLParserEndElement(void* parser, const char *name)
  166. {
  167. // End element handler that is registered with the XML_Parser. This
  168. // just casts the user data to a cmXMLParser and calls EndElement.
  169. static_cast<cmXMLParser*>(parser)->EndElement(name);
  170. }
  171. //----------------------------------------------------------------------------
  172. void cmXMLParserCharacterDataHandler(void* parser, const char* data,
  173. int length)
  174. {
  175. // Character data handler that is registered with the XML_Parser.
  176. // This just casts the user data to a cmXMLParser and calls
  177. // CharacterDataHandler.
  178. static_cast<cmXMLParser*>(parser)->CharacterDataHandler(data, length);
  179. }
  180. //----------------------------------------------------------------------------
  181. void cmXMLParser::ReportXmlParseError()
  182. {
  183. std::cerr << "Error parsing XML in stream at line "
  184. << XML_GetCurrentLineNumber(static_cast<XML_Parser>(this->Parser))
  185. << ": "
  186. << XML_ErrorString(XML_GetErrorCode(
  187. static_cast<XML_Parser>(this->Parser))) << std::endl;
  188. }