Line data Source code
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 : /// TheStream - The real stream we output to. We set it to be
29 : /// unbuffered, since we're already doing our own buffering.
30 : ///
31 : raw_ostream *TheStream;
32 :
33 : /// Position - The current output column and line of the data that's
34 : /// been flushed and the portion of the buffer that's been
35 : /// scanned. The line and column scheme is zero-based.
36 : ///
37 : std::pair<unsigned, unsigned> Position;
38 :
39 : /// Scanned - This points to one past the last character in the
40 : /// buffer we've scanned.
41 : ///
42 : const char *Scanned;
43 :
44 : void write_impl(const char *Ptr, size_t Size) override;
45 :
46 : /// current_pos - Return the current position within the stream,
47 : /// not counting the bytes currently in the buffer.
48 3 : uint64_t current_pos() const override {
49 : // Our current position in the stream is all the contents which have been
50 : // written to the underlying stream (*not* the current position of the
51 : // underlying stream).
52 3 : return TheStream->tell();
53 : }
54 :
55 : /// ComputePosition - Examine the given output buffer and figure out the new
56 : /// position after output.
57 : ///
58 : void ComputePosition(const char *Ptr, size_t size);
59 :
60 87177 : void setStream(raw_ostream &Stream) {
61 87177 : releaseStream();
62 :
63 87177 : TheStream = &Stream;
64 :
65 : // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
66 : // own buffering, and it doesn't need or want TheStream to do another
67 : // layer of buffering underneath. Resize the buffer to what TheStream
68 : // had been using, and tell TheStream not to do its own buffering.
69 87177 : if (size_t BufferSize = TheStream->GetBufferSize())
70 77175 : SetBufferSize(BufferSize);
71 : else
72 10002 : SetUnbuffered();
73 87177 : TheStream->SetUnbuffered();
74 :
75 87177 : Scanned = nullptr;
76 87177 : }
77 :
78 : public:
79 : /// formatted_raw_ostream - Open the specified file for
80 : /// writing. If an error occurs, information about the error is
81 : /// put into ErrorInfo, and the stream should be immediately
82 : /// destroyed; the string will be empty if no error occurred.
83 : ///
84 : /// As a side effect, the given Stream is set to be Unbuffered.
85 : /// This is because formatted_raw_ostream does its own buffering,
86 : /// so it doesn't want another layer of buffering to be happening
87 : /// underneath it.
88 : ///
89 : formatted_raw_ostream(raw_ostream &Stream)
90 174354 : : TheStream(nullptr), Position(0, 0) {
91 87177 : setStream(Stream);
92 : }
93 : explicit formatted_raw_ostream() : TheStream(nullptr), Position(0, 0) {
94 : Scanned = nullptr;
95 : }
96 :
97 109933 : ~formatted_raw_ostream() override {
98 87026 : flush();
99 87025 : releaseStream();
100 109933 : }
101 22908 :
102 : /// PadToColumn - Align the output to some column number. If the current
103 : /// column is already equal to or more than NewCol, PadToColumn inserts one
104 22908 : /// space.
105 87025 : ///
106 87026 : /// \param NewCol - The column to move to.
107 87025 : formatted_raw_ostream &PadToColumn(unsigned NewCol);
108 87025 :
109 : /// getColumn - Return the column number
110 : unsigned getColumn() { return Position.first; }
111 :
112 : /// getLine - Return the line number
113 : unsigned getLine() { return Position.second; }
114 :
115 : raw_ostream &resetColor() override {
116 : TheStream->resetColor();
117 : return *this;
118 0 : }
119 :
120 : raw_ostream &reverseColor() override {
121 : TheStream->reverseColor();
122 : return *this;
123 0 : }
124 0 :
125 0 : raw_ostream &changeColor(enum Colors Color, bool Bold, bool BG) override {
126 : TheStream->changeColor(Color, Bold, BG);
127 : return *this;
128 0 : }
129 0 :
130 0 : bool is_displayed() const override {
131 0 : return TheStream->is_displayed();
132 : }
133 0 :
134 0 : private:
135 0 : void releaseStream() {
136 : // Transfer the buffer settings from this raw_ostream back to the underlying
137 : // stream.
138 2156 : if (!TheStream)
139 2156 : return;
140 : if (size_t BufferSize = GetBufferSize())
141 : TheStream->SetBufferSize(BufferSize);
142 : else
143 174202 : TheStream->SetUnbuffered();
144 : }
145 : };
146 174202 :
147 : /// fouts() - This returns a reference to a formatted_raw_ostream for
148 174050 : /// standard output. Use it like: fouts() << "foo" << "bar";
149 77023 : formatted_raw_ostream &fouts();
150 :
151 10002 : /// ferrs() - This returns a reference to a formatted_raw_ostream for
152 : /// standard error. Use it like: ferrs() << "foo" << "bar";
153 : formatted_raw_ostream &ferrs();
154 :
155 : /// fdbgs() - This returns a reference to a formatted_raw_ostream for
156 : /// debug output. Use it like: fdbgs() << "foo" << "bar";
157 : formatted_raw_ostream &fdbgs();
158 :
159 : } // end llvm namespace
160 :
161 :
162 : #endif
|