diff options
Diffstat (limited to 'Source/CPack/WiX/cmWIXPatchParser.cxx')
-rw-r--r-- | Source/CPack/WiX/cmWIXPatchParser.cxx | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/Source/CPack/WiX/cmWIXPatchParser.cxx b/Source/CPack/WiX/cmWIXPatchParser.cxx new file mode 100644 index 0000000..449a70b --- /dev/null +++ b/Source/CPack/WiX/cmWIXPatchParser.cxx @@ -0,0 +1,156 @@ +/*============================================================================ + 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> + +cmWIXPatchNode::Type cmWIXPatchText::type() +{ + return cmWIXPatchNode::TEXT; +} + +cmWIXPatchNode::Type cmWIXPatchElement::type() +{ + return cmWIXPatchNode::ELEMENT; +} + +cmWIXPatchNode::~cmWIXPatchNode() +{ +} + +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) + , State(BEGIN_DOCUMENT) + , Valid(true) + , Fragments(fragments) +{ +} + +void cmWIXPatchParser::StartElement(const std::string& name, const char** atts) +{ + if (State == BEGIN_DOCUMENT) { + if (name == "CPackWiXPatch") { + State = BEGIN_FRAGMENTS; + } else { + ReportValidationError("Expected root element 'CPackWiXPatch'"); + } + } else if (State == BEGIN_FRAGMENTS) { + if (name == "CPackWiXFragment") { + State = INSIDE_FRAGMENT; + StartFragment(atts); + } else { + ReportValidationError("Expected 'CPackWixFragment' element"); + } + } else if (State == INSIDE_FRAGMENT) { + cmWIXPatchElement& parent = *ElementStack.back(); + + cmWIXPatchElement* element = new cmWIXPatchElement; + parent.children.push_back(element); + + element->name = name; + + for (size_t i = 0; atts[i]; i += 2) { + std::string key = atts[i]; + std::string value = atts[i + 1]; + + element->attributes[key] = value; + } + + ElementStack.push_back(element); + } +} + +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") { + if (Fragments.find(value) != Fragments.end()) { + std::ostringstream tmp; + tmp << "Invalid reuse of 'CPackWixFragment' 'Id': " << value; + ReportValidationError(tmp.str()); + } + + ElementStack.push_back(&Fragments[value]); + } else { + ReportValidationError( + "The only allowed 'CPackWixFragment' attribute is 'Id'"); + } + } +} + +void cmWIXPatchParser::EndElement(const std::string& name) +{ + if (State == INSIDE_FRAGMENT) { + if (name == "CPackWiXFragment") { + State = BEGIN_FRAGMENTS; + ElementStack.clear(); + } else { + ElementStack.pop_back(); + } + } +} + +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); + } + } +} + +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); + Valid = false; +} + +void cmWIXPatchParser::ReportValidationError(std::string const& message) +{ + ReportError( + XML_GetCurrentLineNumber(static_cast<XML_Parser>(this->Parser)), + XML_GetCurrentColumnNumber(static_cast<XML_Parser>(this->Parser)), + message.c_str()); +} + +bool cmWIXPatchParser::IsValid() const +{ + return Valid; +} |