cmake/Source/CPack/WiX/cmWIXSourceWriter.cxx

186 lines
4.3 KiB
C++
Raw Normal View History

2016-10-30 18:24:19 +01:00
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
2013-03-16 19:13:01 +02:00
#include "cmWIXSourceWriter.h"
2020-02-01 23:06:01 +01:00
#include <windows.h>
2013-03-16 19:13:01 +02:00
2020-02-01 23:06:01 +01:00
#include "cmCPackGenerator.h"
2023-12-07 09:12:54 +01:00
#include "cmCryptoHash.h"
2017-07-20 19:35:53 +02:00
#include "cmUuid.h"
2016-10-30 18:24:19 +01:00
2013-03-16 19:13:01 +02:00
cmWIXSourceWriter::cmWIXSourceWriter(cmCPackLog* logger,
2016-07-09 11:21:54 +02:00
std::string const& filename,
2016-10-30 18:24:19 +01:00
GuidType componentGuidType,
RootElementType rootElementType)
2016-07-09 11:21:54 +02:00
: Logger(logger)
, File(filename.c_str())
, State(DEFAULT)
, SourceFilename(filename)
2016-10-30 18:24:19 +01:00
, ComponentGuidType(componentGuidType)
2013-03-16 19:13:01 +02:00
{
WriteXMLDeclaration();
2016-10-30 18:24:19 +01:00
if (rootElementType == INCLUDE_ELEMENT_ROOT) {
2013-03-16 19:13:01 +02:00
BeginElement("Include");
2016-07-09 11:21:54 +02:00
} else {
2013-03-16 19:13:01 +02:00
BeginElement("Wix");
2016-07-09 11:21:54 +02:00
}
2013-03-16 19:13:01 +02:00
AddAttribute("xmlns", "http://schemas.microsoft.com/wix/2006/wi");
}
cmWIXSourceWriter::~cmWIXSourceWriter()
{
2016-07-09 11:21:54 +02:00
if (Elements.size() > 1) {
2018-08-09 18:06:22 +02:00
cmCPackLogger(cmCPackLog::LOG_ERROR,
Elements.size() - 1
2016-07-09 11:21:54 +02:00
<< " WiX elements were still open when closing '"
2023-12-07 09:12:54 +01:00
<< SourceFilename << '\'' << std::endl);
2014-08-03 19:52:23 +02:00
return;
2016-07-09 11:21:54 +02:00
}
2014-08-03 19:52:23 +02:00
EndElement(Elements.back());
2013-03-16 19:13:01 +02:00
}
2015-04-27 22:25:09 +02:00
void cmWIXSourceWriter::BeginElement(std::string const& name)
2013-03-16 19:13:01 +02:00
{
2016-07-09 11:21:54 +02:00
if (State == BEGIN) {
2023-12-07 09:12:54 +01:00
File << '>';
2016-07-09 11:21:54 +02:00
}
2013-03-16 19:13:01 +02:00
2023-12-07 09:12:54 +01:00
File << '\n';
2014-08-03 19:52:23 +02:00
Indent(Elements.size());
2023-12-07 09:12:54 +01:00
File << '<' << name;
2013-03-16 19:13:01 +02:00
2014-08-03 19:52:23 +02:00
Elements.push_back(name);
State = BEGIN;
2013-03-16 19:13:01 +02:00
}
2014-08-03 19:52:23 +02:00
void cmWIXSourceWriter::EndElement(std::string const& name)
2013-03-16 19:13:01 +02:00
{
2016-07-09 11:21:54 +02:00
if (Elements.empty()) {
2014-08-03 19:52:23 +02:00
cmCPackLogger(cmCPackLog::LOG_ERROR,
2016-07-09 11:21:54 +02:00
"can not end WiX element with no open elements in '"
2023-12-07 09:12:54 +01:00
<< SourceFilename << '\'' << std::endl);
2014-08-03 19:52:23 +02:00
return;
2016-07-09 11:21:54 +02:00
}
2014-08-03 19:52:23 +02:00
2016-07-09 11:21:54 +02:00
if (Elements.back() != name) {
2018-08-09 18:06:22 +02:00
cmCPackLogger(cmCPackLog::LOG_ERROR,
"WiX element <"
2016-07-09 11:21:54 +02:00
<< Elements.back() << "> can not be closed by </" << name
2023-12-07 09:12:54 +01:00
<< "> in '" << SourceFilename << '\'' << std::endl);
2013-03-16 19:13:01 +02:00
return;
2016-07-09 11:21:54 +02:00
}
2013-03-16 19:13:01 +02:00
2016-07-09 11:21:54 +02:00
if (State == DEFAULT) {
2023-12-07 09:12:54 +01:00
File << '\n';
2016-07-09 11:21:54 +02:00
Indent(Elements.size() - 1);
2023-12-07 09:12:54 +01:00
File << "</" << Elements.back() << '>';
2016-07-09 11:21:54 +02:00
} else {
2014-08-03 19:52:23 +02:00
File << "/>";
2016-07-09 11:21:54 +02:00
}
2013-03-16 19:13:01 +02:00
2014-08-03 19:52:23 +02:00
Elements.pop_back();
State = DEFAULT;
2013-03-16 19:13:01 +02:00
}
2016-03-13 13:35:51 +01:00
void cmWIXSourceWriter::AddTextNode(std::string const& text)
{
2016-07-09 11:21:54 +02:00
if (State == BEGIN) {
2023-12-07 09:12:54 +01:00
File << '>';
2016-07-09 11:21:54 +02:00
}
2016-03-13 13:35:51 +01:00
2016-07-09 11:21:54 +02:00
if (Elements.empty()) {
2016-03-13 13:35:51 +01:00
cmCPackLogger(cmCPackLog::LOG_ERROR,
2016-07-09 11:21:54 +02:00
"can not add text without open WiX element in '"
2023-12-07 09:12:54 +01:00
<< SourceFilename << '\'' << std::endl);
2016-03-13 13:35:51 +01:00
return;
2016-07-09 11:21:54 +02:00
}
2016-03-13 13:35:51 +01:00
2023-12-07 09:12:54 +01:00
File << cmWIXSourceWriter::EscapeAttributeValue(text);
2016-03-13 13:35:51 +01:00
State = DEFAULT;
}
2016-07-09 11:21:54 +02:00
void cmWIXSourceWriter::AddProcessingInstruction(std::string const& target,
std::string const& content)
2013-03-16 19:13:01 +02:00
{
2016-07-09 11:21:54 +02:00
if (State == BEGIN) {
2023-12-07 09:12:54 +01:00
File << '>';
2016-07-09 11:21:54 +02:00
}
2013-03-16 19:13:01 +02:00
2023-12-07 09:12:54 +01:00
File << '\n';
2014-08-03 19:52:23 +02:00
Indent(Elements.size());
2023-12-07 09:12:54 +01:00
File << "<?" << target << ' ' << content << "?>";
2013-03-16 19:13:01 +02:00
2014-08-03 19:52:23 +02:00
State = DEFAULT;
2013-03-16 19:13:01 +02:00
}
2016-07-09 11:21:54 +02:00
void cmWIXSourceWriter::AddAttribute(std::string const& key,
std::string const& value)
2013-03-16 19:13:01 +02:00
{
2023-12-07 09:12:54 +01:00
File << ' ' << key << "=\"" << EscapeAttributeValue(value) << '"';
2014-08-03 19:52:23 +02:00
}
2016-07-09 11:21:54 +02:00
void cmWIXSourceWriter::AddAttributeUnlessEmpty(std::string const& key,
std::string const& value)
2014-08-03 19:52:23 +02:00
{
2016-07-09 11:21:54 +02:00
if (!value.empty()) {
2014-08-03 19:52:23 +02:00
AddAttribute(key, value);
2016-07-09 11:21:54 +02:00
}
2013-03-16 19:13:01 +02:00
}
2016-10-30 18:24:19 +01:00
std::string cmWIXSourceWriter::CreateGuidFromComponentId(
std::string const& componentId)
{
std::string guid = "*";
if (this->ComponentGuidType == CMAKE_GENERATED_GUID) {
2023-12-07 09:12:54 +01:00
cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
std::string md5 = hasher.HashString(componentId);
2016-10-30 18:24:19 +01:00
cmUuid uuid;
std::vector<unsigned char> ns;
guid = uuid.FromMd5(ns, md5);
}
return guid;
}
2013-03-16 19:13:01 +02:00
void cmWIXSourceWriter::WriteXMLDeclaration()
{
2023-12-07 09:12:54 +01:00
File << R"(<?xml version="1.0" encoding="UTF-8"?>)" << std::endl;
2013-03-16 19:13:01 +02:00
}
void cmWIXSourceWriter::Indent(size_t count)
{
2016-07-09 11:21:54 +02:00
for (size_t i = 0; i < count; ++i) {
2014-08-03 19:52:23 +02:00
File << " ";
2016-07-09 11:21:54 +02:00
}
2013-03-16 19:13:01 +02:00
}
2016-07-09 11:21:54 +02:00
std::string cmWIXSourceWriter::EscapeAttributeValue(std::string const& value)
2013-03-16 19:13:01 +02:00
{
std::string result;
result.reserve(value.size());
2018-01-26 17:06:56 +01:00
for (char c : value) {
2016-07-09 11:21:54 +02:00
switch (c) {
case '<':
result += "&lt;";
break;
case '>':
result += "&gt;";
break;
case '&':
result += "&amp;";
break;
case '"':
result += "&quot;";
break;
default:
result += c;
break;
}
}
2013-03-16 19:13:01 +02:00
return result;
}