cmXMLParser.cxx 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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. #include <ctype.h>
  16. //----------------------------------------------------------------------------
  17. cmXMLParser::cmXMLParser()
  18. {
  19. this->Parser = 0;
  20. this->ParseError = 0;
  21. }
  22. //----------------------------------------------------------------------------
  23. cmXMLParser::~cmXMLParser()
  24. {
  25. if ( this->Parser )
  26. {
  27. this->CleanupParser();
  28. }
  29. }
  30. //----------------------------------------------------------------------------
  31. int cmXMLParser::Parse(const char* string)
  32. {
  33. return (int)this->InitializeParser() &&
  34. this->ParseChunk(string, (unsigned int)strlen(string)) &&
  35. this->CleanupParser();
  36. }
  37. int cmXMLParser::ParseFile(const char* file)
  38. {
  39. if ( !file )
  40. {
  41. return 0;
  42. }
  43. std::ifstream ifs(file);
  44. if ( !ifs )
  45. {
  46. return 0;
  47. }
  48. cmOStringStream str;
  49. str << ifs.rdbuf();
  50. return this->Parse(str.str().c_str());
  51. }
  52. //----------------------------------------------------------------------------
  53. int cmXMLParser::InitializeParser()
  54. {
  55. if ( this->Parser )
  56. {
  57. std::cerr << "Parser already initialized" << std::endl;
  58. this->ParseError = 1;
  59. return 0;
  60. }
  61. // Create the expat XML parser.
  62. this->Parser = XML_ParserCreate(0);
  63. XML_SetElementHandler(static_cast<XML_Parser>(this->Parser),
  64. &cmXMLParserStartElement,
  65. &cmXMLParserEndElement);
  66. XML_SetCharacterDataHandler(static_cast<XML_Parser>(this->Parser),
  67. &cmXMLParserCharacterDataHandler);
  68. XML_SetUserData(static_cast<XML_Parser>(this->Parser), this);
  69. this->ParseError = 0;
  70. return 1;
  71. }
  72. //----------------------------------------------------------------------------
  73. int cmXMLParser::ParseChunk(const char* inputString, unsigned int length)
  74. {
  75. if ( !this->Parser )
  76. {
  77. std::cerr << "Parser not initialized" << std::endl;
  78. this->ParseError = 1;
  79. return 0;
  80. }
  81. int res;
  82. res = this->ParseBuffer(inputString, length);
  83. if ( res == 0 )
  84. {
  85. this->ParseError = 1;
  86. }
  87. return res;
  88. }
  89. //----------------------------------------------------------------------------
  90. int cmXMLParser::CleanupParser()
  91. {
  92. if ( !this->Parser )
  93. {
  94. std::cerr << "Parser not initialized" << std::endl;
  95. this->ParseError = 1;
  96. return 0;
  97. }
  98. int result = !this->ParseError;
  99. if(result)
  100. {
  101. // Tell the expat XML parser about the end-of-input.
  102. if(!XML_Parse(static_cast<XML_Parser>(this->Parser), "", 0, 1))
  103. {
  104. this->ReportXmlParseError();
  105. result = 0;
  106. }
  107. }
  108. // Clean up the parser.
  109. XML_ParserFree(static_cast<XML_Parser>(this->Parser));
  110. this->Parser = 0;
  111. return result;
  112. }
  113. //----------------------------------------------------------------------------
  114. int cmXMLParser::ParseBuffer(const char* buffer, unsigned int count)
  115. {
  116. // Pass the buffer to the expat XML parser.
  117. if(!XML_Parse(static_cast<XML_Parser>(this->Parser), buffer, count, 0))
  118. {
  119. this->ReportXmlParseError();
  120. return 0;
  121. }
  122. return 1;
  123. }
  124. //----------------------------------------------------------------------------
  125. int cmXMLParser::ParseBuffer(const char* buffer)
  126. {
  127. return this->ParseBuffer(buffer, static_cast<int>(strlen(buffer)));
  128. }
  129. //----------------------------------------------------------------------------
  130. int cmXMLParser::ParsingComplete()
  131. {
  132. // Default behavior is to parse to end of stream.
  133. return 0;
  134. }
  135. //----------------------------------------------------------------------------
  136. void cmXMLParser::StartElement(const char * name,
  137. const char ** /*atts*/)
  138. {
  139. std::cout << "Start element: " << name << std::endl;
  140. }
  141. //----------------------------------------------------------------------------
  142. void cmXMLParser::EndElement(const char * name)
  143. {
  144. std::cout << "End element: " << name << std::endl;
  145. }
  146. //----------------------------------------------------------------------------
  147. void cmXMLParser::CharacterDataHandler(const char* /*inData*/,
  148. int /*inLength*/)
  149. {
  150. }
  151. //----------------------------------------------------------------------------
  152. int cmXMLParser::IsSpace(char c)
  153. {
  154. return isspace(c);
  155. }
  156. //----------------------------------------------------------------------------
  157. void cmXMLParserStartElement(void* parser, const char *name,
  158. const char **atts)
  159. {
  160. // Begin element handler that is registered with the XML_Parser.
  161. // This just casts the user data to a cmXMLParser and calls
  162. // StartElement.
  163. static_cast<cmXMLParser*>(parser)->StartElement(name, atts);
  164. }
  165. //----------------------------------------------------------------------------
  166. void cmXMLParserEndElement(void* parser, const char *name)
  167. {
  168. // End element handler that is registered with the XML_Parser. This
  169. // just casts the user data to a cmXMLParser and calls EndElement.
  170. static_cast<cmXMLParser*>(parser)->EndElement(name);
  171. }
  172. //----------------------------------------------------------------------------
  173. void cmXMLParserCharacterDataHandler(void* parser, const char* data,
  174. int length)
  175. {
  176. // Character data handler that is registered with the XML_Parser.
  177. // This just casts the user data to a cmXMLParser and calls
  178. // CharacterDataHandler.
  179. static_cast<cmXMLParser*>(parser)->CharacterDataHandler(data, length);
  180. }
  181. //----------------------------------------------------------------------------
  182. void cmXMLParser::ReportXmlParseError()
  183. {
  184. std::cerr << "Error parsing XML in stream at line "
  185. << XML_GetCurrentLineNumber(static_cast<XML_Parser>(this->Parser))
  186. << ": "
  187. << XML_ErrorString(XML_GetErrorCode(
  188. static_cast<XML_Parser>(this->Parser))) << std::endl;
  189. }