1 /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 file Copyright.txt or https://cmake.org/licensing for details. */
5 #include "cmConfigure.h" // IWYU pragma: keep
9 #include "cmsys/FStream.hxx"
11 #include "cm_codecvt.hxx"
13 // This is the first base class of cmGeneratedFileStream. It will be
14 // created before and destroyed after the ofstream portion and can
15 // therefore be used to manage the temporary file.
16 class cmGeneratedFileStreamBase
19 // This constructor does not prepare the temporary file. The open
20 // method must be used.
21 cmGeneratedFileStreamBase();
23 // This constructor prepares the temporary output file.
24 cmGeneratedFileStreamBase(std::string const& name);
26 // The destructor renames the temporary output file to the real name.
27 ~cmGeneratedFileStreamBase();
29 // Internal methods to handle the temporary file. Open is always
30 // called before the real stream is opened. Close is always called
31 // after the real stream is closed and Okay is set to whether the
32 // real stream was still valid for writing when it was closed.
33 void Open(std::string const& name);
36 // Internal file replacement implementation.
37 int RenameFile(std::string const& oldname, std::string const& newname);
39 // Internal file compression implementation.
40 int CompressFile(std::string const& oldname, std::string const& newname);
42 // The name of the final destination file for the output.
45 // The extension of the temporary file.
48 // The name of the temporary file.
51 // Whether to do a copy-if-different.
52 bool CopyIfDifferent = false;
54 // Whether the real file stream was valid when it was closed.
57 // Whether the destination file is compressed
58 bool Compress = false;
60 // Whether the destination file is compressed
61 bool CompressExtraExtension = true;
64 /** \class cmGeneratedFileStream
65 * \brief Output stream for generated files.
67 * File generation should be atomic so that if CMake is killed then a
68 * generated file is either the original version or the complete new
69 * version. This stream is used to make sure file generation is
70 * atomic. Optionally the output file is only replaced if its
71 * contents have changed to prevent the file modification time from
74 class cmGeneratedFileStream
75 : private cmGeneratedFileStreamBase
76 , public cmsys::ofstream
79 using Stream = cmsys::ofstream;
80 using Encoding = codecvt::Encoding;
83 * This constructor prepares a default stream. The open method must
84 * be used before writing to the stream.
86 cmGeneratedFileStream(Encoding encoding = codecvt::None);
89 * This constructor takes the name of the file to be generated. It
90 * automatically generates a name for the temporary file. If the
91 * file cannot be opened an error message is produced unless the
92 * second argument is set to true.
94 cmGeneratedFileStream(std::string const& name, bool quiet = false,
95 Encoding encoding = codecvt::None);
98 * The destructor checks the stream status to be sure the temporary
99 * file was successfully written before allowing the original to be
102 ~cmGeneratedFileStream() override;
104 cmGeneratedFileStream(cmGeneratedFileStream const&) = delete;
107 * Open an output file by name. This should be used only with a
108 * non-open stream. It automatically generates a name for the
109 * temporary file. If the file cannot be opened an error message is
110 * produced unless the second argument is set to true.
112 cmGeneratedFileStream& Open(std::string const& name, bool quiet = false,
113 bool binaryFlag = false);
116 * Close the output file. This should be used only with an open
117 * stream. The temporary file is atomically renamed to the
118 * destination file if the stream is still valid when this method
124 * Set whether copy-if-different is done.
126 void SetCopyIfDifferent(bool copy_if_different);
129 * Set whether compression is done.
131 void SetCompression(bool compression);
134 * Set whether compression has extra extension
136 void SetCompressionExtraExtension(bool ext);
139 * Set name of the file that will hold the actual output. This method allows
140 * the output file to be changed during the use of cmGeneratedFileStream.
142 void SetName(const std::string& fname);
145 * Set set a custom temporary file extension used with 'Open'.
146 * This does not work if the file was opened by the constructor.
148 void SetTempExt(std::string const& ext);
151 * Write a specific string using an alternate encoding.
152 * Afterward, the original encoding is restored.
154 void WriteAltEncoding(std::string const& data, Encoding encoding);