diff --git a/lib/Support/FormattedStream.cpp b/lib/Support/FormattedStream.cpp index 867e5de4d12..0db21f651a7 100644 --- a/lib/Support/FormattedStream.cpp +++ b/lib/Support/FormattedStream.cpp @@ -15,27 +15,34 @@ using namespace llvm; -/// ComputeColumn - Examine the current output and figure out which +/// CountColumns - Examine the given char sequence and figure out which /// column we end up in after output. /// -void formatted_raw_ostream::ComputeColumn() { +static unsigned CountColumns(unsigned Column, const char *Ptr, size_t Size) { // Keep track of the current column by scanning the string for // special characters - // The buffer may have been allocated underneath us. - if (Scanned == 0 && GetNumBytesInBuffer() != 0) { - Scanned = begin(); + for (const char *End = Ptr + Size; Ptr != End; ++Ptr) { + ++Column; + if (*Ptr == '\n' || *Ptr == '\r') + Column = 0; + else if (*Ptr == '\t') + // Assumes tab stop = 8 characters. + Column += (8 - (Column & 0x7)) & 0x7; } - while (Scanned != end()) { - ++ColumnScanned; - if (*Scanned == '\n' || *Scanned == '\r') - ColumnScanned = 0; - else if (*Scanned == '\t') - // Assumes tab stop = 8 characters. - ColumnScanned += (8 - (ColumnScanned & 0x7)) & 0x7; - ++Scanned; - } + return Column; +} + +/// ComputeColumn - Examine the current output and figure out which +/// column we end up in after output. +void formatted_raw_ostream::ComputeColumn() { + // The buffer may have been allocated underneath us. + if (Scanned == 0) Scanned = begin(); + // Scan all characters added since our last scan to determine the new column. + ColumnScanned = CountColumns(ColumnScanned, Scanned, end() - Scanned); + // We're now current with everything in the buffer. + Scanned = end(); } /// PadToColumn - Align the output to some column number. @@ -63,9 +70,25 @@ void formatted_raw_ostream::PadToColumn(unsigned NewCol, unsigned MinPad) { } void formatted_raw_ostream::write_impl(const char *Ptr, size_t Size) { + // Figure out what's in the buffer and add it to the column count. ComputeColumn(); + + // Write the data to the underlying stream (which is unbuffered, so + // the data will be immediately written out). TheStream->write(Ptr, Size); - Scanned = begin(); + + // If this FormattedStream is unbuffered, scan the string that + // was just written to determine the new column. + if (Ptr == begin()) { + // Buffered mode. The buffer is being flushed; reset the scanning + // position to the beginning of the buffer. + assert(Ptr + Size == end() && "Buffer is not being fully flushed!"); + Scanned = begin(); + } else { + // Unbuffered mode. Immediately scan the string that was just + // written to determine the new column. + ColumnScanned = CountColumns(ColumnScanned, Ptr, Size); + } } /// fouts() - This returns a reference to a formatted_raw_ostream for