From 035c7fabc3b82cbc9a346c11abe2e9462b4c0379 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 30 Oct 2012 15:39:57 -0700 Subject: Imported Upstream version 2.8.9 --- Source/cmGeneratedFileStream.cxx | 260 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 Source/cmGeneratedFileStream.cxx (limited to 'Source/cmGeneratedFileStream.cxx') 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 +#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(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; +} -- cgit v1.2.3