summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/WindowsManifestMerger.cpp
blob: 60cddd1059698cc608c8005d0cd482cab38faa85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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
OpenPOWER on IntegriCloud