CMake/Source/cmXMLParser.cxx

203 lines
5.1 KiB
C++
Raw Normal View History

Simplify CMake per-source license notices Per-source copyright/license notice headers that spell out copyright holder names and years are hard to maintain and often out-of-date or plain wrong. Precise contributor information is already maintained automatically by the version control tool. Ultimately it is the receiver of a file who is responsible for determining its licensing status, and per-source notices are merely a convenience. Therefore it is simpler and more accurate for each source to have a generic notice of the license name and references to more detailed information on copyright holders and full license terms. Our `Copyright.txt` file now contains a list of Contributors whose names appeared source-level copyright notices. It also references version control history for more precise information. Therefore we no longer need to spell out the list of Contributors in each source file notice. Replace CMake per-source copyright/license notice headers with a short description of the license and links to `Copyright.txt` and online information available from "https://cmake.org/licensing". The online URL also handles cases of modules being copied out of our source into other projects, so we can drop our notices about replacing links with full license text. Run the `Utilities/Scripts/filter-notices.bash` script to perform the majority of the replacements mechanically. Manually fix up shebang lines and trailing newlines in a few files. Manually update the notices in a few files that the script does not handle.
2016-09-27 22:01:08 +03:00
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
2005-01-18 21:41:23 +03:00
#include "cmXMLParser.h"
#include <cm_expat.h>
#include <cmsys/FStream.hxx>
#include <ctype.h>
#include <iostream>
#include <sstream>
#include <string.h>
2005-01-18 21:41:23 +03:00
cmXMLParser::cmXMLParser()
{
2016-09-06 00:18:05 +03:00
this->Parser = CM_NULLPTR;
2005-01-18 21:41:23 +03:00
this->ParseError = 0;
2016-09-06 00:18:05 +03:00
this->ReportCallback = CM_NULLPTR;
this->ReportCallbackData = CM_NULLPTR;
2005-01-18 21:41:23 +03:00
}
cmXMLParser::~cmXMLParser()
{
if (this->Parser) {
2005-01-18 21:41:23 +03:00
this->CleanupParser();
}
2005-01-18 21:41:23 +03:00
}
int cmXMLParser::Parse(const char* string)
{
return (int)this->InitializeParser() &&
this->ParseChunk(string, strlen(string)) && this->CleanupParser();
2005-01-18 21:41:23 +03:00
}
int cmXMLParser::ParseFile(const char* file)
{
if (!file) {
2005-01-18 21:41:23 +03:00
return 0;
}
2005-01-18 21:41:23 +03:00
cmsys::ifstream ifs(file);
if (!ifs) {
2005-01-18 21:41:23 +03:00
return 0;
}
2005-01-18 21:41:23 +03:00
std::ostringstream str;
2005-01-18 21:41:23 +03:00
str << ifs.rdbuf();
return this->Parse(str.str().c_str());
}
int cmXMLParser::InitializeParser()
{
if (this->Parser) {
2005-01-18 21:41:23 +03:00
std::cerr << "Parser already initialized" << std::endl;
this->ParseError = 1;
return 0;
}
2005-01-18 21:41:23 +03:00
// Create the expat XML parser.
2016-09-06 00:18:05 +03:00
this->Parser = XML_ParserCreate(CM_NULLPTR);
2005-01-18 21:41:23 +03:00
XML_SetElementHandler(static_cast<XML_Parser>(this->Parser),
&cmXMLParserStartElement, &cmXMLParserEndElement);
2005-01-18 21:41:23 +03:00
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,
2007-07-25 17:22:19 +04:00
std::string::size_type length)
2005-01-18 21:41:23 +03:00
{
if (!this->Parser) {
2005-01-18 21:41:23 +03:00
std::cerr << "Parser not initialized" << std::endl;
this->ParseError = 1;
return 0;
}
2005-01-18 21:41:23 +03:00
int res;
res = this->ParseBuffer(inputString, length);
if (res == 0) {
2005-01-18 21:41:23 +03:00
this->ParseError = 1;
}
2005-01-18 21:41:23 +03:00
return res;
}
int cmXMLParser::CleanupParser()
{
if (!this->Parser) {
2005-01-18 21:41:23 +03:00
std::cerr << "Parser not initialized" << std::endl;
this->ParseError = 1;
return 0;
}
2005-01-18 21:41:23 +03:00
int result = !this->ParseError;
if (result) {
2005-01-18 21:41:23 +03:00
// Tell the expat XML parser about the end-of-input.
if (!XML_Parse(static_cast<XML_Parser>(this->Parser), "", 0, 1)) {
2005-01-18 21:41:23 +03:00
this->ReportXmlParseError();
result = 0;
}
}
2005-01-18 21:41:23 +03:00
// Clean up the parser.
XML_ParserFree(static_cast<XML_Parser>(this->Parser));
2016-09-06 00:18:05 +03:00
this->Parser = CM_NULLPTR;
2005-01-18 21:41:23 +03:00
return result;
}
2007-07-26 22:36:06 +04:00
int cmXMLParser::ParseBuffer(const char* buffer, std::string::size_type count)
2005-01-18 21:41:23 +03:00
{
// Pass the buffer to the expat XML parser.
if (!XML_Parse(static_cast<XML_Parser>(this->Parser), buffer,
static_cast<int>(count), 0)) {
2005-01-18 21:41:23 +03:00
this->ReportXmlParseError();
return 0;
}
2005-01-18 21:41:23 +03:00
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 std::string& name, const char** /*atts*/)
2005-01-18 21:41:23 +03:00
{
std::cout << "Start element: " << name << std::endl;
}
void cmXMLParser::EndElement(const std::string& name)
2005-01-18 21:41:23 +03:00
{
std::cout << "End element: " << name << std::endl;
}
void cmXMLParser::CharacterDataHandler(const char* /*inData*/,
int /*inLength*/)
2005-01-18 21:41:23 +03:00
{
}
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);
}
}
}
2016-09-06 00:18:05 +03:00
return CM_NULLPTR;
}
void cmXMLParserStartElement(void* parser, const char* name, const char** atts)
2005-01-18 21:41:23 +03:00
{
// 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)
2005-01-18 21:41:23 +03:00
{
// 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)
2005-01-18 21:41:23 +03:00
{
// 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)));
2005-01-18 21:41:23 +03:00
}
void cmXMLParser::ReportError(int line, int /*unused*/, const char* msg)
{
if (this->ReportCallback) {
this->ReportCallback(line, msg, this->ReportCallbackData);
} else {
std::cerr << "Error parsing XML in stream at line " << line << ": " << msg
<< std::endl;
}
}