summaryrefslogtreecommitdiffstats
path: root/Source/CPack/WiX
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CPack/WiX')
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.cxx37
-rw-r--r--Source/CPack/WiX/cmCPackWIXGenerator.h3
-rw-r--r--Source/CPack/WiX/cmWIXPatch.cxx44
-rw-r--r--Source/CPack/WiX/cmWIXPatch.h5
-rw-r--r--Source/CPack/WiX/cmWIXPatchParser.cxx52
-rw-r--r--Source/CPack/WiX/cmWIXPatchParser.h29
-rw-r--r--Source/CPack/WiX/cmWIXSourceWriter.cxx19
-rw-r--r--Source/CPack/WiX/cmWIXSourceWriter.h2
8 files changed, 164 insertions, 27 deletions
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index 6f25e50..ece327a 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -242,7 +242,16 @@ bool cmCPackWIXGenerator::InitializeWiXConfiguration()
const char* patchFilePath = GetOption("CPACK_WIX_PATCH_FILE");
if(patchFilePath)
{
- this->Patch->LoadFragments(patchFilePath);
+ std::vector<std::string> patchFilePaths;
+ cmSystemTools::ExpandListArgument(patchFilePath, patchFilePaths);
+
+ for(size_t i = 0; i < patchFilePaths.size(); ++i)
+ {
+ if(!this->Patch->LoadFragments(patchFilePaths[i]))
+ {
+ return false;
+ }
+ }
}
return true;
@@ -482,6 +491,7 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
featureDefinitions.BeginElement("Feature");
featureDefinitions.AddAttribute("Id", "ProductFeature");
featureDefinitions.AddAttribute("Display", "expand");
+ featureDefinitions.AddAttribute("Absent", "disallow");
featureDefinitions.AddAttribute("ConfigurableDirectory", "INSTALL_ROOT");
std::string cpackPackageName;
@@ -816,6 +826,8 @@ bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType(
fileDefinitions.AddAttribute("Id", componentId);
fileDefinitions.AddAttribute("Guid", "*");
+ this->Patch->ApplyFragment(componentId, fileDefinitions);
+
std::string registryKey = std::string("Software\\") +
cpackVendor + "\\" + cpackPackageName;
@@ -910,8 +922,9 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
relativeDirectoryPath = ".";
}
- cmInstalledFile const* directoryInstalledFile =
- this->GetInstalledFile(relativeDirectoryPath);
+ cmInstalledFile const* directoryInstalledFile = this->GetInstalledFile(
+ this->RelativePathWithoutComponentPrefix(relativeDirectoryPath)
+ );
bool emptyDirectory = dir.GetNumberOfFiles() == 2;
bool createDirectory = false;
@@ -979,8 +992,9 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
}
else
{
- cmInstalledFile const* installedFile =
- this->GetInstalledFile(relativePath);
+ cmInstalledFile const* installedFile = this->GetInstalledFile(
+ this->RelativePathWithoutComponentPrefix(relativePath)
+ );
if(installedFile)
{
@@ -1229,3 +1243,16 @@ void cmCPackWIXGenerator::AddCustomFlags(
stream << " " << QuotePath(*i);
}
}
+
+std::string cmCPackWIXGenerator::RelativePathWithoutComponentPrefix(
+ std::string const& path)
+{
+ if(this->Components.empty())
+ {
+ return path;
+ }
+
+ std::string::size_type pos = path.find('/');
+
+ return path.substr(pos + 1);
+}
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h
index d501609..3f66b2c 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.h
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.h
@@ -168,6 +168,9 @@ private:
void AddCustomFlags(
std::string const& variableName, std::ostream& stream);
+ std::string RelativePathWithoutComponentPrefix(
+ std::string const& path);
+
std::vector<std::string> WixSources;
id_map_t PathToIdMap;
ambiguity_map_t IdAmbiguityCounter;
diff --git a/Source/CPack/WiX/cmWIXPatch.cxx b/Source/CPack/WiX/cmWIXPatch.cxx
index 5a8dc63..07375da 100644
--- a/Source/CPack/WiX/cmWIXPatch.cxx
+++ b/Source/CPack/WiX/cmWIXPatch.cxx
@@ -20,10 +20,18 @@ cmWIXPatch::cmWIXPatch(cmCPackLog* logger):
}
-void cmWIXPatch::LoadFragments(std::string const& patchFilePath)
+bool cmWIXPatch::LoadFragments(std::string const& patchFilePath)
{
cmWIXPatchParser parser(Fragments, Logger);
- parser.ParseFile(patchFilePath.c_str());
+ if(!parser.ParseFile(patchFilePath.c_str()))
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR,
+ "Failed parsing XML patch file: '" <<
+ patchFilePath << "'" << std::endl);
+ return false;
+ }
+
+ return true;
}
void cmWIXPatch::ApplyFragment(
@@ -33,13 +41,30 @@ void cmWIXPatch::ApplyFragment(
if(i == Fragments.end()) return;
const cmWIXPatchElement& fragment = i->second;
+
+ this->ApplyElementChildren(fragment, writer);
+
+ Fragments.erase(i);
+}
+
+void cmWIXPatch::ApplyElementChildren(
+ const cmWIXPatchElement& element, cmWIXSourceWriter& writer)
+{
for(cmWIXPatchElement::child_list_t::const_iterator
- j = fragment.children.begin(); j != fragment.children.end(); ++j)
+ j = element.children.begin(); j != element.children.end(); ++j)
+ {
+ cmWIXPatchNode *node = *j;
+
+ switch(node->type())
{
- ApplyElement(**j, writer);
+ case cmWIXPatchNode::ELEMENT:
+ ApplyElement(dynamic_cast<const cmWIXPatchElement&>(*node), writer);
+ break;
+ case cmWIXPatchNode::TEXT:
+ writer.AddTextNode(dynamic_cast<const cmWIXPatchText&>(*node).text);
+ break;
}
-
- Fragments.erase(i);
+ }
}
void cmWIXPatch::ApplyElement(
@@ -53,16 +78,11 @@ void cmWIXPatch::ApplyElement(
writer.AddAttribute(i->first, i->second);
}
- for(cmWIXPatchElement::child_list_t::const_iterator
- i = element.children.begin(); i != element.children.end(); ++i)
- {
- ApplyElement(**i, writer);
- }
+ this->ApplyElementChildren(element, writer);
writer.EndElement(element.name);
}
-
bool cmWIXPatch::CheckForUnappliedFragments()
{
std::string fragmentList;
diff --git a/Source/CPack/WiX/cmWIXPatch.h b/Source/CPack/WiX/cmWIXPatch.h
index 7b7b2f1..2f31a01 100644
--- a/Source/CPack/WiX/cmWIXPatch.h
+++ b/Source/CPack/WiX/cmWIXPatch.h
@@ -26,13 +26,16 @@ class cmWIXPatch
public:
cmWIXPatch(cmCPackLog* logger);
- void LoadFragments(std::string const& patchFilePath);
+ bool LoadFragments(std::string const& patchFilePath);
void ApplyFragment(std::string const& id, cmWIXSourceWriter& writer);
bool CheckForUnappliedFragments();
private:
+ void ApplyElementChildren(const cmWIXPatchElement& element,
+ cmWIXSourceWriter& writer);
+
void ApplyElement(const cmWIXPatchElement& element,
cmWIXSourceWriter& writer);
diff --git a/Source/CPack/WiX/cmWIXPatchParser.cxx b/Source/CPack/WiX/cmWIXPatchParser.cxx
index e066c28..14c5413 100644
--- a/Source/CPack/WiX/cmWIXPatchParser.cxx
+++ b/Source/CPack/WiX/cmWIXPatchParser.cxx
@@ -16,6 +16,21 @@
#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)
@@ -63,20 +78,20 @@ void cmWIXPatchParser::StartElement(const std::string& name, const char **atts)
{
cmWIXPatchElement &parent = *ElementStack.back();
- parent.children.resize(parent.children.size() + 1);
- cmWIXPatchElement*& currentElement = parent.children.back();
- currentElement = new cmWIXPatchElement;
- currentElement->name = name;
+ 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];
- 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
{
- 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)
{
cmCPackLogger(cmCPackLog::LOG_ERROR,
diff --git a/Source/CPack/WiX/cmWIXPatchParser.h b/Source/CPack/WiX/cmWIXPatchParser.h
index acfb4c0..acaeae3 100644
--- a/Source/CPack/WiX/cmWIXPatchParser.h
+++ b/Source/CPack/WiX/cmWIXPatchParser.h
@@ -20,11 +20,33 @@
#include <map>
#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();
- typedef std::list<cmWIXPatchElement*> child_list_t;
+ typedef std::list<cmWIXPatchNode*> child_list_t;
typedef std::map<std::string, std::string> attributes_t;
std::string name;
@@ -48,6 +70,9 @@ private:
void StartFragment(const char **attributes);
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);
void ReportValidationError(std::string const& message);
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx
index 8d38e9b..63acb27 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx
@@ -102,6 +102,25 @@ void cmWIXSourceWriter::EndElement(std::string const& name)
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(
std::string const& target, std::string const& content)
{
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.h b/Source/CPack/WiX/cmWIXSourceWriter.h
index 3b9999c..9e303f0 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXSourceWriter.h
@@ -34,6 +34,8 @@ public:
void EndElement(std::string const& name);
+ void AddTextNode(std::string const& text);
+
void AddProcessingInstruction(
std::string const& target, std::string const& content);