From 097af7fc8f8688cc21453a5561347f14ca7c5771 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 23 Aug 2008 19:23:10 +0000 Subject: 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 --- lib/Support/raw_ostream.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'lib/Support') 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 @@ -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 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 //===----------------------------------------------------------------------===// -- cgit v1.2.3