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