cmGeneratedFileStream.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  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. #include "cmSystemTools.h"
  17. /** \class cmGeneratedFileStream
  18. * \brief Output stream for generated files that does copy-if-different.
  19. *
  20. * Many files generated by CMake don't change each time they are generated.
  21. * This class can be used in place of std::ofstream to open a file and
  22. * write output to it. The class will automatically write output to a
  23. * temporary file and copy it over an existing file only if the generated
  24. * file has changed.
  25. */
  26. class cmGeneratedFileStream
  27. {
  28. public:
  29. /**
  30. * The constructor takes the name of the file to be generated. It
  31. * automatically generates a name for the temporary file.
  32. */
  33. cmGeneratedFileStream(const char* name):
  34. m_Name(name),
  35. m_TempName(m_Name+".tmp"),
  36. m_Stream(m_TempName.c_str()),
  37. m_Copied(false),
  38. m_AlwaysCopy(false)
  39. {}
  40. /**
  41. * The destructor ensures that the file has been closed and copied if
  42. * it has changed.
  43. */
  44. ~cmGeneratedFileStream() { this->DoCopy(); }
  45. /**
  46. * Get the real output stream.
  47. */
  48. std::ostream& GetStream() { return m_Stream; }
  49. /**
  50. * Allow a test for whether the file is open.
  51. */
  52. operator bool() { return m_Stream.good(); }
  53. /**
  54. * Close the file stream. This will cause the copy-if-different to the
  55. * real file name to occur.
  56. */
  57. void close() { this->DoCopy(); }
  58. /**
  59. * If always copy is true, then copy the file all the time without
  60. * checking for differences. The default is false.
  61. */
  62. bool SetAlwaysCopy(bool v) { m_AlwaysCopy = v; return v;}
  63. private:
  64. /**
  65. * The name of the real file where output will be copied if it has changed.
  66. */
  67. std::string m_Name;
  68. /**
  69. * The name of the temporary file.
  70. */
  71. std::string m_TempName;
  72. /**
  73. * The real output stream used to write to the file.
  74. */
  75. std::ofstream m_Stream;
  76. /**
  77. * Whether the temporary file has already been copied to the real file.
  78. */
  79. bool m_Copied;
  80. /**
  81. * If always copy is true, then copy the file all the time without
  82. * checking for differences. The default is false.
  83. */
  84. bool m_AlwaysCopy;
  85. /**
  86. * Closes the temporary file and does the copy-if-different to the
  87. * real file.
  88. */
  89. void DoCopy()
  90. {
  91. if(!m_Copied)
  92. {
  93. m_Stream.close();
  94. if(m_AlwaysCopy)
  95. {
  96. cmSystemTools::cmCopyFile(m_TempName.c_str(), m_Name.c_str());
  97. }
  98. else
  99. {
  100. cmSystemTools::CopyFileIfDifferent(m_TempName.c_str(),
  101. m_Name.c_str());
  102. }
  103. cmSystemTools::RemoveFile(m_TempName.c_str());
  104. m_Copied = true;
  105. }
  106. }
  107. };
  108. /**
  109. * Allow a cmGeneratedFileStream to be used just as a real std::ostream
  110. * would be.
  111. */
  112. template <class T>
  113. std::ostream& operator << (cmGeneratedFileStream& l, const T& r)
  114. {
  115. std::ostream& os = l.GetStream();
  116. os << r;
  117. return os;
  118. }
  119. #endif