Merge topic 'wix-text-node'

5a266095 CPackWIX: Handle text nodes in XML patch content
This commit is contained in:
Brad King 2015-10-14 13:36:02 -04:00 committed by CMake Topic Stage
commit 088fcbf733
6 changed files with 119 additions and 20 deletions

View File

@ -33,15 +33,32 @@ void cmWIXPatch::ApplyFragment(
if(i == Fragments.end()) return; if(i == Fragments.end()) return;
const cmWIXPatchElement& fragment = i->second; const cmWIXPatchElement& fragment = i->second;
for(cmWIXPatchElement::child_list_t::const_iterator
j = fragment.children.begin(); j != fragment.children.end(); ++j) this->ApplyElementChildren(fragment, writer);
{
ApplyElement(**j, writer);
}
Fragments.erase(i); Fragments.erase(i);
} }
void cmWIXPatch::ApplyElementChildren(
const cmWIXPatchElement& element, cmWIXSourceWriter& writer)
{
for(cmWIXPatchElement::child_list_t::const_iterator
j = element.children.begin(); j != element.children.end(); ++j)
{
cmWIXPatchNode *node = *j;
switch(node->type())
{
case cmWIXPatchNode::ELEMENT:
ApplyElement(dynamic_cast<const cmWIXPatchElement&>(*node), writer);
break;
case cmWIXPatchNode::TEXT:
writer.AddTextNode(dynamic_cast<const cmWIXPatchText&>(*node).text);
break;
}
}
}
void cmWIXPatch::ApplyElement( void cmWIXPatch::ApplyElement(
const cmWIXPatchElement& element, cmWIXSourceWriter& writer) const cmWIXPatchElement& element, cmWIXSourceWriter& writer)
{ {
@ -53,16 +70,11 @@ void cmWIXPatch::ApplyElement(
writer.AddAttribute(i->first, i->second); writer.AddAttribute(i->first, i->second);
} }
for(cmWIXPatchElement::child_list_t::const_iterator this->ApplyElementChildren(element, writer);
i = element.children.begin(); i != element.children.end(); ++i)
{
ApplyElement(**i, writer);
}
writer.EndElement(element.name); writer.EndElement(element.name);
} }
bool cmWIXPatch::CheckForUnappliedFragments() bool cmWIXPatch::CheckForUnappliedFragments()
{ {
std::string fragmentList; std::string fragmentList;

View File

@ -33,6 +33,9 @@ public:
bool CheckForUnappliedFragments(); bool CheckForUnappliedFragments();
private: private:
void ApplyElementChildren(const cmWIXPatchElement& element,
cmWIXSourceWriter& writer);
void ApplyElement(const cmWIXPatchElement& element, void ApplyElement(const cmWIXPatchElement& element,
cmWIXSourceWriter& writer); cmWIXSourceWriter& writer);

View File

@ -16,6 +16,21 @@
#include <cm_expat.h> #include <cm_expat.h>
cmWIXPatchNode::Type cmWIXPatchText::type()
{
return cmWIXPatchNode::TEXT;
}
cmWIXPatchNode::Type cmWIXPatchElement::type()
{
return cmWIXPatchNode::ELEMENT;
}
cmWIXPatchNode::~cmWIXPatchNode()
{
}
cmWIXPatchElement::~cmWIXPatchElement() cmWIXPatchElement::~cmWIXPatchElement()
{ {
for(child_list_t::iterator i = children.begin(); i != children.end(); ++i) for(child_list_t::iterator i = children.begin(); i != children.end(); ++i)
@ -63,20 +78,20 @@ void cmWIXPatchParser::StartElement(const std::string& name, const char **atts)
{ {
cmWIXPatchElement &parent = *ElementStack.back(); cmWIXPatchElement &parent = *ElementStack.back();
parent.children.resize(parent.children.size() + 1); cmWIXPatchElement *element = new cmWIXPatchElement;
cmWIXPatchElement*& currentElement = parent.children.back(); parent.children.push_back(element);
currentElement = new cmWIXPatchElement;
currentElement->name = name; element->name = name;
for(size_t i = 0; atts[i]; i += 2) for(size_t i = 0; atts[i]; i += 2)
{ {
std::string key = atts[i]; std::string key = atts[i];
std::string value = atts[i+1]; std::string value = atts[i+1];
currentElement->attributes[key] = value; element->attributes[key] = value;
} }
ElementStack.push_back(currentElement); ElementStack.push_back(element);
} }
} }
@ -117,11 +132,34 @@ void cmWIXPatchParser::EndElement(const std::string& name)
} }
else else
{ {
ElementStack.pop_back(); 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) void cmWIXPatchParser::ReportError(int line, int column, const char* msg)
{ {
cmCPackLogger(cmCPackLog::LOG_ERROR, cmCPackLogger(cmCPackLog::LOG_ERROR,

View File

@ -20,11 +20,33 @@
#include <map> #include <map>
#include <list> #include <list>
struct cmWIXPatchElement struct cmWIXPatchNode
{ {
enum Type
{
TEXT,
ELEMENT
};
virtual ~cmWIXPatchNode();
virtual Type type() = 0;
};
struct cmWIXPatchText : public cmWIXPatchNode
{
virtual Type type();
std::string text;
};
struct cmWIXPatchElement : cmWIXPatchNode
{
virtual Type type();
~cmWIXPatchElement(); ~cmWIXPatchElement();
typedef std::list<cmWIXPatchElement*> child_list_t; typedef std::list<cmWIXPatchNode*> child_list_t;
typedef std::map<std::string, std::string> attributes_t; typedef std::map<std::string, std::string> attributes_t;
std::string name; std::string name;
@ -48,6 +70,9 @@ private:
void StartFragment(const char **attributes); void StartFragment(const char **attributes);
virtual void EndElement(const std::string& name); virtual void EndElement(const std::string& name);
virtual void CharacterDataHandler(const char* data, int length);
virtual void ReportError(int line, int column, const char* msg); virtual void ReportError(int line, int column, const char* msg);
void ReportValidationError(std::string const& message); void ReportValidationError(std::string const& message);

View File

@ -102,6 +102,25 @@ void cmWIXSourceWriter::EndElement(std::string const& name)
State = DEFAULT; State = DEFAULT;
} }
void cmWIXSourceWriter::AddTextNode(std::string const& text)
{
if(State == BEGIN)
{
File << ">";
}
if(Elements.empty())
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
"can not add text without open WiX element in '" <<
SourceFilename << "'" << std::endl);
return;
}
File << this->EscapeAttributeValue(text);
State = DEFAULT;
}
void cmWIXSourceWriter::AddProcessingInstruction( void cmWIXSourceWriter::AddProcessingInstruction(
std::string const& target, std::string const& content) std::string const& target, std::string const& content)
{ {

View File

@ -34,6 +34,8 @@ public:
void EndElement(std::string const& name); void EndElement(std::string const& name);
void AddTextNode(std::string const& text);
void AddProcessingInstruction( void AddProcessingInstruction(
std::string const& target, std::string const& content); std::string const& target, std::string const& content);