1*9880d681SAndroid Build Coastguard Worker //===-- llvm/Support/FormattedStream.cpp - Formatted streams ----*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains the implementation of formatted_raw_ostream.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FormattedStream.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
17*9880d681SAndroid Build Coastguard Worker #include <algorithm>
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Worker using namespace llvm;
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker /// UpdatePosition - Examine the given char sequence and figure out which
22*9880d681SAndroid Build Coastguard Worker /// column we end up in after output, and how many line breaks are contained.
23*9880d681SAndroid Build Coastguard Worker ///
UpdatePosition(std::pair<unsigned,unsigned> & Position,const char * Ptr,size_t Size)24*9880d681SAndroid Build Coastguard Worker static void UpdatePosition(std::pair<unsigned, unsigned> &Position, const char *Ptr, size_t Size) {
25*9880d681SAndroid Build Coastguard Worker unsigned &Column = Position.first;
26*9880d681SAndroid Build Coastguard Worker unsigned &Line = Position.second;
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker // Keep track of the current column and line by scanning the string for
29*9880d681SAndroid Build Coastguard Worker // special characters
30*9880d681SAndroid Build Coastguard Worker for (const char *End = Ptr + Size; Ptr != End; ++Ptr) {
31*9880d681SAndroid Build Coastguard Worker ++Column;
32*9880d681SAndroid Build Coastguard Worker switch (*Ptr) {
33*9880d681SAndroid Build Coastguard Worker case '\n':
34*9880d681SAndroid Build Coastguard Worker Line += 1;
35*9880d681SAndroid Build Coastguard Worker case '\r':
36*9880d681SAndroid Build Coastguard Worker Column = 0;
37*9880d681SAndroid Build Coastguard Worker break;
38*9880d681SAndroid Build Coastguard Worker case '\t':
39*9880d681SAndroid Build Coastguard Worker // Assumes tab stop = 8 characters.
40*9880d681SAndroid Build Coastguard Worker Column += (8 - (Column & 0x7)) & 0x7;
41*9880d681SAndroid Build Coastguard Worker break;
42*9880d681SAndroid Build Coastguard Worker }
43*9880d681SAndroid Build Coastguard Worker }
44*9880d681SAndroid Build Coastguard Worker }
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard Worker /// ComputePosition - Examine the current output and update line and column
47*9880d681SAndroid Build Coastguard Worker /// counts.
ComputePosition(const char * Ptr,size_t Size)48*9880d681SAndroid Build Coastguard Worker void formatted_raw_ostream::ComputePosition(const char *Ptr, size_t Size) {
49*9880d681SAndroid Build Coastguard Worker // If our previous scan pointer is inside the buffer, assume we already
50*9880d681SAndroid Build Coastguard Worker // scanned those bytes. This depends on raw_ostream to not change our buffer
51*9880d681SAndroid Build Coastguard Worker // in unexpected ways.
52*9880d681SAndroid Build Coastguard Worker if (Ptr <= Scanned && Scanned <= Ptr + Size)
53*9880d681SAndroid Build Coastguard Worker // Scan all characters added since our last scan to determine the new
54*9880d681SAndroid Build Coastguard Worker // column.
55*9880d681SAndroid Build Coastguard Worker UpdatePosition(Position, Scanned, Size - (Scanned - Ptr));
56*9880d681SAndroid Build Coastguard Worker else
57*9880d681SAndroid Build Coastguard Worker UpdatePosition(Position, Ptr, Size);
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Worker // Update the scanning pointer.
60*9880d681SAndroid Build Coastguard Worker Scanned = Ptr + Size;
61*9880d681SAndroid Build Coastguard Worker }
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker /// PadToColumn - Align the output to some column number.
64*9880d681SAndroid Build Coastguard Worker ///
65*9880d681SAndroid Build Coastguard Worker /// \param NewCol - The column to move to.
66*9880d681SAndroid Build Coastguard Worker ///
PadToColumn(unsigned NewCol)67*9880d681SAndroid Build Coastguard Worker formatted_raw_ostream &formatted_raw_ostream::PadToColumn(unsigned NewCol) {
68*9880d681SAndroid Build Coastguard Worker // Figure out what's in the buffer and add it to the column count.
69*9880d681SAndroid Build Coastguard Worker ComputePosition(getBufferStart(), GetNumBytesInBuffer());
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker // Output spaces until we reach the desired column.
72*9880d681SAndroid Build Coastguard Worker indent(std::max(int(NewCol - getColumn()), 1));
73*9880d681SAndroid Build Coastguard Worker return *this;
74*9880d681SAndroid Build Coastguard Worker }
75*9880d681SAndroid Build Coastguard Worker
write_impl(const char * Ptr,size_t Size)76*9880d681SAndroid Build Coastguard Worker void formatted_raw_ostream::write_impl(const char *Ptr, size_t Size) {
77*9880d681SAndroid Build Coastguard Worker // Figure out what's in the buffer and add it to the column count.
78*9880d681SAndroid Build Coastguard Worker ComputePosition(Ptr, Size);
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker // Write the data to the underlying stream (which is unbuffered, so
81*9880d681SAndroid Build Coastguard Worker // the data will be immediately written out).
82*9880d681SAndroid Build Coastguard Worker TheStream->write(Ptr, Size);
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker // Reset the scanning pointer.
85*9880d681SAndroid Build Coastguard Worker Scanned = nullptr;
86*9880d681SAndroid Build Coastguard Worker }
87*9880d681SAndroid Build Coastguard Worker
88*9880d681SAndroid Build Coastguard Worker /// fouts() - This returns a reference to a formatted_raw_ostream for
89*9880d681SAndroid Build Coastguard Worker /// standard output. Use it like: fouts() << "foo" << "bar";
fouts()90*9880d681SAndroid Build Coastguard Worker formatted_raw_ostream &llvm::fouts() {
91*9880d681SAndroid Build Coastguard Worker static formatted_raw_ostream S(outs());
92*9880d681SAndroid Build Coastguard Worker return S;
93*9880d681SAndroid Build Coastguard Worker }
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker /// ferrs() - This returns a reference to a formatted_raw_ostream for
96*9880d681SAndroid Build Coastguard Worker /// standard error. Use it like: ferrs() << "foo" << "bar";
ferrs()97*9880d681SAndroid Build Coastguard Worker formatted_raw_ostream &llvm::ferrs() {
98*9880d681SAndroid Build Coastguard Worker static formatted_raw_ostream S(errs());
99*9880d681SAndroid Build Coastguard Worker return S;
100*9880d681SAndroid Build Coastguard Worker }
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker /// fdbgs() - This returns a reference to a formatted_raw_ostream for
103*9880d681SAndroid Build Coastguard Worker /// the debug stream. Use it like: fdbgs() << "foo" << "bar";
fdbgs()104*9880d681SAndroid Build Coastguard Worker formatted_raw_ostream &llvm::fdbgs() {
105*9880d681SAndroid Build Coastguard Worker static formatted_raw_ostream S(dbgs());
106*9880d681SAndroid Build Coastguard Worker return S;
107*9880d681SAndroid Build Coastguard Worker }
108