//===- ToolOutputFile.cpp -------------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include <mcld/Support/ToolOutputFile.h>
#include <mcld/Support/Path.h>
#include <mcld/Support/FileHandle.h>
#include <mcld/Support/MemoryArea.h>
#include <mcld/Support/raw_mem_ostream.h>
#include <mcld/Support/SystemUtils.h>
#include <mcld/Support/MsgHandling.h>
#include <llvm/Support/Signals.h>
#include <llvm/Support/Path.h>
#include <llvm/Support/FormattedStream.h>
using namespace mcld;
//===----------------------------------------------------------------------===//
// CleanupInstaller
//===----------------------------------------------------------------------===//
ToolOutputFile::CleanupInstaller::CleanupInstaller(const std::string& pName)
: Keep(false), m_Filename(pName) {
// Arrange for the file to be deleted if the process is killed.
if (m_Filename != "-")
llvm::sys::RemoveFileOnSignal(llvm::sys::Path(m_Filename));
}
ToolOutputFile::CleanupInstaller::~CleanupInstaller()
{
// Delete the file if the client hasn't told us not to.
if (!Keep && m_Filename != "-")
llvm::sys::Path(m_Filename).eraseFromDisk();
// Ok, the file is successfully written and closed, or deleted. There's no
// further need to clean it up on signals.
if (m_Filename != "-")
llvm::sys::DontRemoveFileOnSignal(llvm::sys::Path(m_Filename));
}
//===----------------------------------------------------------------------===//
// ToolOutputFile
//===----------------------------------------------------------------------===//
ToolOutputFile::ToolOutputFile(const sys::fs::Path& pPath,
FileHandle::OpenMode pMode,
FileHandle::Permission pPermission)
: m_Installer(pPath.native()),
m_pMemoryArea(NULL),
m_pOStream(NULL),
m_pFOStream(NULL) {
if (!m_FileHandle.open(pPath, pMode, pPermission)) {
// If open fails, no clean-up is needed.
m_Installer.Keep = true;
fatal(diag::err_cannot_open_output_file)
<< pPath
<< sys::strerror(m_FileHandle.error());
return;
}
m_pMemoryArea = new MemoryArea(m_FileHandle);
m_pOStream = new raw_mem_ostream(*m_pMemoryArea);
}
ToolOutputFile::~ToolOutputFile()
{
delete m_pFOStream;
delete m_pOStream;
delete m_pMemoryArea;
}
void ToolOutputFile::keep()
{
m_Installer.Keep = true;
}
/// mem_os - Return the contained raw_mem_ostream.
raw_mem_ostream& ToolOutputFile::mem_os()
{
assert(NULL != m_pOStream);
return *m_pOStream;
}
/// formatted_os - Return the containeed formatted_raw_ostream.
/// Since formatted_os is rarely used, we lazily initialize it.
llvm::formatted_raw_ostream& ToolOutputFile::formatted_os()
{
if (NULL == m_pFOStream) {
assert(NULL != m_pOStream);
m_pFOStream = new llvm::formatted_raw_ostream(*m_pOStream);
}
return *m_pFOStream;
}
/// memory - Return the contained MemoryArea.
MemoryArea& ToolOutputFile::memory()
{
assert(NULL != m_pOStream);
return m_pOStream->getMemoryArea();
}