/*========================================================================= Program: CMake - Cross-Platform Makefile Generator Module: $RCSfile$ Language: C++ Date: $Date$ Version: $Revision$ Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef cmGeneratedFileStream_h #define cmGeneratedFileStream_h #include "cmStandardIncludes.h" /** \class cmGeneratedFileStream * \brief Output stream for generated files that does copy-if-different. * * Many files generated by CMake don't change each time they are generated. * This class can be used in place of std::ofstream to open a file and * write output to it. The class will automatically write output to a * temporary file and copy it over an existing file only if the generated * file has changed. */ class cmGeneratedFileStream { public: /** * The constructor takes the name of the file to be generated. It * automatically generates a name for the temporary file. */ cmGeneratedFileStream(const char* name): m_Name(name), m_TempName(m_Name+".tmp"), m_Stream(m_TempName.c_str()), m_Copied(false), m_AlwaysCopy(false) {} /** * The destructor ensures that the file has been closed and copied if * it has changed. */ ~cmGeneratedFileStream() { this->DoCopy(); } /** * Get the real output stream. */ std::ostream& GetStream() { return m_Stream; } /** * Allow a test for whether the file is open. */ operator bool() { return m_Stream.good(); } /** * Close the file stream. This will cause the copy-if-different to the * real file name to occur. */ void close() { this->DoCopy(); } /** * If always copy is true, then copy the file all the time without * checking for differences. The default is false. */ bool SetAlwaysCopy(bool v) { m_AlwaysCopy = v; return v;} private: /** * The name of the real file where output will be copied if it has changed. */ std::string m_Name; /** * The name of the temporary file. */ std::string m_TempName; /** * The real output stream used to write to the file. */ std::ofstream m_Stream; /** * Whether the temporary file has already been copied to the real file. */ bool m_Copied; /** * If always copy is true, then copy the file all the time without * checking for differences. The default is false. */ bool m_AlwaysCopy; /** * Closes the temporary file and does the copy-if-different to the * real file. */ void DoCopy() { if(!m_Copied) { m_Stream.close(); if(m_AlwaysCopy) { cmSystemTools::cmCopyFile(m_TempName.c_str(), m_Name.c_str()); } else { cmSystemTools::CopyFileIfDifferent(m_TempName.c_str(), m_Name.c_str()); } cmSystemTools::RemoveFile(m_TempName.c_str()); m_Copied = true; } } }; /** * Allow a cmGeneratedFileStream to be used just as a real std::ostream * would be. */ template std::ostream& operator << (cmGeneratedFileStream& l, const T& r) { std::ostream& os = l.GetStream(); os << r; return os; } #endif