diff options
author | Chris Lattner <sabre@nondot.org> | 2008-08-23 19:23:10 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-08-23 19:23:10 +0000 |
commit | 097af7fc8f8688cc21453a5561347f14ca7c5771 (patch) | |
tree | 3278cf5420b9c3a9e07d8ccfd4afd8e7fb36a886 /lib | |
parent | 8ff7ce3dd2c0b57283372e9ed939ab07018fec2f (diff) |
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
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Support/raw_ostream.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index d776fa583f..104dc77149 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/raw_ostream.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Config/config.h" #include <ostream> @@ -134,6 +135,55 @@ raw_ostream &raw_ostream::write(const char *Ptr, unsigned Size) { return *this; } +// Formatted output. +raw_ostream &raw_ostream::operator<<(const format_object_base &Fmt) { + // If we have more than a few bytes left in our output buffer, try formatting + // directly onto its end. + unsigned NextBufferSize = 127; + if (OutBufEnd-OutBufCur > 3) { + unsigned BufferBytesLeft = OutBufEnd-OutBufCur; + unsigned BytesUsed = Fmt.print(OutBufCur, BufferBytesLeft); + + // Common case is that we have plenty of space. + if (BytesUsed < BufferBytesLeft) { + OutBufCur += BytesUsed; + return *this; + } + + // Otherwise, we overflowed and the return value tells us the size to try + // again with. + NextBufferSize = BytesUsed; + } + + // If we got here, we didn't have enough space in the output buffer for the + // string. Try printing into a SmallVector that is resized to have enough + // space. Iterate until we win. + SmallVector<char, 128> V; + + while (1) { + V.resize(NextBufferSize); + + // Try formatting into the SmallVector. + unsigned BytesUsed = Fmt.print(&V[0], NextBufferSize); + + // If BytesUsed fit into the vector, we win. + if (BytesUsed < NextBufferSize) + return write(&V[0], BytesUsed); + + // Otherwise, try again with a new size. + assert(BytesUsed > NextBufferSize && "Didn't grow buffer!?"); + NextBufferSize = BytesUsed; + } +} + +//===----------------------------------------------------------------------===// +// Formatted Output +//===----------------------------------------------------------------------===// + +// Out of line virtual method. +void format_object_base::home() { +} + //===----------------------------------------------------------------------===// // raw_fd_ostream //===----------------------------------------------------------------------===// |