FormattedStream.cpp revision 302408
155682Smarkm//===-- llvm/Support/FormattedStream.cpp - Formatted streams ----*- C++ -*-===//
2233294Sstas//
3233294Sstas//                     The LLVM Compiler Infrastructure
4233294Sstas//
555682Smarkm// This file is distributed under the University of Illinois Open Source
6233294Sstas// License. See LICENSE.TXT for details.
7233294Sstas//
8233294Sstas//===----------------------------------------------------------------------===//
955682Smarkm//
10233294Sstas// This file contains the implementation of formatted_raw_ostream.
11233294Sstas//
1255682Smarkm//===----------------------------------------------------------------------===//
13233294Sstas
14233294Sstas#include "llvm/Support/Debug.h"
15233294Sstas#include "llvm/Support/FormattedStream.h"
1655682Smarkm#include "llvm/Support/raw_ostream.h"
17233294Sstas#include <algorithm>
18233294Sstas
19233294Sstasusing namespace llvm;
2055682Smarkm
21233294Sstas/// UpdatePosition - Examine the given char sequence and figure out which
22233294Sstas/// column we end up in after output, and how many line breaks are contained.
23233294Sstas///
24233294Sstasstatic void UpdatePosition(std::pair<unsigned, unsigned> &Position, const char *Ptr, size_t Size) {
25233294Sstas  unsigned &Column = Position.first;
26233294Sstas  unsigned &Line = Position.second;
27233294Sstas
28233294Sstas  // Keep track of the current column and line by scanning the string for
29233294Sstas  // special characters
30233294Sstas  for (const char *End = Ptr + Size; Ptr != End; ++Ptr) {
31233294Sstas    ++Column;
3255682Smarkm    switch (*Ptr) {
3355682Smarkm    case '\n':
3455682Smarkm      Line += 1;
35178825Sdfr    case '\r':
3655682Smarkm      Column = 0;
37178825Sdfr      break;
38178825Sdfr    case '\t':
3955682Smarkm      // Assumes tab stop = 8 characters.
40178825Sdfr      Column += (8 - (Column & 0x7)) & 0x7;
4155682Smarkm      break;
42178825Sdfr    }
43178825Sdfr  }
44178825Sdfr}
45178825Sdfr
46178825Sdfr/// ComputePosition - Examine the current output and update line and column
47233294Sstas/// counts.
48178825Sdfrvoid formatted_raw_ostream::ComputePosition(const char *Ptr, size_t Size) {
49178825Sdfr  // If our previous scan pointer is inside the buffer, assume we already
50178825Sdfr  // scanned those bytes. This depends on raw_ostream to not change our buffer
51178825Sdfr  // in unexpected ways.
52178825Sdfr  if (Ptr <= Scanned && Scanned <= Ptr + Size)
5355682Smarkm    // Scan all characters added since our last scan to determine the new
54178825Sdfr    // column.
55178825Sdfr    UpdatePosition(Position, Scanned, Size - (Scanned - Ptr));
5655682Smarkm  else
57178825Sdfr    UpdatePosition(Position, Ptr, Size);
58233294Sstas
59178825Sdfr  // Update the scanning pointer.
60178825Sdfr  Scanned = Ptr + Size;
61178825Sdfr}
62178825Sdfr
63178825Sdfr/// PadToColumn - Align the output to some column number.
64178825Sdfr///
65233294Sstas/// \param NewCol - The column to move to.
66233294Sstas///
67178825Sdfrformatted_raw_ostream &formatted_raw_ostream::PadToColumn(unsigned NewCol) {
68178825Sdfr  // Figure out what's in the buffer and add it to the column count.
69178825Sdfr  ComputePosition(getBufferStart(), GetNumBytesInBuffer());
7055682Smarkm
71178825Sdfr  // Output spaces until we reach the desired column.
72178825Sdfr  indent(std::max(int(NewCol - getColumn()), 1));
73178825Sdfr  return *this;
74178825Sdfr}
75178825Sdfr
76178825Sdfrvoid formatted_raw_ostream::write_impl(const char *Ptr, size_t Size) {
77178825Sdfr  // Figure out what's in the buffer and add it to the column count.
78233294Sstas  ComputePosition(Ptr, Size);
79233294Sstas
80178825Sdfr  // Write the data to the underlying stream (which is unbuffered, so
81178825Sdfr  // the data will be immediately written out).
82233294Sstas  TheStream->write(Ptr, Size);
83178825Sdfr
84233294Sstas  // Reset the scanning pointer.
85233294Sstas  Scanned = nullptr;
86233294Sstas}
87178825Sdfr
88233294Sstas/// fouts() - This returns a reference to a formatted_raw_ostream for
89233294Sstas/// standard output.  Use it like: fouts() << "foo" << "bar";
90233294Sstasformatted_raw_ostream &llvm::fouts() {
91178825Sdfr  static formatted_raw_ostream S(outs());
9255682Smarkm  return S;
93178825Sdfr}
94178825Sdfr
95178825Sdfr/// ferrs() - This returns a reference to a formatted_raw_ostream for
96178825Sdfr/// standard error.  Use it like: ferrs() << "foo" << "bar";
9755682Smarkmformatted_raw_ostream &llvm::ferrs() {
98178825Sdfr  static formatted_raw_ostream S(errs());
99178825Sdfr  return S;
100178825Sdfr}
10172445Sassar
102178825Sdfr/// fdbgs() - This returns a reference to a formatted_raw_ostream for
10355682Smarkm/// the debug stream.  Use it like: fdbgs() << "foo" << "bar";
10455682Smarkmformatted_raw_ostream &llvm::fdbgs() {
105178825Sdfr  static formatted_raw_ostream S(dbgs());
106233294Sstas  return S;
107178825Sdfr}
10855682Smarkm