2013-12-17 01:30:11 +04:00
|
|
|
/*============================================================================
|
|
|
|
CMake - Cross Platform Makefile Generator
|
|
|
|
Copyright 2013 Kitware, Inc.
|
|
|
|
|
|
|
|
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 "cmWIXPatchParser.h"
|
|
|
|
|
|
|
|
#include <CPack/cmCPackGenerator.h>
|
|
|
|
|
|
|
|
#include <cm_expat.h>
|
|
|
|
|
2015-10-12 22:53:08 +03:00
|
|
|
cmWIXPatchNode::Type cmWIXPatchText::type()
|
|
|
|
{
|
|
|
|
return cmWIXPatchNode::TEXT;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmWIXPatchNode::Type cmWIXPatchElement::type()
|
|
|
|
{
|
|
|
|
return cmWIXPatchNode::ELEMENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmWIXPatchNode::~cmWIXPatchNode()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-12-17 01:30:11 +04:00
|
|
|
cmWIXPatchElement::~cmWIXPatchElement()
|
|
|
|
{
|
|
|
|
for(child_list_t::iterator i = children.begin(); i != children.end(); ++i)
|
|
|
|
{
|
|
|
|
delete *i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cmWIXPatchParser::cmWIXPatchParser(
|
|
|
|
fragment_map_t& fragments, cmCPackLog* logger):
|
|
|
|
Logger(logger),
|
2013-12-20 21:12:01 +04:00
|
|
|
State(BEGIN_DOCUMENT),
|
|
|
|
Valid(true),
|
|
|
|
Fragments(fragments)
|
2013-12-17 01:30:11 +04:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-02-22 04:05:55 +04:00
|
|
|
void cmWIXPatchParser::StartElement(const std::string& name, const char **atts)
|
2013-12-17 01:30:11 +04:00
|
|
|
{
|
2013-12-20 21:12:01 +04:00
|
|
|
if(State == BEGIN_DOCUMENT)
|
2013-12-17 01:30:11 +04:00
|
|
|
{
|
2014-02-22 04:05:55 +04:00
|
|
|
if(name == "CPackWiXPatch")
|
2013-12-17 01:30:11 +04:00
|
|
|
{
|
2013-12-20 21:12:01 +04:00
|
|
|
State = BEGIN_FRAGMENTS;
|
2013-12-17 01:30:11 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ReportValidationError("Expected root element 'CPackWiXPatch'");
|
|
|
|
}
|
|
|
|
}
|
2013-12-20 21:12:01 +04:00
|
|
|
else if(State == BEGIN_FRAGMENTS)
|
2013-12-17 01:30:11 +04:00
|
|
|
{
|
2014-02-22 04:05:55 +04:00
|
|
|
if(name == "CPackWiXFragment")
|
2013-12-17 01:30:11 +04:00
|
|
|
{
|
2013-12-20 21:12:01 +04:00
|
|
|
State = INSIDE_FRAGMENT;
|
2013-12-17 01:30:11 +04:00
|
|
|
StartFragment(atts);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ReportValidationError("Expected 'CPackWixFragment' element");
|
|
|
|
}
|
|
|
|
}
|
2013-12-20 21:12:01 +04:00
|
|
|
else if(State == INSIDE_FRAGMENT)
|
2013-12-17 01:30:11 +04:00
|
|
|
{
|
2013-12-20 21:12:01 +04:00
|
|
|
cmWIXPatchElement &parent = *ElementStack.back();
|
2013-12-17 01:30:11 +04:00
|
|
|
|
2015-10-12 22:53:08 +03:00
|
|
|
cmWIXPatchElement *element = new cmWIXPatchElement;
|
|
|
|
parent.children.push_back(element);
|
|
|
|
|
|
|
|
element->name = name;
|
2013-12-17 01:30:11 +04:00
|
|
|
|
|
|
|
for(size_t i = 0; atts[i]; i += 2)
|
|
|
|
{
|
|
|
|
std::string key = atts[i];
|
|
|
|
std::string value = atts[i+1];
|
|
|
|
|
2015-10-12 22:53:08 +03:00
|
|
|
element->attributes[key] = value;
|
2013-12-17 01:30:11 +04:00
|
|
|
}
|
|
|
|
|
2015-10-12 22:53:08 +03:00
|
|
|
ElementStack.push_back(element);
|
2013-12-17 01:30:11 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cmWIXPatchParser::StartFragment(const char **attributes)
|
|
|
|
{
|
|
|
|
for(size_t i = 0; attributes[i]; i += 2)
|
|
|
|
{
|
|
|
|
std::string key = attributes[i];
|
|
|
|
std::string value = attributes[i+1];
|
|
|
|
|
|
|
|
if(key == "Id")
|
|
|
|
{
|
2013-12-20 21:12:01 +04:00
|
|
|
if(Fragments.find(value) != Fragments.end())
|
2013-12-17 01:30:11 +04:00
|
|
|
{
|
|
|
|
std::stringstream tmp;
|
|
|
|
tmp << "Invalid reuse of 'CPackWixFragment' 'Id': " << value;
|
|
|
|
ReportValidationError(tmp.str());
|
|
|
|
}
|
|
|
|
|
2013-12-20 21:12:01 +04:00
|
|
|
ElementStack.push_back(&Fragments[value]);
|
2013-12-17 01:30:11 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ReportValidationError(
|
|
|
|
"The only allowed 'CPackWixFragment' attribute is 'Id'");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-22 04:05:55 +04:00
|
|
|
void cmWIXPatchParser::EndElement(const std::string& name)
|
2013-12-17 01:30:11 +04:00
|
|
|
{
|
2013-12-20 21:12:01 +04:00
|
|
|
if(State == INSIDE_FRAGMENT)
|
2013-12-17 01:30:11 +04:00
|
|
|
{
|
2014-02-22 04:05:55 +04:00
|
|
|
if(name == "CPackWiXFragment")
|
2013-12-17 01:30:11 +04:00
|
|
|
{
|
2013-12-20 21:12:01 +04:00
|
|
|
State = BEGIN_FRAGMENTS;
|
|
|
|
ElementStack.clear();
|
2013-12-17 01:30:11 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-10-12 22:53:08 +03:00
|
|
|
ElementStack.pop_back();
|
2013-12-17 01:30:11 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-12 22:53:08 +03:00
|
|
|
void cmWIXPatchParser::CharacterDataHandler(const char* data, int length)
|
|
|
|
{
|
|
|
|
const char* whitespace = "\x20\x09\x0d\x0a";
|
|
|
|
|
|
|
|
if(State == INSIDE_FRAGMENT)
|
|
|
|
{
|
|
|
|
cmWIXPatchElement &parent = *ElementStack.back();
|
|
|
|
|
|
|
|
std::string text(data, length);
|
|
|
|
|
|
|
|
std::string::size_type first = text.find_first_not_of(whitespace);
|
|
|
|
std::string::size_type last = text.find_last_not_of(whitespace);
|
|
|
|
|
|
|
|
if(first != std::string::npos && last != std::string::npos)
|
|
|
|
{
|
|
|
|
cmWIXPatchText *text_node = new cmWIXPatchText;
|
|
|
|
text_node->text = text.substr(first, last - first + 1);
|
|
|
|
|
|
|
|
parent.children.push_back(text_node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-17 01:30:11 +04:00
|
|
|
void cmWIXPatchParser::ReportError(int line, int column, const char* msg)
|
|
|
|
{
|
|
|
|
cmCPackLogger(cmCPackLog::LOG_ERROR,
|
|
|
|
"Error while processing XML patch file at " << line << ":" << column <<
|
|
|
|
": "<< msg << std::endl);
|
2013-12-20 21:12:01 +04:00
|
|
|
Valid = false;
|
2013-12-17 01:30:11 +04:00
|
|
|
}
|
|
|
|
|
2014-02-25 02:21:12 +04:00
|
|
|
void cmWIXPatchParser::ReportValidationError(std::string const& message)
|
2013-12-17 01:30:11 +04:00
|
|
|
{
|
2015-03-26 18:56:44 +03:00
|
|
|
ReportError(XML_GetCurrentLineNumber(static_cast<XML_Parser>(this->Parser)),
|
|
|
|
XML_GetCurrentColumnNumber(static_cast<XML_Parser>(this->Parser)),
|
2013-12-17 01:30:11 +04:00
|
|
|
message.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cmWIXPatchParser::IsValid() const
|
|
|
|
{
|
2013-12-20 21:12:01 +04:00
|
|
|
return Valid;
|
2013-12-17 01:30:11 +04:00
|
|
|
}
|