diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Support/CMakeLists.txt | 4 | ||||
-rw-r--r-- | llvm/lib/Support/WindowsManifestMerger.cpp | 70 |
2 files changed, 74 insertions, 0 deletions
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt index 0a8e3897cce..e258e4df799 100644 --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -27,6 +27,9 @@ elseif( CMAKE_HOST_UNIX ) if( UNIX AND NOT (BEOS OR HAIKU) ) set(system_libs ${system_libs} m) endif() + if( LLVM_LIBXML2_ENABLED ) + set(system_libs ${system_libs} ${LIBXML2_LIBS}) + endif() endif( MSVC OR MINGW ) add_llvm_library(LLVMSupport @@ -110,6 +113,7 @@ add_llvm_library(LLVMSupport Triple.cpp Twine.cpp Unicode.cpp + WindowsManifestMerger.cpp YAMLParser.cpp YAMLTraits.cpp raw_os_ostream.cpp diff --git a/llvm/lib/Support/WindowsManifestMerger.cpp b/llvm/lib/Support/WindowsManifestMerger.cpp new file mode 100644 index 00000000000..60cddd10596 --- /dev/null +++ b/llvm/lib/Support/WindowsManifestMerger.cpp @@ -0,0 +1,70 @@ +//===-- WindowsManifestMerger.cpp ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// +// +// This file implements the .manifest merger class. +// +//===---------------------------------------------------------------------===// + +#include "llvm/Support/WindowsManifestMerger.h" +#include "llvm/Support/MemoryBuffer.h" + +#include <stdarg.h> + +namespace llvm { + +char WindowsManifestError::ID = 0; + +WindowsManifestError::WindowsManifestError(const Twine &Msg) : Msg(Msg.str()) {} + +void WindowsManifestError::log(raw_ostream &OS) const { OS << Msg; } + +Error WindowsManifestMerger::merge(const MemoryBuffer &Manifest) { +#if LLVM_LIBXML2_ENABLED + xmlSetGenericErrorFunc((void *)this, WindowsManifestMerger::errorCallback); + XMLDocumentImpl ManifestXML = + xmlReadMemory(Manifest.getBufferStart(), Manifest.getBufferSize(), + "manifest.xml", nullptr, 0); + xmlSetGenericErrorFunc(nullptr, nullptr); + if (auto E = getParseError()) + return E; + CombinedRoot = xmlDocGetRootElement(ManifestXML); +#endif + return Error::success(); +} + +std::unique_ptr<MemoryBuffer> WindowsManifestMerger::getMergedManifest() { +#if LLVM_LIBXML2_ENABLED + unsigned char *XmlBuff; + int BufferSize = 0; + if (CombinedRoot) { + std::unique_ptr<xmlDoc> OutputDoc(xmlNewDoc((const unsigned char *)"1.0")); + xmlDocSetRootElement(OutputDoc.get(), CombinedRoot); + xmlDocDumpMemory(OutputDoc.get(), &XmlBuff, &BufferSize); + } + if (BufferSize == 0) + return nullptr; + return MemoryBuffer::getMemBuffer( + StringRef(reinterpret_cast<const char *>(XmlBuff), (size_t)BufferSize)); +#else + return nullptr; +#endif +} + +void WindowsManifestMerger::errorCallback(void *Ctx, const char *Format, ...) { + auto *Merger = (WindowsManifestMerger *)Ctx; + Merger->ParseErrorOccurred = true; +} + +Error WindowsManifestMerger::getParseError() { + if (!ParseErrorOccurred) + return Error::success(); + return make_error<WindowsManifestError>("invalid xml document"); +} + +} // namespace llvm |