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