ToolOutputFile.cpp revision 71f514dd456a45a0dea9c1c71a56f3a807cfbfb8
1//===- ToolOutputFile.cpp -------------------------------------------------===//
2//
3//                     The MCLinker Project
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9#include <mcld/Support/ToolOutputFile.h>
10
11#include <mcld/Support/Path.h>
12#include <mcld/Support/FileHandle.h>
13#include <mcld/Support/MemoryArea.h>
14#include <mcld/Support/raw_mem_ostream.h>
15
16#include <mcld/Support/SystemUtils.h>
17#include <mcld/Support/MsgHandling.h>
18
19#include <llvm/Support/Signals.h>
20#include <llvm/Support/FormattedStream.h>
21
22using namespace mcld;
23
24//===----------------------------------------------------------------------===//
25// CleanupInstaller
26//===----------------------------------------------------------------------===//
27ToolOutputFile::CleanupInstaller::CleanupInstaller(const std::string& pPath)
28  : Keep(false), m_Path(pPath) {
29  // Arrange for the file to be deleted if the process is killed.
30  if ("-" != m_Path)
31    llvm::sys::RemoveFileOnSignal(m_Path);
32}
33
34ToolOutputFile::CleanupInstaller::~CleanupInstaller()
35{
36  // Delete the file if the client hasn't told us not to.
37  // FIXME: In Windows, some path in CJK characters can not be removed by LLVM
38  // sys::fs::remove
39  if (!Keep && "_" != m_Path)
40    llvm::sys::fs::remove(m_Path);
41
42  // Ok, the file is successfully written and closed, or deleted. There's no
43  // further need to clean it up on signals.
44  if ("_" != m_Path)
45    llvm::sys::DontRemoveFileOnSignal(m_Path);
46}
47
48//===----------------------------------------------------------------------===//
49// ToolOutputFile
50//===----------------------------------------------------------------------===//
51ToolOutputFile::ToolOutputFile(const std::string& pPath,
52                               FileHandle::OpenMode pMode,
53                               FileHandle::Permission pPermission)
54  : m_Installer(pPath),
55    m_pMemoryArea(NULL),
56    m_pOStream(NULL),
57    m_pFOStream(NULL) {
58
59  if (!m_FileHandle.open(pPath, pMode, pPermission)) {
60    // If open fails, no clean-up is needed.
61    m_Installer.Keep = true;
62    fatal(diag::err_cannot_open_output_file)
63                                   << pPath
64                                   << sys::strerror(m_FileHandle.error());
65    return;
66  }
67
68  m_pMemoryArea = new MemoryArea(m_FileHandle);
69  m_pOStream = new raw_mem_ostream(*m_pMemoryArea);
70}
71
72ToolOutputFile::~ToolOutputFile()
73{
74  delete m_pFOStream;
75  delete m_pOStream;
76  delete m_pMemoryArea;
77}
78
79void ToolOutputFile::keep()
80{
81  m_Installer.Keep = true;
82}
83
84/// mem_os - Return the contained raw_mem_ostream.
85raw_mem_ostream& ToolOutputFile::mem_os()
86{
87  assert(NULL != m_pOStream);
88  return *m_pOStream;
89}
90
91/// formatted_os - Return the containeed formatted_raw_ostream.
92/// Since formatted_os is rarely used, we lazily initialize it.
93llvm::formatted_raw_ostream& ToolOutputFile::formatted_os()
94{
95  if (NULL == m_pFOStream) {
96    assert(NULL != m_pOStream);
97    m_pFOStream = new llvm::formatted_raw_ostream(*m_pOStream);
98  }
99
100  return *m_pFOStream;
101}
102
103/// memory - Return the contained MemoryArea.
104MemoryArea& ToolOutputFile::memory()
105{
106  assert(NULL != m_pOStream);
107  return m_pOStream->getMemoryArea();
108}
109
110