mirror of
https://github.com/reactos/CMake.git
synced 2024-12-14 23:29:57 +00:00
96afb12087
This converts the CMake license to a pure 3-clause OSI-approved BSD License. We drop the previous license clause requiring modified versions to be plainly marked. We also update the CMake copyright to cover the full development time range.
238 lines
6.8 KiB
C++
238 lines
6.8 KiB
C++
/*============================================================================
|
|
CMake - Cross Platform Makefile Generator
|
|
Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
|
|
|
|
Distributed under the OSI-approved BSD License (the "License");
|
|
see accompanying file Copyright.txt for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even the
|
|
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
See the License for more information.
|
|
============================================================================*/
|
|
#include "cmXMLParser.h"
|
|
|
|
#include <cm_expat.h>
|
|
#include <ctype.h>
|
|
|
|
//----------------------------------------------------------------------------
|
|
cmXMLParser::cmXMLParser()
|
|
{
|
|
this->Parser = 0;
|
|
this->ParseError = 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
cmXMLParser::~cmXMLParser()
|
|
{
|
|
if ( this->Parser )
|
|
{
|
|
this->CleanupParser();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int cmXMLParser::Parse(const char* string)
|
|
{
|
|
return (int)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;
|
|
}
|
|
|
|
cmOStringStream 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,
|
|
std::string::size_type 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, std::string::size_type count)
|
|
{
|
|
// Pass the buffer to the expat XML parser.
|
|
if(!XML_Parse(static_cast<XML_Parser>(this->Parser), buffer,
|
|
static_cast<int>(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);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const char* cmXMLParser::FindAttribute(const char** atts,
|
|
const char* attribute)
|
|
{
|
|
if(atts && attribute)
|
|
{
|
|
for(const char** a = atts; *a && *(a+1); a += 2)
|
|
{
|
|
if(strcmp(*a, attribute) == 0)
|
|
{
|
|
return *(a+1);
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
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()
|
|
{
|
|
XML_Parser parser = static_cast<XML_Parser>(this->Parser);
|
|
this->ReportError(XML_GetCurrentLineNumber(parser),
|
|
XML_GetCurrentColumnNumber(parser),
|
|
XML_ErrorString(XML_GetErrorCode(parser)));
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void cmXMLParser::ReportError(int line, int, const char* msg)
|
|
{
|
|
std::cerr << "Error parsing XML in stream at line "
|
|
<< line << ": " << msg << std::endl;
|
|
}
|