Export error-handling functions in formatted_tool_output_file.
[oota-llvm.git] / include / llvm / Support / FormattedStream.h
1 //===-- llvm/Support/FormattedStream.h - Formatted streams ------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains raw_ostream implementations for streams to do
11 // things like pretty-print comments.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_SUPPORT_FORMATTEDSTREAM_H
16 #define LLVM_SUPPORT_FORMATTEDSTREAM_H
17
18 #include "llvm/Support/raw_ostream.h"
19
20 namespace llvm 
21 {
22   class formatted_tool_output_file;
23
24   /// formatted_raw_ostream - Formatted raw_fd_ostream to handle
25   /// asm-specific constructs.
26   ///
27   class formatted_raw_ostream : public raw_ostream {
28     friend class formatted_tool_output_file;
29
30   public:
31     /// DELETE_STREAM - Tell the destructor to delete the held stream.
32     ///
33     static const bool DELETE_STREAM = true;
34
35     /// PRESERVE_STREAM - Tell the destructor to not delete the held
36     /// stream.
37     ///
38     static const bool PRESERVE_STREAM = false;
39
40   private:
41     /// TheStream - The real stream we output to. We set it to be
42     /// unbuffered, since we're already doing our own buffering.
43     ///
44     raw_ostream *TheStream;
45
46     /// DeleteStream - Do we need to delete TheStream in the
47     /// destructor?
48     ///
49     bool DeleteStream;
50
51     /// ColumnScanned - The current output column of the data that's
52     /// been flushed and the portion of the buffer that's been
53     /// scanned.  The column scheme is zero-based.
54     ///
55     unsigned ColumnScanned;
56
57     /// Scanned - This points to one past the last character in the
58     /// buffer we've scanned.
59     ///
60     const char *Scanned;
61
62     virtual void write_impl(const char *Ptr, size_t Size);
63
64     /// current_pos - Return the current position within the stream,
65     /// not counting the bytes currently in the buffer.
66     virtual uint64_t current_pos() const { 
67       // This has the same effect as calling TheStream.current_pos(),
68       // but that interface is private.
69       return TheStream->tell() - TheStream->GetNumBytesInBuffer();
70     }
71
72     /// ComputeColumn - Examine the given output buffer and figure out which
73     /// column we end up in after output.
74     ///
75     void ComputeColumn(const char *Ptr, size_t size);
76
77   public:
78     /// formatted_raw_ostream - Open the specified file for
79     /// writing. If an error occurs, information about the error is
80     /// put into ErrorInfo, and the stream should be immediately
81     /// destroyed; the string will be empty if no error occurred.
82     ///
83     /// As a side effect, the given Stream is set to be Unbuffered.
84     /// This is because formatted_raw_ostream does its own buffering,
85     /// so it doesn't want another layer of buffering to be happening
86     /// underneath it.
87     ///
88     formatted_raw_ostream(raw_ostream &Stream, bool Delete = false) 
89       : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) {
90       setStream(Stream, Delete);
91     }
92     explicit formatted_raw_ostream()
93       : raw_ostream(), TheStream(0), DeleteStream(false), ColumnScanned(0) {
94       Scanned = 0;
95     }
96
97     ~formatted_raw_ostream() {
98       flush();
99       releaseStream();
100     }
101
102     void setStream(raw_ostream &Stream, bool Delete = false) {
103       releaseStream();
104
105       TheStream = &Stream;
106       DeleteStream = Delete;
107
108       // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
109       // own buffering, and it doesn't need or want TheStream to do another
110       // layer of buffering underneath. Resize the buffer to what TheStream
111       // had been using, and tell TheStream not to do its own buffering.
112       if (size_t BufferSize = TheStream->GetBufferSize())
113         SetBufferSize(BufferSize);
114       else
115         SetUnbuffered();
116       TheStream->SetUnbuffered();
117
118       Scanned = 0;
119     }
120
121     /// PadToColumn - Align the output to some column number.  If the current
122     /// column is already equal to or more than NewCol, PadToColumn inserts one
123     /// space.
124     ///
125     /// \param NewCol - The column to move to.
126     formatted_raw_ostream &PadToColumn(unsigned NewCol);
127
128   private:
129     void releaseStream() {
130       // Delete the stream if needed. Otherwise, transfer the buffer
131       // settings from this raw_ostream back to the underlying stream.
132       if (!TheStream)
133         return;
134       if (DeleteStream)
135         delete TheStream;
136       else if (size_t BufferSize = GetBufferSize())
137         TheStream->SetBufferSize(BufferSize);
138       else
139         TheStream->SetUnbuffered();
140     }
141   };
142
143   /// formatted_tool_output_file - This is a subclass of formatted_raw_ostream
144   /// for use when the underlying stream is a tool_output_file. It exposes
145   /// keep() and several other member functions.
146   class formatted_tool_output_file : public formatted_raw_ostream {
147   private:
148     tool_output_file &get_tool_output_file() const {
149       return *static_cast<tool_output_file *>(TheStream);
150     }
151
152   public:
153     formatted_tool_output_file(tool_output_file &Stream, bool Delete = false) 
154       : formatted_raw_ostream(Stream, Delete) {}
155
156     formatted_tool_output_file() {}
157
158     ~formatted_tool_output_file();
159
160     void setStream(tool_output_file &Stream, bool Delete = false) {
161       return formatted_raw_ostream::setStream(Stream, Delete);
162     }
163
164     void keep()            { return get_tool_output_file().keep(); }
165     bool has_error() const { return get_tool_output_file().has_error(); }
166     void clear_error()     { return get_tool_output_file().clear_error(); }
167     void close()           { return get_tool_output_file().close(); }
168   };
169
170 /// fouts() - This returns a reference to a formatted_raw_ostream for
171 /// standard output.  Use it like: fouts() << "foo" << "bar";
172 formatted_raw_ostream &fouts();
173
174 /// ferrs() - This returns a reference to a formatted_raw_ostream for
175 /// standard error.  Use it like: ferrs() << "foo" << "bar";
176 formatted_raw_ostream &ferrs();
177
178 /// fdbgs() - This returns a reference to a formatted_raw_ostream for
179 /// debug output.  Use it like: fdbgs() << "foo" << "bar";
180 formatted_raw_ostream &fdbgs();
181
182 } // end llvm namespace
183
184
185 #endif