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 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 
     35 ToolOutputFile::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 //===----------------------------------------------------------------------===//
     52 ToolOutputFile::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 
     73 ToolOutputFile::~ToolOutputFile()
     74 {
     75   delete m_pFOStream;
     76   delete m_pOStream;
     77   delete m_pMemoryArea;
     78 }
     79 
     80 void ToolOutputFile::keep()
     81 {
     82   m_Installer.Keep = true;
     83 }
     84 
     85 /// mem_os - Return the contained raw_mem_ostream.
     86 raw_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.
     94 llvm::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.
    105 MemoryArea& ToolOutputFile::memory()
    106 {
    107   assert(NULL != m_pOStream);
    108   return m_pOStream->getMemoryArea();
    109 }
    110 
    111