cmGeneratedFileStream.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*=========================================================================
  2. Program: CMake - Cross-Platform Makefile Generator
  3. Module: $RCSfile$
  4. Language: C++
  5. Date: $Date$
  6. Version: $Revision$
  7. Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
  8. See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
  9. This software is distributed WITHOUT ANY WARRANTY; without even
  10. the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  11. PURPOSE. See the above copyright notices for more information.
  12. =========================================================================*/
  13. #ifndef cmGeneratedFileStream_h
  14. #define cmGeneratedFileStream_h
  15. #include "cmStandardIncludes.h"
  16. /** \class cmGeneratedFileStream
  17. * \brief Output stream for generated files that does copy-if-different.
  18. *
  19. * Many files generated by CMake don't change each time they are generated.
  20. * This class can be used in place of std::ofstream to open a file and
  21. * write output to it. The class will automatically write output to a
  22. * temporary file and copy it over an existing file only if the generated
  23. * file has changed.
  24. */
  25. class cmGeneratedFileStream
  26. {
  27. public:
  28. /**
  29. * The constructor takes the name of the file to be generated. It
  30. * automatically generates a name for the temporary file.
  31. */
  32. cmGeneratedFileStream(const char* name):
  33. m_Name(name),
  34. m_TempName(m_Name+".tmp"),
  35. m_Stream(m_TempName.c_str()),
  36. m_Copied(false),
  37. m_AlwaysCopy(false)
  38. {}
  39. /**
  40. * The destructor ensures that the file has been closed and copied if
  41. * it has changed.
  42. */
  43. ~cmGeneratedFileStream() { this->DoCopy(); }
  44. /**
  45. * Get the real output stream.
  46. */
  47. std::ostream& GetStream() { return m_Stream; }
  48. /**
  49. * Allow a test for whether the file is open.
  50. */
  51. operator bool() { return m_Stream.good(); }
  52. /**
  53. * Close the file stream. This will cause the copy-if-different to the
  54. * real file name to occur.
  55. */
  56. void close() { this->DoCopy(); }
  57. /**
  58. * If always copy is true, then copy the file all the time without
  59. * checking for differences. The default is false.
  60. */
  61. bool SetAlwaysCopy(bool v) { m_AlwaysCopy = v; return v;}
  62. private:
  63. /**
  64. * The name of the real file where output will be copied if it has changed.
  65. */
  66. std::string m_Name;
  67. /**
  68. * The name of the temporary file.
  69. */
  70. std::string m_TempName;
  71. /**
  72. * The real output stream used to write to the file.
  73. */
  74. std::ofstream m_Stream;
  75. /**
  76. * Whether the temporary file has already been copied to the real file.
  77. */
  78. bool m_Copied;
  79. /**
  80. * If always copy is true, then copy the file all the time without
  81. * checking for differences. The default is false.
  82. */
  83. bool m_AlwaysCopy;
  84. /**
  85. * Closes the temporary file and does the copy-if-different to the
  86. * real file.
  87. */
  88. void DoCopy()
  89. {
  90. if(!m_Copied)
  91. {
  92. m_Stream.close();
  93. if(m_AlwaysCopy)
  94. {
  95. cmSystemTools::cmCopyFile(m_TempName.c_str(), m_Name.c_str());
  96. }
  97. else
  98. {
  99. cmSystemTools::CopyFileIfDifferent(m_TempName.c_str(),
  100. m_Name.c_str());
  101. }
  102. cmSystemTools::RemoveFile(m_TempName.c_str());
  103. m_Copied = true;
  104. }
  105. }
  106. };
  107. /**
  108. * Allow a cmGeneratedFileStream to be used just as a real std::ostream
  109. * would be.
  110. */
  111. template <class T>
  112. std::ostream& operator << (cmGeneratedFileStream& l, const T& r)
  113. {
  114. std::ostream& os = l.GetStream();
  115. os << r;
  116. return os;
  117. }
  118. #endif