llvm.org GIT mirror llvm / 097af7f
add a simple mechanism for formatted output. This gives raw_ostream's all the power and risk of fprintf format strings. Use them like this: OS << format("%10.4f", 42.0) << "\n" << format("%x", 42) << '\n'; git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55246 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 11 years ago
2 changed file(s) with 116 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
2020 #include
2121
2222 namespace llvm {
23
23 class format_object_base;
24
2425 /// raw_ostream - This class implements an extremely fast bulk output stream
2526 /// that can *only* output to a stream. It does not support seeking, reopening,
2627 /// rewinding, line buffered disciplines etc. It is a simple buffer that outputs
9192 }
9293
9394 raw_ostream &operator<<(unsigned long N);
94
9595 raw_ostream &operator<<(long N);
96
9796 raw_ostream &operator<<(unsigned long long N);
98
9997 raw_ostream &operator<<(long long N);
10098
10199 raw_ostream &operator<<(unsigned int N) {
110108 return this->operator<<(ftostr(N));
111109 }
112110
113
114111 raw_ostream &write(const char *Ptr, unsigned Size);
112
113 // Formatted output, see the format() function below.
114 raw_ostream &operator<<(const format_object_base &Fmt);
115115
116116 //===--------------------------------------------------------------------===//
117117 // Subclass Interface
136136 virtual void handle();
137137 };
138138
139 //===----------------------------------------------------------------------===//
140 // Formatted Output
141 //===----------------------------------------------------------------------===//
142
143 /// format_object_base - This is a helper class used for handling formatted
144 /// output. It is the abstract base class of a templated derived class.
145 class format_object_base {
146 protected:
147 const char *Fmt;
148 virtual void home(); // Out of line virtual method.
149 public:
150 format_object_base(const char *fmt) : Fmt(fmt) {}
151 virtual ~format_object_base() {}
152
153 /// print - Format the object into the specified buffer. On success, this
154 /// returns the length of the formatted string. If the buffer is too small,
155 /// this returns a length to retry with, which will be larger than BufferSize.
156 virtual unsigned print(char *Buffer, unsigned BufferSize) const = 0;
157 };
158
159 /// format_object - This is a templated helper class used by the format function
160 /// that captures the object to be formated and the format string. When
161 /// actually printed, this synthesizes the string into a temporary buffer
162 /// provided and returns whether or not it is big enough.
163 template
164 class format_object : public format_object_base {
165 T Val;
166 public:
167 format_object(const char *fmt, const T &val)
168 : format_object_base(fmt), Val(val) {
169 }
170
171 /// print - Format the object into the specified buffer. On success, this
172 /// returns the length of the formatted string. If the buffer is too small,
173 /// this returns a length to retry with, which will be larger than BufferSize.
174 virtual unsigned print(char *Buffer, unsigned BufferSize) const {
175 int N = snprintf(Buffer, BufferSize-1, Fmt, Val);
176 if (N < 0) // VC++ and old GlibC return negative on overflow.
177 return BufferSize*2;
178 if (unsigned(N) >= BufferSize-1)// Other impls yield number of bytes needed.
179 return N+1;
180 // If N is positive and <= BufferSize-1, then the string fit, yay.
181 return N;
182 }
183 };
184
185 /// format - This is a helper function that is used to produce formatted output.
186 /// This is typically used like: OS << format("%0.4f", myfloat) << '\n';
187 template
188 inline format_object format(const char *Fmt, const T &Val) {
189 return format_object(Fmt, Val);
190 }
191
192 //===----------------------------------------------------------------------===//
193 // File Output Streams
194 //===----------------------------------------------------------------------===//
195
139196 /// raw_fd_ostream - A raw_ostream that writes to a file descriptor.
140197 ///
141198 class raw_fd_ostream : public raw_ostream {
186243 raw_ostream &errs();
187244
188245
246 //===----------------------------------------------------------------------===//
247 // Bridge Output Streams
248 //===----------------------------------------------------------------------===//
249
189250 /// raw_os_ostream - A raw_ostream that writes to an std::ostream. This is a
190251 /// simple adaptor class.
191252 class raw_os_ostream : public raw_ostream {
1111 //===----------------------------------------------------------------------===//
1212
1313 #include "llvm/Support/raw_ostream.h"
14 #include "llvm/ADT/SmallVector.h"
1415 #include "llvm/Config/config.h"
1516 #include
1617
133134 return *this;
134135 }
135136
137 // Formatted output.
138 raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) {
139 // If we have more than a few bytes left in our output buffer, try formatting
140 // directly onto its end.
141 unsigned NextBufferSize = 127;
142 if (OutBufEnd-OutBufCur > 3) {
143 unsigned BufferBytesLeft = OutBufEnd-OutBufCur;
144 unsigned BytesUsed = Fmt.print(OutBufCur, BufferBytesLeft);
145
146 // Common case is that we have plenty of space.
147 if (BytesUsed < BufferBytesLeft) {
148 OutBufCur += BytesUsed;
149 return *this;
150 }
151
152 // Otherwise, we overflowed and the return value tells us the size to try
153 // again with.
154 NextBufferSize = BytesUsed;
155 }
156
157 // If we got here, we didn't have enough space in the output buffer for the
158 // string. Try printing into a SmallVector that is resized to have enough
159 // space. Iterate until we win.
160 SmallVector V;
161
162 while (1) {
163 V.resize(NextBufferSize);
164
165 // Try formatting into the SmallVector.
166 unsigned BytesUsed = Fmt.print(&V[0], NextBufferSize);
167
168 // If BytesUsed fit into the vector, we win.
169 if (BytesUsed < NextBufferSize)
170 return write(&V[0], BytesUsed);
171
172 // Otherwise, try again with a new size.
173 assert(BytesUsed > NextBufferSize && "Didn't grow buffer!?");
174 NextBufferSize = BytesUsed;
175 }
176 }
177
178 //===----------------------------------------------------------------------===//
179 // Formatted Output
180 //===----------------------------------------------------------------------===//
181
182 // Out of line virtual method.
183 void format_object_base::home() {
184 }
185
136186 //===----------------------------------------------------------------------===//
137187 // raw_fd_ostream
138188 //===----------------------------------------------------------------------===//