summaryrefslogtreecommitdiff
path: root/Source/cmGeneratedFileStream.cxx
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2012-10-30 15:39:57 -0700
committerAnas Nashif <anas.nashif@intel.com>2012-10-30 15:39:57 -0700
commit035c7fabc3b82cbc9a346c11abe2e9462b4c0379 (patch)
tree7e40f5a790eae329a8c5d3e59f046451767956ff /Source/cmGeneratedFileStream.cxx
downloadcmake-035c7fabc3b82cbc9a346c11abe2e9462b4c0379.tar.gz
cmake-035c7fabc3b82cbc9a346c11abe2e9462b4c0379.tar.bz2
cmake-035c7fabc3b82cbc9a346c11abe2e9462b4c0379.zip
Imported Upstream version 2.8.9upstream/2.8.9
Diffstat (limited to 'Source/cmGeneratedFileStream.cxx')
-rw-r--r--Source/cmGeneratedFileStream.cxx260
1 files changed, 260 insertions, 0 deletions
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
new file mode 100644
index 000000000..1a391ede9
--- /dev/null
+++ b/Source/cmGeneratedFileStream.cxx
@@ -0,0 +1,260 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "cmGeneratedFileStream.h"
+
+#include "cmSystemTools.h"
+
+#if defined(CMAKE_BUILD_WITH_CMAKE)
+# include <cm_zlib.h>
+#endif
+
+//----------------------------------------------------------------------------
+cmGeneratedFileStream::cmGeneratedFileStream():
+ cmGeneratedFileStreamBase(), Stream()
+{
+}
+
+//----------------------------------------------------------------------------
+cmGeneratedFileStream::cmGeneratedFileStream(const char* name, bool quiet):
+ cmGeneratedFileStreamBase(name),
+ Stream(TempName.c_str())
+{
+ // Check if the file opened.
+ if(!*this && !quiet)
+ {
+ cmSystemTools::Error("Cannot open file for write: ",
+ this->TempName.c_str());
+ cmSystemTools::ReportLastSystemError("");
+ }
+}
+
+//----------------------------------------------------------------------------
+cmGeneratedFileStream::~cmGeneratedFileStream()
+{
+ // This is the first destructor called. Check the status of the
+ // stream and give the information to the private base. Next the
+ // stream will be destroyed which will close the temporary file.
+ // Finally the base destructor will be called to replace the
+ // destination file.
+ this->Okay = (*this)?true:false;
+}
+
+//----------------------------------------------------------------------------
+cmGeneratedFileStream&
+cmGeneratedFileStream::Open(const char* name, bool quiet, bool binaryFlag)
+{
+ // Store the file name and construct the temporary file name.
+ this->cmGeneratedFileStreamBase::Open(name);
+
+ // Open the temporary output file.
+ if ( binaryFlag )
+ {
+ this->Stream::open(this->TempName.c_str(),
+ std::ios::out | std::ios::binary);
+ }
+ else
+ {
+ this->Stream::open(this->TempName.c_str(), std::ios::out);
+ }
+
+ // Check if the file opened.
+ if(!*this && !quiet)
+ {
+ cmSystemTools::Error("Cannot open file for write: ",
+ this->TempName.c_str());
+ cmSystemTools::ReportLastSystemError("");
+ }
+ return *this;
+}
+
+//----------------------------------------------------------------------------
+bool
+cmGeneratedFileStream::Close()
+{
+ // Save whether the temporary output file is valid before closing.
+ this->Okay = (*this)?true:false;
+
+ // Close the temporary output file.
+ this->Stream::close();
+
+ // Remove the temporary file (possibly by renaming to the real file).
+ return this->cmGeneratedFileStreamBase::Close();
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratedFileStream::SetCopyIfDifferent(bool copy_if_different)
+{
+ this->CopyIfDifferent = copy_if_different;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratedFileStream::SetCompression(bool compression)
+{
+ this->Compress = compression;
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratedFileStream::SetCompressionExtraExtension(bool ext)
+{
+ this->CompressExtraExtension = ext;
+}
+
+//----------------------------------------------------------------------------
+cmGeneratedFileStreamBase::cmGeneratedFileStreamBase():
+ Name(),
+ TempName(),
+ CopyIfDifferent(false),
+ Okay(false),
+ Compress(false),
+ CompressExtraExtension(true)
+{
+}
+
+//----------------------------------------------------------------------------
+cmGeneratedFileStreamBase::cmGeneratedFileStreamBase(const char* name):
+ Name(),
+ TempName(),
+ CopyIfDifferent(false),
+ Okay(false),
+ Compress(false),
+ CompressExtraExtension(true)
+{
+ this->Open(name);
+}
+
+//----------------------------------------------------------------------------
+cmGeneratedFileStreamBase::~cmGeneratedFileStreamBase()
+{
+ this->Close();
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratedFileStreamBase::Open(const char* name)
+{
+ // Save the original name of the file.
+ this->Name = name;
+
+ // Create the name of the temporary file.
+ this->TempName = name;
+#if defined(__VMS)
+ this->TempName += "_tmp";
+#else
+ this->TempName += ".tmp";
+#endif
+
+ // Make sure the temporary file that will be used is not present.
+ cmSystemTools::RemoveFile(this->TempName.c_str());
+
+ std::string dir = cmSystemTools::GetFilenamePath(this->TempName);
+ cmSystemTools::MakeDirectory(dir.c_str());
+}
+
+//----------------------------------------------------------------------------
+bool cmGeneratedFileStreamBase::Close()
+{
+ bool replaced = false;
+
+ std::string resname = this->Name;
+ if ( this->Compress && this->CompressExtraExtension )
+ {
+ resname += ".gz";
+ }
+
+ // Only consider replacing the destination file if no error
+ // occurred.
+ if(!this->Name.empty() &&
+ this->Okay &&
+ (!this->CopyIfDifferent ||
+ cmSystemTools::FilesDiffer(this->TempName.c_str(), resname.c_str())))
+ {
+ // The destination is to be replaced. Rename the temporary to the
+ // destination atomically.
+ if ( this->Compress )
+ {
+ std::string gzname = this->TempName + ".temp.gz";
+ if ( this->CompressFile(this->TempName.c_str(), gzname.c_str()) )
+ {
+ this->RenameFile(gzname.c_str(), resname.c_str());
+ }
+ cmSystemTools::RemoveFile(gzname.c_str());
+ }
+ else
+ {
+ this->RenameFile(this->TempName.c_str(), resname.c_str());
+ }
+
+ replaced = true;
+ }
+
+ // Else, the destination was not replaced.
+ //
+ // Always delete the temporary file. We never want it to stay around.
+ cmSystemTools::RemoveFile(this->TempName.c_str());
+
+ return replaced;
+}
+
+//----------------------------------------------------------------------------
+#ifdef CMAKE_BUILD_WITH_CMAKE
+int cmGeneratedFileStreamBase::CompressFile(const char* oldname,
+ const char* newname)
+{
+ gzFile gf = gzopen(newname, "w");
+ if ( !gf )
+ {
+ return 0;
+ }
+ FILE* ifs = fopen(oldname, "r");
+ if ( !ifs )
+ {
+ return 0;
+ }
+ size_t res;
+ const size_t BUFFER_SIZE = 1024;
+ char buffer[BUFFER_SIZE];
+ while ( (res = fread(buffer, 1, BUFFER_SIZE, ifs)) > 0 )
+ {
+ if ( !gzwrite(gf, buffer, static_cast<int>(res)) )
+ {
+ fclose(ifs);
+ gzclose(gf);
+ return 0;
+ }
+ }
+ fclose(ifs);
+ gzclose(gf);
+ return 1;
+}
+#else
+int cmGeneratedFileStreamBase::CompressFile(const char*, const char*)
+{
+ return 0;
+}
+#endif
+
+//----------------------------------------------------------------------------
+int cmGeneratedFileStreamBase::RenameFile(const char* oldname,
+ const char* newname)
+{
+ return cmSystemTools::RenameFile(oldname, newname);
+}
+
+//----------------------------------------------------------------------------
+void cmGeneratedFileStream::SetName(const char* fname)
+{
+ if ( !fname )
+ {
+ this->Name = "";
+ return;
+ }
+ this->Name = fname;
+}