FormattedStream.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. //===-- llvm/Support/FormattedStream.h - Formatted streams ------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file contains raw_ostream implementations for streams to do
  11. // things like pretty-print comments.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_SUPPORT_FORMATTEDSTREAM_H
  15. #define LLVM_SUPPORT_FORMATTEDSTREAM_H
  16. #include "llvm/Support/raw_ostream.h"
  17. #include <utility>
  18. namespace llvm {
  19. /// formatted_raw_ostream - A raw_ostream that wraps another one and keeps track
  20. /// of line and column position, allowing padding out to specific column
  21. /// boundaries and querying the number of lines written to the stream.
  22. ///
  23. class formatted_raw_ostream : public raw_ostream {
  24. /// TheStream - The real stream we output to. We set it to be
  25. /// unbuffered, since we're already doing our own buffering.
  26. ///
  27. raw_ostream *TheStream;
  28. /// Position - The current output column and line of the data that's
  29. /// been flushed and the portion of the buffer that's been
  30. /// scanned. The line and column scheme is zero-based.
  31. ///
  32. std::pair<unsigned, unsigned> Position;
  33. /// Scanned - This points to one past the last character in the
  34. /// buffer we've scanned.
  35. ///
  36. const char *Scanned;
  37. void write_impl(const char *Ptr, size_t Size) override;
  38. /// current_pos - Return the current position within the stream,
  39. /// not counting the bytes currently in the buffer.
  40. uint64_t current_pos() const override {
  41. // Our current position in the stream is all the contents which have been
  42. // written to the underlying stream (*not* the current position of the
  43. // underlying stream).
  44. return TheStream->tell();
  45. }
  46. /// ComputePosition - Examine the given output buffer and figure out the new
  47. /// position after output.
  48. ///
  49. void ComputePosition(const char *Ptr, size_t size);
  50. void setStream(raw_ostream &Stream) {
  51. releaseStream();
  52. TheStream = &Stream;
  53. // This formatted_raw_ostream inherits from raw_ostream, so it'll do its
  54. // own buffering, and it doesn't need or want TheStream to do another
  55. // layer of buffering underneath. Resize the buffer to what TheStream
  56. // had been using, and tell TheStream not to do its own buffering.
  57. if (size_t BufferSize = TheStream->GetBufferSize())
  58. SetBufferSize(BufferSize);
  59. else
  60. SetUnbuffered();
  61. TheStream->SetUnbuffered();
  62. Scanned = nullptr;
  63. }
  64. public:
  65. /// formatted_raw_ostream - Open the specified file for
  66. /// writing. If an error occurs, information about the error is
  67. /// put into ErrorInfo, and the stream should be immediately
  68. /// destroyed; the string will be empty if no error occurred.
  69. ///
  70. /// As a side effect, the given Stream is set to be Unbuffered.
  71. /// This is because formatted_raw_ostream does its own buffering,
  72. /// so it doesn't want another layer of buffering to be happening
  73. /// underneath it.
  74. ///
  75. formatted_raw_ostream(raw_ostream &Stream)
  76. : TheStream(nullptr), Position(0, 0) {
  77. setStream(Stream);
  78. }
  79. explicit formatted_raw_ostream() : TheStream(nullptr), Position(0, 0) {
  80. Scanned = nullptr;
  81. }
  82. ~formatted_raw_ostream() override {
  83. flush();
  84. releaseStream();
  85. }
  86. /// PadToColumn - Align the output to some column number. If the current
  87. /// column is already equal to or more than NewCol, PadToColumn inserts one
  88. /// space.
  89. ///
  90. /// \param NewCol - The column to move to.
  91. formatted_raw_ostream &PadToColumn(unsigned NewCol);
  92. /// getColumn - Return the column number
  93. unsigned getColumn() { return Position.first; }
  94. /// getLine - Return the line number
  95. unsigned getLine() { return Position.second; }
  96. raw_ostream &resetColor() override {
  97. TheStream->resetColor();
  98. return *this;
  99. }
  100. raw_ostream &reverseColor() override {
  101. TheStream->reverseColor();
  102. return *this;
  103. }
  104. raw_ostream &changeColor(enum Colors Color, bool Bold, bool BG) override {
  105. TheStream->changeColor(Color, Bold, BG);
  106. return *this;
  107. }
  108. bool is_displayed() const override {
  109. return TheStream->is_displayed();
  110. }
  111. private:
  112. void releaseStream() {
  113. // Transfer the buffer settings from this raw_ostream back to the underlying
  114. // stream.
  115. if (!TheStream)
  116. return;
  117. if (size_t BufferSize = GetBufferSize())
  118. TheStream->SetBufferSize(BufferSize);
  119. else
  120. TheStream->SetUnbuffered();
  121. }
  122. };
  123. /// fouts() - This returns a reference to a formatted_raw_ostream for
  124. /// standard output. Use it like: fouts() << "foo" << "bar";
  125. formatted_raw_ostream &fouts();
  126. /// ferrs() - This returns a reference to a formatted_raw_ostream for
  127. /// standard error. Use it like: ferrs() << "foo" << "bar";
  128. formatted_raw_ostream &ferrs();
  129. /// fdbgs() - This returns a reference to a formatted_raw_ostream for
  130. /// debug output. Use it like: fdbgs() << "foo" << "bar";
  131. formatted_raw_ostream &fdbgs();
  132. } // end llvm namespace
  133. #endif