mirror of https://github.com/Kitware/CMake.git

3 changed files with 423 additions and 96 deletions
@ -0,0 +1,217 @@ |
|||
/*=========================================================================
|
|||
|
|||
Program: CMake - Cross-Platform Makefile Generator |
|||
Module: $RCSfile$ |
|||
Language: C++ |
|||
Date: $Date$ |
|||
Version: $Revision$ |
|||
|
|||
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. |
|||
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
|
|||
|
|||
This software is distributed WITHOUT ANY WARRANTY; without even |
|||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
|||
PURPOSE. See the above copyright notices for more information. |
|||
|
|||
=========================================================================*/ |
|||
#include "cmXMLParser.h"
|
|||
|
|||
#include <cmexpat/expat.h>
|
|||
|
|||
//----------------------------------------------------------------------------
|
|||
cmXMLParser::cmXMLParser() |
|||
{ |
|||
this->Parser = 0; |
|||
this->ParseError = 0; |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------
|
|||
cmXMLParser::~cmXMLParser() |
|||
{ |
|||
if ( this->Parser ) |
|||
{ |
|||
this->CleanupParser(); |
|||
} |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------
|
|||
int cmXMLParser::Parse(const char* string) |
|||
{ |
|||
return this->InitializeParser() && |
|||
this->ParseChunk(string, strlen(string)) && |
|||
this->CleanupParser(); |
|||
} |
|||
|
|||
int cmXMLParser::ParseFile(const char* file) |
|||
{ |
|||
if ( !file ) |
|||
{ |
|||
return 0; |
|||
} |
|||
|
|||
std::ifstream ifs(file); |
|||
if ( !ifs ) |
|||
{ |
|||
return 0; |
|||
} |
|||
|
|||
ostringstream 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, unsigned int 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, unsigned int count) |
|||
{ |
|||
// Pass the buffer to the expat XML parser.
|
|||
if(!XML_Parse(static_cast<XML_Parser>(this->Parser), buffer, 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 char * name, |
|||
const char ** /*atts*/) |
|||
{ |
|||
std::cout << "Start element: " << name << std::endl; |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------
|
|||
void cmXMLParser::EndElement(const char * name) |
|||
{ |
|||
std::cout << "End element: " << name << std::endl; |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------
|
|||
void cmXMLParser::CharacterDataHandler(const char* /*inData*/, |
|||
int /*inLength*/) |
|||
{ |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------
|
|||
int cmXMLParser::IsSpace(char c) |
|||
{ |
|||
return isspace(c); |
|||
} |
|||
|
|||
//----------------------------------------------------------------------------
|
|||
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() |
|||
{ |
|||
std::cerr << "Error parsing XML in stream at line " |
|||
<< XML_GetCurrentLineNumber(static_cast<XML_Parser>(this->Parser)) |
|||
<< ": " |
|||
<< XML_ErrorString(XML_GetErrorCode( |
|||
static_cast<XML_Parser>(this->Parser))) << std::endl; |
|||
} |
|||
|
@ -0,0 +1,108 @@ |
|||
/*========================================================================= |
|||
|
|||
Program: CMake - Cross-Platform Makefile Generator |
|||
Module: $RCSfile$ |
|||
Language: C++ |
|||
Date: $Date$ |
|||
Version: $Revision$ |
|||
|
|||
Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. |
|||
See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. |
|||
|
|||
This software is distributed WITHOUT ANY WARRANTY; without even |
|||
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
|||
PURPOSE. See the above copyright notices for more information. |
|||
|
|||
=========================================================================*/ |
|||
#ifndef cmXMLParser_h |
|||
#define cmXMLParser_h |
|||
|
|||
#include "cmStandardIncludes.h" |
|||
|
|||
extern "C" |
|||
{ |
|||
void cmXMLParserStartElement(void*, const char*, const char**); |
|||
void cmXMLParserEndElement(void*, const char*); |
|||
void cmXMLParserCharacterDataHandler(void*, const char*, int); |
|||
} |
|||
|
|||
/** \class cmXMLParser |
|||
* \brief Helper class for performing XML parsing |
|||
* |
|||
* Superclass for all XML parsers. |
|||
*/ |
|||
class cmXMLParser |
|||
{ |
|||
public: |
|||
cmXMLParser(); |
|||
virtual ~cmXMLParser(); |
|||
|
|||
//! Parse given XML string |
|||
virtual int Parse(const char* string); |
|||
|
|||
//! Parse given XML file |
|||
virtual int ParseFile(const char* file); |
|||
|
|||
/** |
|||
* When parsing fragments of XML or streaming XML, use the following three |
|||
* methods. InitializeParser method initialize parser but does not perform |
|||
* any actual parsing. ParseChunk parses framgent of XML. This has to match |
|||
* to what was already parsed. CleanupParser finishes parsing. If there were |
|||
* errors, CleanupParser will report them. |
|||
*/ |
|||
virtual int InitializeParser(); |
|||
virtual int ParseChunk(const char* inputString, unsigned int length); |
|||
virtual int CleanupParser(); |
|||
|
|||
protected: |
|||
//! This variable is true if there was a parse error while parsing in chunks. |
|||
int ParseError; |
|||
|
|||
//1 Expat parser structure. Exists only during call to Parse(). |
|||
void* Parser; |
|||
|
|||
/** |
|||
* Called before each block of input is read from the stream to check if |
|||
* parsing is complete. Can be replaced by subclasses to change the |
|||
* terminating condition for parsing. Parsing always stops when the end of |
|||
* file is reached in the stream. |
|||
*/ |
|||
|
|||
virtual int ParsingComplete(); |
|||
|
|||
/** |
|||
* Called when a new element is opened in the XML source. Should be replaced |
|||
* by subclasses to handle each element. |
|||
* name = Name of new element. |
|||
* atts = Null-terminated array of attribute name/value pairs. Even |
|||
* indices are attribute names, and odd indices are values. |
|||
*/ |
|||
virtual void StartElement(const char* name, const char** atts); |
|||
|
|||
//! Called at the end of an element in the XML source opened when StartElement |
|||
// was called. |
|||
virtual void EndElement(const char* name); |
|||
|
|||
//! Called when there is character data to handle. |
|||
virtual void CharacterDataHandler(const char* data, int length); |
|||
|
|||
//! Called by Parse to report an XML syntax error. |
|||
virtual void ReportXmlParseError(); |
|||
|
|||
//! Utility for convenience of subclasses. Wraps isspace C library |
|||
// routine. |
|||
static int IsSpace(char c); |
|||
|
|||
//! Send the given buffer to the XML parser. |
|||
virtual int ParseBuffer(const char* buffer, unsigned int count); |
|||
|
|||
//! Send the given c-style string to the XML parser. |
|||
int ParseBuffer(const char* buffer); |
|||
|
|||
//! Callbacks for the expat |
|||
friend void cmXMLParserStartElement(void*, const char*, const char**); |
|||
friend void cmXMLParserEndElement(void*, const char*); |
|||
friend void cmXMLParserCharacterDataHandler(void*, const char*, int); |
|||
}; |
|||
|
|||
#endif |
Write
Preview
Loading…
Cancel
Save
Reference in new issue