summaryrefslogtreecommitdiffstats
path: root/Source/cmGeneratedFileStream.h
blob: cb81d1d145bdc1c3916818abf2a13a26c2b42ef2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*=========================================================================

  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"

#if defined(__sgi) && !defined(__GNUC__)
# pragma set woff 1375 /* base class destructor not virtual */
#endif

// This is the first base class of cmGeneratedFileStream.  It will be
// created before and destroyed after the ofstream portion and can
// therefore be used to manage the temporary file.
class cmGeneratedFileStreamBase
{
protected:
  // This constructor does not prepare the temporary file.  The open
  // method must be used.
  cmGeneratedFileStreamBase();

  // This constructor prepares the temporary output file.
  cmGeneratedFileStreamBase(const char* name);

  // The destructor renames the temporary output file to the real name.
  ~cmGeneratedFileStreamBase();

  // Internal methods to handle the temporary file.  Open is always
  // called before the real stream is opened.  Close is always called
  // after the real stream is closed and m_Okay is set to whether the
  // real stream was still valid for writing when it was closed.
  void Open(const char* name);
  void Close();

  // Internal file replacement implementation.
  int RenameFile(const char* oldname, const char* newname);

  // Internal file compression implementation.
  int CompressFile(const char* oldname, const char* newname);

  // The name of the final destination file for the output.
  std::string m_Name;

  // The name of the temporary file.
  std::string m_TempName;

  // Whether to do a copy-if-different.
  bool m_CopyIfDifferent;

  // Whether the real file stream was valid when it was closed.
  bool m_Okay;

  // Whether the destionation file is compressed
  bool m_Compress;
};

/** \class cmGeneratedFileStream
 * \brief Output stream for generated files.
 *
 * File generation should be atomic so that if CMake is killed then a
 * generated file is either the original version or the complete new
 * version.  This stream is used to make sure file generation is
 * atomic.  Optionally the output file is only replaced if its
 * contents have changed to prevent the file modification time from
 * being updated.
 */
class cmGeneratedFileStream: private cmGeneratedFileStreamBase,
                             public std::ofstream
{
public:
  typedef std::ofstream Stream;

  /**
   * This constructor prepares a default stream.  The open method must
   * be used before writing to the stream.
   */
  cmGeneratedFileStream();

  /**
   * This constructor takes the name of the file to be generated.  It
   * automatically generates a name for the temporary file.  If the
   * file cannot be opened an error message is produced unless the
   * second argument is set to true.
   */
  cmGeneratedFileStream(const char* name, bool quiet=false);

  /**
   * The destructor checks the stream status to be sure the temporary
   * file was successfully written before allowing the original to be
   * replaced.
   */
  ~cmGeneratedFileStream();

  /**
   * Open an output file by name.  This should be used only with a
   * non-open stream.  It automatically generates a name for the
   * temporary file.  If the file cannot be opened an error message is
   * produced unless the second argument is set to true.
   */
  cmGeneratedFileStream& Open(const char* name, bool quiet=false);

  /**
   * Close the output file.  This should be used only with an open
   * stream.  The temporary file is atomically renamed to the
   * destionation file if the stream is still valid when this method
   * is called.
   */
  cmGeneratedFileStream& Close();

  /**
   * Set whether copy-if-different is done.
   */
  void SetCopyIfDifferent(bool copy_if_different);

  /**
   * Set whether compression is done.
   */
  void SetCompression(bool compression);

  /**
   * Set name of the file that will hold the actual output. This method allows
   * the output file to be changed during the use of cmGeneratedFileStream.
   */
  void SetName(const char* fname);
};

#if defined(__sgi) && !defined(__GNUC__)
# pragma reset woff 1375 /* base class destructor not virtual */
#endif

#endif