]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/include/llvm/Support/FormattedStream.h
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / contrib / llvm / 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 #include <utility>
20
21 namespace llvm {
22
23 /// formatted_raw_ostream - A raw_ostream that wraps another one and keeps track
24 /// of line and column position, allowing padding out to specific column
25 /// boundaries and querying the number of lines written to the stream.
26 ///
27 class formatted_raw_ostream : public raw_ostream {
28 public:
29   /// DELETE_STREAM - Tell the destructor to delete the held stream.
30   ///
31   static const bool DELETE_STREAM = true;
32
33   /// PRESERVE_STREAM - Tell the destructor to not delete the held
34   /// stream.
35   ///
36   static const bool PRESERVE_STREAM = false;
37
38 private:
39   /// TheStream - The real stream we output to. We set it to be
40   /// unbuffered, since we're already doing our own buffering.
41   ///
42   raw_ostream *TheStream;
43
44   /// DeleteStream - Do we need to delete TheStream in the
45   /// destructor?
46   ///
47   bool DeleteStream;
48
49   /// Position - The current output column and line of the data that's
50   /// been flushed and the portion of the buffer that's been
51   /// scanned.  The line and column scheme is zero-based.
52   ///
53   std::pair<unsigned, unsigned> Position;
54
55   /// Scanned - This points to one past the last character in the
56   /// buffer we've scanned.
57   ///
58   const char *Scanned;
59
60   virtual void write_impl(const char *Ptr, size_t Size) LLVM_OVERRIDE;
61
62   /// current_pos - Return the current position within the stream,
63   /// not counting the bytes currently in the buffer.
64   virtual uint64_t current_pos() const LLVM_OVERRIDE {
65     // Our current position in the stream is all the contents which have been
66     // written to the underlying stream (*not* the current position of the
67     // underlying stream).
68     return TheStream->tell();
69   }
70
71   /// ComputePosition - Examine the given output buffer and figure out the new
72   /// position after output.
73   ///
74   void ComputePosition(const char *Ptr, size_t size);
75
76 public:
77   /// formatted_raw_ostream - Open the specified file for
78   /// writing. If an error occurs, information about the error is
79   /// put into ErrorInfo, and the stream should be immediately
80   /// destroyed; the string will be empty if no error occurred.
81   ///
82   /// As a side effect, the given Stream is set to be Unbuffered.
83   /// This is because formatted_raw_ostream does its own buffering,
84   /// so it doesn't want another layer of buffering to be happening
85   /// underneath it.
86   ///
87   formatted_raw_ostream(raw_ostream &Stream, bool Delete = false) 
88     : raw_ostream(), TheStream(0), DeleteStream(false), Position(0, 0) {
89     setStream(Stream, Delete);
90   }
91   explicit formatted_raw_ostream()
92     : raw_ostream(), TheStream(0), DeleteStream(false), Position(0, 0) {
93     Scanned = 0;
94   }
95
96   ~formatted_raw_ostream() {
97     flush();
98     releaseStream();
99   }
100
101   void setStream(raw_ostream &Stream, bool Delete = false) {
102     releaseStream();
103
104     TheStream = &Stream;
105     DeleteStream = Delete;
106
107     // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
108     // own buffering, and it doesn't need or want TheStream to do another
109     // layer of buffering underneath. Resize the buffer to what TheStream
110     // had been using, and tell TheStream not to do its own buffering.
111     if (size_t BufferSize = TheStream->GetBufferSize())
112       SetBufferSize(BufferSize);
113     else
114       SetUnbuffered();
115     TheStream->SetUnbuffered();
116
117     Scanned = 0;
118   }
119
120   /// PadToColumn - Align the output to some column number.  If the current
121   /// column is already equal to or more than NewCol, PadToColumn inserts one
122   /// space.
123   ///
124   /// \param NewCol - The column to move to.
125   formatted_raw_ostream &PadToColumn(unsigned NewCol);
126
127   /// getColumn - Return the column number
128   unsigned getColumn() { return Position.first; }
129
130   /// getLine - Return the line number
131   unsigned getLine() { return Position.second; }
132   
133   raw_ostream &resetColor() {
134     TheStream->resetColor();
135     return *this;
136   }
137   
138   raw_ostream &reverseColor() {
139     TheStream->reverseColor();
140     return *this;
141   }
142   
143   raw_ostream &changeColor(enum Colors Color,
144                            bool Bold,
145                            bool BG) {
146     TheStream->changeColor(Color, Bold, BG);
147     return *this;
148   }
149   
150   bool is_displayed() const {
151     return TheStream->is_displayed();
152   }
153
154 private:
155   void releaseStream() {
156     // Delete the stream if needed. Otherwise, transfer the buffer
157     // settings from this raw_ostream back to the underlying stream.
158     if (!TheStream)
159       return;
160     if (DeleteStream)
161       delete TheStream;
162     else if (size_t BufferSize = GetBufferSize())
163       TheStream->SetBufferSize(BufferSize);
164     else
165       TheStream->SetUnbuffered();
166   }
167 };
168
169 /// fouts() - This returns a reference to a formatted_raw_ostream for
170 /// standard output.  Use it like: fouts() << "foo" << "bar";
171 formatted_raw_ostream &fouts();
172
173 /// ferrs() - This returns a reference to a formatted_raw_ostream for
174 /// standard error.  Use it like: ferrs() << "foo" << "bar";
175 formatted_raw_ostream &ferrs();
176
177 /// fdbgs() - This returns a reference to a formatted_raw_ostream for
178 /// debug output.  Use it like: fdbgs() << "foo" << "bar";
179 formatted_raw_ostream &fdbgs();
180
181 } // end llvm namespace
182
183
184 #endif